Rotate Triangle

Blitz3D Forums/Blitz3D Programming/Rotate Triangle

Lee,

I out-clevered myself.

The original idea was to set up the pivot as described, parent the triangle and then turn the pivot. But this affects only the triangle entity, not the underlying mesh. Updating the mesh to match the entity orientation seemed messy. Then I got the "improved" idea to use the pivot orientation to rotate the mesh. That failed because

AlignToVector pivot, ny, -nx, 0, 2

points the y-axis the way I want, but other than that the orientation could be anything.

So it is back to the original idea. I think this works:

Graphics3D 800, 600, 0, 2

tri1 = CreateTriangle()

;SeedRnd MilliSecs()
;RotateMesh tri1, Rnd(50), Rnd(50), Rnd(50)

tri2 = CopyMesh( tri1 )

dumpvertices tri1, "Before"

AlignTriangle tri2

dumpvertices tri2, "After"

EntityColor tri1, 150, 150, 150
EntityColor tri2, 0, 255, 0

cam = CreateCamera()
PositionEntity cam, 0, 0, 30
TurnEntity cam, 0, 180, 0
CameraZoom cam, 7


HideEntity tri2
Repeat
	HideEntity tri1
	ShowEntity tri2
	RenderWorld
	Flip
	Delay 400
	
	HideEntity tri2
	ShowEntity tri1
	RenderWorld
	Flip
	Delay 400
Until KeyHit(1)	
Stop



Function CreateTriangle()
	tMesh=CreateMesh()
	tSurface=CreateSurface( tMesh )

	AddVertex tSurface, 3, 0, 0
	AddVertex tSurface, 0, 3, 0
	AddVertex tSurface, 0, 0, 3
	
	AddTriangle tSurface,0, 1, 2
	UpdateNormals tMesh

	PositionMesh tMesh, -1, -1, -1

	Return tMesh
End Function

Function AlignTriangle( tri )
	s = GetSurface( tri, 1 )
	
	nx# = VertexNX( s, 0 )
	ny# = VertexNY( s, 0 )
	nz# = VertexNZ( s, 0 )
	
	pivot = CreatePivot()
	AlignToVector pivot,  ny, -nx, 0, 2
	EntityParent tri, pivot
	TurnEntity pivot, 0, -ACos(nz), 0   ; Note minus sign. Yaw goes opposite way from what I expect. 
				
	EntityParent tri, 0
	FreeEntity pivot
	
	; Tricky way to change mesh to match entity orientation.
	
	RotateMesh tri, EntityPitch( tri ), EntityYaw( tri ), EntityRoll( tri )
	RotateEntity tri, 0, 0, 0	
	
	
End Function



Function DumpVertices( mesh, message$="Vertex list" )

Local nSurfs, sIndex, surface, lf$, txt$
Local x$,y$,z$, nx$,ny$,nz$

	lf$=Chr$(10)	
	nSurfs=CountSurfaces( mesh )
	DebugLog lf+message+lf

	For sIndex=1 To nSurfs

		surface=GetSurface( mesh, sIndex )

		For v=0 To CountVertices( surface ) - 1

			 x = RSet(  VertexX( surface, v ), 14)
			 y = RSet(  VertexY( surface, v ), 14)
			 z = RSet(  VertexZ( surface, v ), 14)
			nx = RSet( VertexNX( surface, v ), 14)
			ny = RSet( VertexNY( surface, v ), 14)
			nz = RSet( VertexNZ( surface, v ), 14)			
		
			txt="v="+RSet(v,4)+"  "+x+y+z+"     "+nx+ny+nz
			DebugLog txt
			
		Next
				
	Next

End Function


A few notes about this:

AlignTriangle does the actual work. The face normal has been stored in the first vertex.

The triangle is equilateral for ease of visual inspection. The aligned ( green ) triangle is face-on to the camera and should look equilateral.

In theory the aligned triangle has z=0 for all vertices. In practice this is only approximately true.

Notice the minus sign on -ACos(nz). I initially forgot this. The yaw rotation has to be the opposite way from what I visualize. Those left-handed coordinates bite me in the ass every time!

And finally I really did have a clever idea, a simple way to rotate the tri mesh to match the tri entity.