quads / sprites

Blitz3D Forums/Blitz3D Programming/quads / sprites

Anyone know how to emulate sprite-like behaviour for a 3d quad mesh?

If I use pointentity to point the quad at the camera, that works okay, but the roll gets screwed up - I'd like the quad always to be aligned the same way (horizonally + vertically) just like a sprite would be.

Just tried aligntovector, using the vector from the camera to a pivot in front of the camera and that has the same problem. . . looks like I need to calculate a roll to assign depending on the viewing angles - I have no idea how to figure this out!

If you really talk about the roll angle (pitch,yaw,roll) - maybe it works this way:

Pointentity quad,camera
rotateentity quad, entityPitch(quad,1), entityYaw(quad,1),0,1


unfortunately I tried that - the roll is always zero, on the camera and the quad. . . quads that are on the plane defined by the x-z component of the cameras direction and the y-axis appear on screen with the correct orientation. But whenever they are elsewhere, there is some rotation due to perpective (not really roll).

I want to eliminate this rotation if I can, by giving the quad a counteractive roll. . .

Here's a couple of pictures that help illustrate my problem.
As you can see, the problem is increased for quads vertically above or below.






Just tried aligntovector, using the vector from the camera to a pivot in front of the camera and that has the same problem. . .


Actually, just checking again, AlignToVector does seem to orientate all the quads in the same direction, but that orienation varies with the direction you are facing, so they aren't always vertical. However, thinking of the senario I'll be using them in this might be okay.

I guess that getting them vertical might be as simple as setting their roll to the cameras yaw after doing the aligntovector, but maybe not. . .


I'm still open to anyone else's ideas / suggestions as usual :O)

I use a similar method to what Dark Half suggested in a post a while ago. When you create your quad parent it to the camera and create its 4 vertices in the x/y plane. Using TFormpoint whenever you wish to move the quad allows you to place the quad in the world at its correct location always facing the camera. If you wish to roll the quad about the local z axis of the camera then you simply adjust the x/y coordinates of each corner of the quad using basic trigonometry.

I don't have access to my code at the moment but I'll post it later (probably around 8:00pm Australian Eastern Standard time) if it helps.

try this...ignore the messiness of the code I basically ripped it out of my quad functions code and cut it down to make what I hope is a simple example. Unfortunately I have left some of the unnecessary bits in but they are commented out....


Type QuadObject
Field Mesh
Field Surface
Field Camera ;parent used for tforming from world space to camera space for each vertex...
Field Index[3] ;0-3 for each vertex

Field Width#
Field Height#

Field Vert_X#[3]
Field Vert_Y#[3]
Field Vert_Z#[3]

Field Vert_U#[3]
Field Vert_V#[3]

Field Vert_R[3]
Field Vert_G[3]
Field Vert_B[3]
Field Vert_A#[3] ;alpha

Field Alpha#

Field InUse ; true / false.  If false then quad should not be shown, and should be available for use as other particles...


End Type

Graphics3D 800,600,0,2

camera=CreateCamera()
Dim quadpositions#(99,2)
mesh=CreateMesh(camera)
surface=CreateSurface(Mesh)


For q=1 To 50
Quad.QuadObject=New QuadObject
Quad\camera=camera
Quad\Mesh=mesh
quad\surface=surface
EntityColor quad\mesh,255,255,255
Quad\Index[0]=AddVertex(Quad\Surface,-Width*0.5,-Height*0.5,0,1)
Quad\Index[1]=AddVertex(Quad\Surface,-Width*0.5,Height*0.5,0,0)
Quad\Index[2]=AddVertex(Quad\Surface,Width*0.5,Height*0.5,1,0)
Quad\Index[3]=AddVertex(Quad\Surface,Width*0.5,-Height*0.5,1,1)
quad\inuse=True 
For i=0 To 3
Quad\Vert_X[i]=VertexX(Quad\Surface,Quad\Index[i])
Quad\Vert_Y[i]=VertexY(Quad\Surface,Quad\Index[i])
Quad\Vert_Z[i]=VertexZ(Quad\Surface,Quad\Index[i])
;Quad\Vert_U[i]=;you will have to put your own values here....;VertexU(Quad\Surface,Quad\Index[i])
;Quad\Vert_V[i]=;you will have to put your own values here....VertexV(Quad\Surface,Quad\Index[i])
;Quad\Vert_R[i]=VertexRed(Quad\Surface,Quad\Index[i])
;Quad\Vert_G[i]=VertexGreen(Quad\Surface,Quad\Index[i])
;Quad\Vert_B[i]=VertexBlue(Quad\Surface,Quad\Index[i])
;Quad\Vert_A[i]=VertexAlpha(Quad\Surface,Quad\Index[i])
;VertexTexCoords(Quad\Surface,i,Quad\Vert_U[i],Quad\Vert_V[i])
Next

;Quad\Visible=True 

AddTriangle(Quad\Surface,Quad\Index[0],Quad\Index[1],Quad\Index[2])
AddTriangle(Quad\Surface,Quad\Index[0],Quad\Index[2],Quad\Index[3])
For j=0 To 2
quadpositions(q-1,j)=Rnd(-50,50)
quadpositions(q-1,2)=quadpositions(q-1,2)+210
Next
SetQuadPosition(Handle(Quad),quadpositions(q-1,0),quadpositions(q-1,1),quadpositions(q-1,2),2,2)

Next 
Repeat

frame=frame+1
;do whatever you want to do to move the quads around...
For i=0 To 49
For j=0 To 2
quadpositions(i,j)=quadpositions(i,j)+2.0*Sin(frame)
Next
Next
i=0

For quad.quadobject=Each quadobject

setquadposition(Handle(Quad),quadpositions(i,0),quadpositions(i,1),quadpositions(i,2),-1,-1,frame,12,1)
i=i+1
Next
UpdateWorld
RenderWorld
Flip


Until KeyDown(1)
End



Function SetQuadPosition(QuadID,WorldX#,WorldY#,WorldZ#,Width#=-1,Height#=-1,Roll#=0,Size#=1.0,UseRoll=False)
;This gets called every frame....or at least whenever the camera moves

Quad.QuadObject=Object.quadobject(QuadID)
If Quad.QuadObject=Null Then Return -1

;check if height, width is to be changed (ie not -1)
If Width#=-1 Then Width#=Quad\Width
If Height#=-1 Then Height#=Quad\Height

TFormPoint WorldX,WorldY,WorldZ,0,Quad\Mesh

If UseRoll=True Then 
Roll=Roll+135
NewX0#=TFormedX()+Size*Cos(Roll+90)
NewY0#=TFormedY()+Size*Sin(Roll+90)

NewX1#=TFormedX()+Size*Cos(Roll)
NewY1#=TFormedY()+Size*Sin(Roll)

NewX2#=TFormedX()+Size*Cos(Roll+270.0)
NewY2#=TFormedY()+Size*Sin(Roll+270.0)

NewX3#=TFormedX()+Size*Cos(Roll+180.0)
NewY3#=TFormedY()+Size*Sin(Roll+180.0)
Else

NewX0#=TFormedX()-Width*0.5
NewY0#=TFormedY()-Height*0.5

NewX1#=TFormedX()-Width*0.5
NewY1#=TFormedY()+Height*0.5

NewX2#=TFormedX()+Width*0.5
NewY2#=TFormedY()+Height*0.5

NewX3#=TFormedX()+Width*0.5
NewY3#=TFormedY()-Height*0.5

EndIf 

If Quad\InUse=False Then 
;ie make the quad disappear....

;according to a bug report in the blitz3d bugs forum this may perform slightly differently on AMD and Intel motherboards
Width=0.0
Height=0.0

NewX0=0
NewY0=0

NewX1=0
NewY1=0

NewX2=0
NewY2=0

NewX3=0
NewY3=0


Else

;do nothing.
EndIf 

VertexCoords Quad\Surface,Quad\Index[0],NewX0,NewY0,TFormedZ()
VertexCoords Quad\Surface,Quad\Index[1],NewX1,NewY1,TFormedZ()
VertexCoords Quad\Surface,Quad\Index[2],NewX2,NewY2,TFormedZ()
VertexCoords Quad\Surface,Quad\Index[3],NewX3,NewY3,TFormedZ()

Return 0

End Function



Heres a simple example JFK made:
http://www.blitzbasic.com/codearcs/codearcs.php?code=321

I had something else slightly more extensive but a bit random: but for somereason all uploading sites i use either forgot that they understand .zips or are down just now, probability having no real account for anything as i use them so rarely.

Ok, I think you will always get soome distotion due to the cameraZoom, maybe you should increase it to 1.4 or something to reduce the fisheye distortion artefacts. Then again, space looks much smaller (eg. rooms in a fps) when you use a Camerazoom of 1.4

If you want to suppress Pitch, you could use the cameras pitch instead, something like:

Pointentity quad,camera
rotateentity quad, entityPitch(camera,1)+180, entityYaw(quad,1),0,1

Tho, I'm only guessing here :)