I recently wrote some billboarding code for a project and it worked so well I decided to port it to DBPro.
+ Code Snippet// Example: Optimized Arbitrary Axis Aligned Billboarding via Manual World Matrix Construction
// By: Jesse George (revenant_chaos@yahoo.com) Jan/2016
//////////////////////////////////////////////////////////////////////////////////////////////////
Set Display Mode 1024,768,32,1
Sync On : Sync Rate 0
color Backdrop RGB(14,19,25)
autocam off
move camera -100
//custom Vec3 structure
Type Vector3
X as float
Y as float
Z as float
endtype
//Load Basic3D Dll (for SetWorldMatrix() function)
Global dll_Basic3D as integer : dll_Basic3D = 1
Load Dll "DBProBasic3DDebug.dll", dll_Basic3D
//Prepare Laser Object
ObjID=1
Make Object Plane ObjID,1,1,1
Rotate Object ObjID,-90,-90,0
`re-create the object from mesh to "fix" the object's rotation
make Mesh From Object 1,ObjID : Delete Object ObjID
Make Object ObjID,1 : Delete Mesh 1
`disable the object's culling, dbpro can't properly cull objects which use custom world matrices
Set Object Radius ObjID,0
`disable the object's lighting; the object's normals will not be transformed properly due to
`some shortcuts (optimizations) used in this example.
set object light ObjID,0
`load and apply texture
TexID=1
load image "LaserBeam.png",TexID
texture object ObjID,TexID
ghost object on ObjID,2
//Allocate and Initalize Matrix4x4 structure. Will be used as a world transformation matrix
Global MatPtr as Dword
`16floats = 64bytes
MatPtr = MAKE MEMORY(64)
`Prepare matrix element pointers
m11=MatPtr : m12=MatPtr+4 : m13=MatPtr+8 : m14=MatPtr+12
m21=MatPtr+16 : m22=MatPtr+20 : m23=MatPtr+24 : m24=MatPtr+28
m31=MatPtr+32 : m32=MatPtr+36 : m33=MatPtr+40 : m34=MatPtr+44
m41=MatPtr+48 : m42=MatPtr+52 : m43=MatPtr+56 : m44=MatPtr+60
`setup some values here to avoid doing so within the main loop
*m14=0.0 : *m24=0.0 : *m34=0.0 : *m44=1.0
*m21=0.0 : *m22=1.0 : *m23=0.0 `binormal doesnt matter for this application
//Initalize some vectors to use for matrix assembly
`TBN vectors (Rotation and Scale)
Tangent as Vector3
Binormal as Vector3
Normal as Vector3
`Translation vector
Translation as Vector3
//Initalize laser beam Vecs and Vars
`Vectors Laser's Beginning and End points
Origin as Vector3
Destination as Vector3
`Laser's Beam Width
BeamWidth as float
BeamWidth = 5.0
`make some spheres for the laser's end points
make object sphere 2,5
make object sphere 3,5
Ink RGB(192,128,0)
do
set cursor 0,0
Print "Use the Mouse and Arrowkeys to navigate"
Print "Use the Mousewheel to adjust billboard width"
//Camera navigation
move camera (upkey()-downkey())*4
move camera right (rightkey()-leftkey())*4 `Matrix1Utils
rotate camera wrapvalue(camera angle X()+(mousemoveY()*0.2)),wrapvalue(camera angle Y()+(mousemoveX()*0.2)),0
`Adjust beam width using mousewheel
MMZ = MouseMoveZ()
if MMZ
if MMZ>0
Inc BeamWidth
else
Dec BeamWidth
endif
endif
//Update Laser
`temp angle for laser movement
TmpAng# = wrapvalue(timer()*0.05)
`set the laser's origin
Origin.X = -Sin(TmpAng#)*80
Origin.Y = -100
Origin.Z = -Cos(TmpAng#)*80
position object 2,Origin.X,Origin.Y,Origin.Z
`set the laser's destination
Destination.X = Sin(TmpAng#)*100
Destination.Y = 100
Destination.Z = Cos(TmpAng#)*100
position object 3,Destination.X,Destination.Y,Destination.Z
`calculate the laser's center
Translation.X = ( Origin.X + Destination.X ) * 0.5
Translation.Y = ( Origin.Y + Destination.Y ) * 0.5
Translation.Z = ( Origin.Z + Destination.Z ) * 0.5
`calculate the laser's direction vector (non-normalized to preserve scaling)
Tangent.X = Destination.X - Origin.X
Tangent.Y = Destination.Y - Origin.Y
Tangent.Z = Destination.Z - Origin.Z
`get a vector from the laser to the camera (non-normalized, doesnt matter....)
Binormal.X = Translation.X - Camera Position X()
Binormal.Y = Translation.Y - Camera Position Y()
Binormal.Z = Translation.Z - Camera Position Z()
`Normal = Tangent <cross> Binormal
Normal.X = (Tangent.Y*Binormal.Z) - (Tangent.Z*Binormal.Y)
Normal.Y = (Tangent.Z*Binormal.X) - (Tangent.X*Binormal.Z)
Normal.Z = (Tangent.X*Binormal.Y) - (Tangent.Y*Binormal.X)
`scale normal vector's length to match the desired beam width
tmp# = (((Normal.X*Normal.X)+(Normal.Y*Normal.Y)+(Normal.Z*Normal.Z))^0.5)/BeamWidth
Normal.X = Normal.X / tmp#
Normal.Y = Normal.Y / tmp#
Normal.Z = Normal.Z / tmp#
`assemble world matrix
*m11=Tangent.X
*m12=Tangent.Y
*m13=Tangent.Z
*m31=Normal.X
*m32=Normal.Y
*m33=Normal.Z
*m41=Translation.X
*m42=Translation.Y
*m43=Translation.Z
`apply the world transformation matrix to the laser object
call dll dll_Basic3D,"?SetWorldMatrix@@YAXHPAUD3DXMATRIX@@@Z",ObjID,MatPtr
Sync
loop
Delete Memory MatPtr
Delete Dll dll_Basic3D
[Edit] Attached Laser Beam Image.
[Edit2] Fixed bug with matrix memory allocation; it appears MAKE MEMORY() does not ensure the memory is initialized with zeros...