Track Editor help required

Blitz3D Forums/Blitz3D Beginners Area/Track Editor help required

CyberHeater(Posted 2004) [#1]
Guys. Once again i'm stuck. Please help out.

I'm writing a race track editor and have got stuck on with the mesh generated having flipped faces.

Look at this example. Arrow shows the problem.



Here is the simplified code. Use left hand mouse button to draw a series of points in a clockwise circle starting from the bottem then use the tab key to generate the mesh.

How can I solve this.

Graphics3D 800,600,16,2

SetBuffer BackBuffer()
	
camPiv = CreatePivot()
camera = CreateCamera(camPiv)
PositionEntity(camera, 0,500,0)
RotateEntity camera, 90, 0,0
CameraRange camera,1,9000

light=CreateLight()
RotateEntity light,100,100,1000


EntityY camera

;set up a non visible cursor entity 
test_sphere=CreateSphere ()
ScaleMesh test_sphere,20,20,20
EntityColor test_sphere, 255,100,100
EntityAlpha test_sphere, 0.4 ;*** Transparece

CreateCube()

Global piv_target=CreatePivot()
Global piv_pointer=CreatePivot()
Global piv_tracker=CreatePivot()
Global campitch#,camyaw#,timer,yheight#
 
cam_z=0


Dim pos(100,2) ;storage for the hand drawn lines.
Dim angles(100,2)
Dim T_Points(100,5)
Dim verts(100)

V_Pos = 0; the first start to array

; Mainloop
While Not KeyDown(1) 
   	Cls ; Clear screen

	;half of screen dimensions needed
	w=GraphicsWidth() :	h=GraphicsHeight()

	;Mouse Related bits;positions	
	x#=MouseX() : y#=MouseY()
	xs=MouseXSpeed() :	ys=MouseYSpeed() ; see how far the mouse has been moved 

	yheight#= Abs(EntityY (camera))
				
	If MouseHit (1) Then
		PositionEntityFromZ2D (camera, test_sphere, x, y)
		PositionEntityFromZ2D (camera, piv_target, x, y)

		pos(V_Pos, 0) = EntityX (piv_target)
		pos(V_Pos, 1) = EntityY (piv_target)
		pos(V_Pos, 2) = EntityZ (piv_target)
		prev_angle = EntityYaw (piv_target,True)
		
		;now draw intersects etc..
		If V_Pos = 1 ; must be second anchor point
			
			;position piv_target to last anchor point and point to new position
			PositionEntity piv_target, pos(V_Pos-1,0),pos(V_Pos-1,1),pos(V_Pos-1,2)
			PositionEntity piv_pointer, pos(V_Pos,0),pos(V_Pos,1),pos(V_Pos,2)

			PointEntity piv_target,piv_pointer,0
			
		ElseIf V_Pos > 1
		
			;calculate the diffence in angles between 2 lines			
			dx#=(pos(V_Pos, 0)-pos(V_Pos-1, 0))
			dy#=(pos(V_Pos, 2)-pos(V_Pos-1, 2))
			angle1#=ATan2(dy,dx)

					
			dx#=(pos(V_Pos-2, 0)-pos(V_Pos-1, 0))
			dy#=(pos(V_Pos-2, 2)-pos(V_Pos-1, 2))
			angle2#=ATan2(dy,dx)
			
			angle = (angle1 + angle2)/2


			;now position and rotate the pivot 
			PositionEntity piv_target, pos(V_Pos-1, 0),pos(V_Pos-1, 1),pos(V_Pos-1, 2)
			RotateEntity piv_target,0,angle,0
			
			
		EndIf
		
		
		TFormPoint -60,0,0,piv_target,0
		x1 = TFormedX() 
		y1 = TFormedY() 
		z1 = TFormedZ()
			
		T_Points(V_Pos,0)=x1
		T_Points(V_Pos,1)=y1
		T_Points(V_Pos,2)=z1
	
		TFormPoint 10,0,0,piv_target,0
		x2 = TFormedX() 
		y2 = TFormedY() 
		z2 = TFormedZ()
			
		T_Points(V_Pos,3)=x2
		T_Points(V_Pos,4)=y2
		T_Points(V_Pos,5)=z2
				
		V_Pos=V_Pos + 1
		EndIf



	If KeyDown( 205 )=True Then TurnEntity camera,0,-180,0 
	If KeyDown( 203 )=True Then TurnEntity camera,0,180,0 
	If KeyDown( 208 )=True Then 
		PositionEntity camera,0,-500,0
		PointEntity camera,piv_tracker
		Delay 50
	EndIf
	If KeyDown( 200 )=True Then ;push forward then flip
		PositionEntity camera,0,500,0
		PointEntity camera,piv_tracker
		Delay 50
	EndIf

	
	MoveEntity camera,0,0,+MouseZSpeed()*80; move the depth and ramp with distance
	
	;PositionEntity camera,xview,yview,cam_z

	RenderWorld
	

	If V_Pos > 1 Then ; draw the interconnecting lines
		For loop = 1 To V_Pos-1
			Line3d(pos(loop-1, 0),pos(loop-1, 1),pos(loop-1, 2),pos(loop, 0),pos(loop, 1),pos(loop, 2), camera)
			Line3d(T_Points(loop,0),T_Points(loop,1),T_Points(loop,2),T_Points(loop,3),T_Points(loop,4),T_Points(loop,5), camera)
		Next
	EndIf


	If KeyHit(15) ;tab key - now generate the mesh

		mesh=CreateMesh()
		he=CreateBrush(255,255,255)
		surf=CreateSurface(mesh,he)
		FreeBrush he
		vertex_offset=0
		For loop = 2 To V_Pos - 1 ;Step 2
		
			AddVertex surf,T_Points(loop,0),T_Points(loop,1),T_Points(loop,2), 0,0
			AddVertex surf,T_Points(loop,3),T_Points(loop,4),T_Points(loop,5),1,0
			AddVertex surf,T_Points(loop-1,0),T_Points(loop-1,1),T_Points(loop-1,2),0,1
			AddVertex surf,T_Points(loop-1,3),T_Points(loop-1,4),T_Points(loop-1,5),1,1
			
			AddTriangle surf,vertex_offset+2,vertex_offset,vertex_offset+1 ; and 2 triangles...
			AddTriangle surf,vertex_offset+2,vertex_offset+1,vertex_offset+3

			vertex_offset=vertex_offset+4
		Next
		bgtexture=CreateTexture(128,128,9) 
		; Set the drawing buffer to the graphic frame so we can write on it 
		SetBuffer TextureBuffer(bgtexture) 
		; draw the grid 
		Color 244,255,255 : Rect 0,0,128,128
		Color 50,99,201 :	Rect 1,1,126,126
		Color 244,255,255 : 
		Line 0,64,128,64
		Line 64,0,64,128

		; Double buffer mode for smooth screen drawing 
		SetBuffer BackBuffer() 

		UpdateNormals mesh
		EntityTexture mesh,bgtexture

 	EndIf

	Flip ; Flip backbuffer to frontbuffer 
Wend 
End


Function PositionEntityFromZ2D (usecam, entity, x2d#, y2d#)
	gw = GraphicsWidth ()
	gh = GraphicsHeight ()
	x# = -((gw / 2) - x2d)
	z# = (gh / 2) - y2d
	div# = (1/(Abs(EntityY (usecam))/4))*100
	PositionEntity entity, x / div, 0, z / div,0
End Function




;=================================================================================
;Draws a 3d line.  Use after renderworld.
;=================================================================================
Function Line3d(x0#,y0#,z0#,x1#,y1#,z1#, camera)
	CameraProject (camera,x0,y0,z0)
	px0#=ProjectedX# ( ) 
	py0#=ProjectedY# ( ) 
	pz0#=ProjectedZ# ( ) 
	CameraProject (camera,x1,y1,z1)
	Color 255,55,55
	If ProjectedZ#( ) >0 And pz0>0 Then Line px0,py0,ProjectedX# ( ) ,ProjectedY# ( ) 
End Function



eBusiness(Posted 2004) [#2]
Try letting the user place all of the vertexes, you will probably need the flexibility anyway.


DJWoodgate(Posted 2004) [#3]
I'm sure there is a simpler way of getting this working, which I can not see at the moment, but you could try something like this:
Define a function to determine if your proposed triangle will be backfacing or not with respect to either the camera or better perhaps the "up" vector for your track section. See the archives for backfacing code. If it is going to be backfacing then reverse the order you add the verts to the triangle.


CyberHeater(Posted 2004) [#4]
I managed to fix it. Only took me a week!

Here is the code>

Graphics3D 800,600,16,2

SetBuffer BackBuffer()
	
camPiv = CreatePivot()
camera = CreateCamera(camPiv)
PositionEntity(camera, 0,500,0)
RotateEntity camera, 90, 0,0
CameraRange camera,1,9000

light=CreateLight()
RotateEntity light,100,100,1000


EntityY camera

;set up a non visible cursor entity 
test_sphere=CreateSphere ()
ScaleMesh test_sphere,20,20,20
EntityColor test_sphere, 255,100,100
EntityAlpha test_sphere, 0.4 ;*** Transparece

CreateCube()

Global piv_target=CreatePivot()
Global piv_pointer=CreatePivot()
Global piv_tracker=CreatePivot()
Global campitch#,camyaw#,timer,yheight#
 
cam_z=0


Dim pos(100,2) ;storage for the hand drawn lines.
Dim angles(100,2)
Dim T_Points(100,5)
Dim verts(100)

V_Pos = 0; the first start to array

; Mainloop
While Not KeyDown(1) 
   	Cls ; Clear screen

	;half of screen dimensions needed
	w=GraphicsWidth() :	h=GraphicsHeight()

	;Mouse Related bits;positions	
	x#=MouseX() : y#=MouseY()
	xs=MouseXSpeed() :	ys=MouseYSpeed() ; see how far the mouse has been moved 

	yheight#= Abs(EntityY (camera))
				
	If MouseHit (1) Then
		PositionEntityFromZ2D (camera, test_sphere, x, y)
		PositionEntityFromZ2D (camera, piv_target, x, y)

		pos(V_Pos, 0) = EntityX (piv_target)
		pos(V_Pos, 1) = EntityY (piv_target)
		pos(V_Pos, 2) = EntityZ (piv_target)
		prev_angle = EntityYaw (piv_target,True)
		
		;now draw intersects etc..
		If V_Pos = 1 ; must be second anchor point
			
			;position piv_target to last anchor point and point to new position
			PositionEntity piv_target, pos(V_Pos-1,0),pos(V_Pos-1,1),pos(V_Pos-1,2)
			PositionEntity piv_pointer, pos(V_Pos,0),pos(V_Pos,1),pos(V_Pos,2)

			PointEntity piv_target,piv_pointer,0
			
		ElseIf V_Pos > 1
		
			;calculate the diffence in angles between 2 lines			
		
			dx1=pos(V_Pos-2,0):dx2=pos(V_Pos-1,0):dx3=pos(V_Pos-1,0):dx4=pos(V_Pos,0)
			dy1=pos(V_Pos-2,2):dy2=pos(V_Pos-1,2):dy3=pos(V_Pos-1,2):dy4=pos(V_Pos,2)

			line1 = ATan2(dy2 - dy1, dx2 - dx1)
			line2 = ATan2(dy4 - dy3, dx4 - dx3)
			
			newangle = line1-line2
			;now make sure it the interects can't flip
			If newangle > 180 Then newangle = newangle -360
			If newangle < -180 Then newangle = newangle + 360
			
			;now position and rotate the pivot 
			PositionEntity piv_target, pos(V_Pos-1, 0),pos(V_Pos-1, 1),pos(V_Pos-1, 2)
			PositionEntity piv_pointer, pos(V_Pos,0),pos(V_Pos,1),pos(V_Pos,2)
			PointEntity piv_target,piv_pointer,0
			TurnEntity piv_target,0,newangle/2,0
			
		EndIf
		
		TFormPoint -60,0,0,piv_target,0
		x1 = TFormedX() 
		y1 = TFormedY() 
		z1 = TFormedZ()
			
		T_Points(V_Pos,0)=x1
		T_Points(V_Pos,1)=y1
		T_Points(V_Pos,2)=z1
	
		TFormPoint 10,0,0,piv_target,0
		x2 = TFormedX() 
		y2 = TFormedY() 
		z2 = TFormedZ()
			
		T_Points(V_Pos,3)=x2
		T_Points(V_Pos,4)=y2
		T_Points(V_Pos,5)=z2
				
		V_Pos=V_Pos + 1
		EndIf



	If KeyDown( 205 )=True Then TurnEntity camera,0,-180,0 
	If KeyDown( 203 )=True Then TurnEntity camera,0,180,0 
	If KeyDown( 208 )=True Then 
		PositionEntity camera,0,-500,0
		PointEntity camera,piv_tracker
		Delay 50
	EndIf
	If KeyDown( 200 )=True Then ;push forward then flip
		PositionEntity camera,0,500,0
		PointEntity camera,piv_tracker
		Delay 50
	EndIf

	
	MoveEntity camera,0,0,+MouseZSpeed()*80; move the depth and ramp with distance
	
	;PositionEntity camera,xview,yview,cam_z

	RenderWorld
	
	Text 10,10,"Angle 1   = " + angle1
	Text 10,30,"Angle 1   = " + angle2
	Text 10,50,"Dif angle = " + angle
	Text 10,80,"test  " + angledif
	Text 10,100,"newangle = " + newangle
	


	If V_Pos > 1 Then ; draw the interconnecting lines
		For loop = 1 To V_Pos-1
			Line3d(pos(loop-1, 0),pos(loop-1, 1),pos(loop-1, 2),pos(loop, 0),pos(loop, 1),pos(loop, 2), camera)
			Line3d(T_Points(loop,0),T_Points(loop,1),T_Points(loop,2),T_Points(loop,3),T_Points(loop,4),T_Points(loop,5), camera)
		Next
	EndIf


	If KeyHit(15) ;tab key - now generate the mesh

		mesh=CreateMesh()
		he=CreateBrush(255,255,255)
		surf=CreateSurface(mesh,he)
		FreeBrush he
		vertex_offset=0
		For loop = 2 To V_Pos - 1 ;Step 2
		
			AddVertex surf,T_Points(loop,0),T_Points(loop,1),T_Points(loop,2), 0,0
			AddVertex surf,T_Points(loop,3),T_Points(loop,4),T_Points(loop,5),1,0
			AddVertex surf,T_Points(loop-1,0),T_Points(loop-1,1),T_Points(loop-1,2),0,1
			AddVertex surf,T_Points(loop-1,3),T_Points(loop-1,4),T_Points(loop-1,5),1,1
			
			AddTriangle surf,vertex_offset+2,vertex_offset,vertex_offset+1 ; and 2 triangles...
			AddTriangle surf,vertex_offset+2,vertex_offset+1,vertex_offset+3

			vertex_offset=vertex_offset+4
		Next
		bgtexture=CreateTexture(128,128,9) 
		; Set the drawing buffer to the graphic frame so we can write on it 
		SetBuffer TextureBuffer(bgtexture) 
		; draw the grid 
		Color 244,255,255 : Rect 0,0,128,128
		Color 50,99,201 :	Rect 1,1,126,126
		Color 244,255,255 : 
		Line 0,64,128,64
		Line 64,0,64,128

		; Double buffer mode for smooth screen drawing 
		SetBuffer BackBuffer() 

		UpdateNormals mesh
		EntityTexture mesh,bgtexture

 	EndIf

	Flip ; Flip backbuffer to frontbuffer 
Wend 
End



Function PositionEntityFromZ2D (usecam, entity, x2d#, y2d#)
	gw = GraphicsWidth ()
	gh = GraphicsHeight ()
	x# = -((gw / 2) - x2d)
	z# = (gh / 2) - y2d
	div# = (1/(Abs(EntityY (usecam))/4))*100
	PositionEntity entity, x / div, 0, z / div,0
End Function


Function line_angle_dif(x1,y1,x2,y2,x3,y3,x4,y4)
	Return ATan2(y2-y1,x2-x1)-ATan2(y4-y3,x4-y3)
End Function

;=================================================================================
;Draws a 3d line.  Use after renderworld.
;=================================================================================
Function Line3d(x0#,y0#,z0#,x1#,y1#,z1#, camera)
	CameraProject (camera,x0,y0,z0)
	px0#=ProjectedX# ( ) 
	py0#=ProjectedY# ( ) 
	pz0#=ProjectedZ# ( ) 
	CameraProject (camera,x1,y1,z1)
	Color 255,55,55
	If ProjectedZ#( ) >0 And pz0>0 Then Line px0,py0,ProjectedX# ( ) ,ProjectedY# ( ) 
End Function