is vertex visible ?

Blitz3D Forums/Blitz3D Programming/is vertex visible ?

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Thanks Stevie! The flat shading looks a lot better. I could use that for my "extrude" editor as well, if that's allright. Here, look, I'll show what I am making:
;-------------------------------------------------------------------------------------------------------
;											   globals
;-------------------------------------------------------------------------------------------------------

	Const 	DragMenu = 30

	Global	campiv					;central pivot for camera
	Global 	camera					;camera
	Global 	plane					;plane used for picking
	Global	mesh					;mesh in editor
	Global	selsurf					;selected surface
	Global  selvert					;selected vertex
	Global	dot						;dot image (selected dot)
	Global	dot2					;dot image 2 (unselected dot)
	Global	UpdateNeeded			;flag for redrawing interface
	Global 	light
	
	;connects two vertices (with the same coords)
	Type Connect	
		Field surf
		Field v1
		Field v2	
	End Type
	
	Dim Cursor_Down(2)

;-------------------------------------------------------------------------------------------------------
;											   setup graphics
;-------------------------------------------------------------------------------------------------------

	Graphics3D 1024, 768, 0, 2
	SetBuffer BackBuffer()
	
	buffer = CreateImage(GraphicsWidth(), GraphicsHeight())
	 	
	;create dot images	
	CreateDots
	
	;setup camera and plane
	Setup3DWorld	  
	 
	;make GUI
	MakeGUI
	
	;WireFrame True	
	 
;-------------------------------------------------------------------------------------------------------
;												 main loop
;-------------------------------------------------------------------------------------------------------

	OpenMesh
	
	Global Cursor_X, Cursor_Y
	

	Repeat
		
		For i = 1 To 2 
			Cursor_Down(i) = MouseDown(i)
		Next
		Cursor_X = MouseX()
		Cursor_Y = MouseY()
		
		;cursor keys	
		If KeyDown(203) Then Turn +1
		If KeyDown(205) Then Turn -1
		If KeyDown(200) Then Zoom +1/5.0
		If KeyDown(208) Then Zoom -1/5.0
		
			;if mouse is down
			If Cursor_Down(1) Then
				;get coords
				CameraPick camera, Cursor_X, Cursor_Y
				;move selected vertex
				MoveVertex selsurf, selvert, PickedX(), PickedY(), PickedZ()
			End If
			
		;render if flag is set
		If UpdateNeeded Then 
			RenderWorld()
			GrabImage buffer, 0, 0
		Else
			DrawBlock buffer, 0, 0
		End If
		
		;draw vertices
		DrawVertices(camera, mesh)

		;reset flag
		UpdateNeeded = False
		
;		;draw and handle GUI				 	 			
;		HandleGUI DrawGui$()
		
		Color 255,255,255
		Text 0, 0, "Use cursor keys to rotate"
		Text 0, 20, "Drag vertices with mouse"

		Flip
		
		If KeyHit(16) Then SetMesh CreateCube()
		If KeyHit(17) Then SetMesh CreateCone()
		If KeyHit(18) Then SetMesh CreateCylinder()
		If KeyHit(19) Then SetMesh CreateSphere()
		 
	Until KeyHit(1)
	 
	End
 
;-------------------------------------------------------------------------------------------------------
;												 MakeGUI()
;-------------------------------------------------------------------------------------------------------
;creates G.U.I.
Function MakeGUI()
End Function

;-------------------------------------------------------------------------------------------------------
;												Setup3DWorld()
;-------------------------------------------------------------------------------------------------------
;creates 3d world
Function Setup3DWorld()
	
	;create camera
	campiv			= CreatePivot()
	camera 			= CreateCamera(campiv)
	CameraZoom		camera, 2.4
	PositionEntity 	camera, 0, 0, -15	
	
	;create plane
	plane 			= CreatePlane(1, campiv)
	RotateEntity 	plane, -90, 0, 0
	EntityPickMode	plane, 2
	EntityAlpha		plane, 0.0

	;create light	
	light			= CreateLight()
	LightColor		light, 128, 128, 128;64, 64, 64
	TurnEntity		light, 0, 10, 0
	;AmbientLight	0, 0, 0
	
End Function

;-------------------------------------------------------------------------------------------------------
;												DrawVertices()
;-------------------------------------------------------------------------------------------------------
;project all vertices of a mesh
Function DrawVertices(cam, mesh)

	Local i%
	Local j%
	Local surf%
	Local maxafstand# = 10000.0
	Local dist#
	Local px#
	Local py#
			
	;if there is a mesh and no vertices are drawn allready
	If (mesh <> 0) And (Not Cursor_Down(1)) Then

		;scan all surfaces	
		For i = 1 To CountSurfaces(mesh)
			
			surf = GetSurface(mesh, i)

			;by Stevie G
			;loop through all triangles		
			Color 255,0,0
			For v = 0 To CountVertices( surf ) - 1
			
				;get global vertex position
				TFormPoint VertexX( surf, v ) , VertexY( surf, v ), VertexZ( surf, v ) , cube, 0
				;get direction vector from camera to vertex
				Cx# = TFormedX() - EntityX( camera, 1 )
				Cy# = TFormedY() - EntityY( Camera, 1 )
				Cz# = TFormedZ() - EntityZ( camera, 1 )
				;tform normal into Global coords 
				TFormNormal VertexNX( surf, v ) , VertexNY( surf, v ) , VertexNZ( surf, v ), cube, 0
				;dot product
				iDot# = Cx * TFormedX() + Cy * TFormedY() + Cz * TFormedZ()
				
				If iDot< 0 			
					TFormPoint VertexX( surf, v ) , VertexY( surf, v) , VertexZ( surf, v ), cube, 0
					CameraProject camera, TFormedX(), TFormedY(), TFormedZ() 
					DrawBlock dot2, ProjectedX()-2, ProjectedY()-2
														
					dist# = VDist(ProjectedX(), ProjectedY(), Cursor_X, Cursor_Y)
					If dist < maxafstand Then 
								
						;select the vertex
						maxafstand = dist
						selsurf = i
						selvert = v
		
					End If
					
				End If
					
			Next
													
		Next
		
	End If

	
	If mesh = 0 Then Return
	
	If selsurf < 1 Then Return
				
	;get selected surface	
	surf = GetSurface(mesh, selsurf)

	;project selected vertex coords onto camera
	CameraProject cam, VertexX(surf, selvert), VertexY(surf, selvert), VertexZ(surf, selvert)

	px# = ProjectedX()
	py# = ProjectedY()	
	
	;draw a dot at the coords
	DrawImage dot, px, py
		
	;position plane on the Z of this vertex	
	TFormPoint VertexX(surf, selvert), VertexY(surf, selvert), VertexZ(surf, selvert), mesh, campiv
	PositionEntity plane, 0, 0, TFormedZ()
	
End Function

;-------------------------------------------------------------------------------------------------------
;													Turn()
;-------------------------------------------------------------------------------------------------------
;turn editor
Function Turn(yw#)
	
	;turn camera
	TurnEntity 		campiv, 0, yw#, 0
	TurnEntity 		light, 0, yw, 0 
	;set flag for redrawing
	UpdateNeeded 	= True
	
End Function

;-------------------------------------------------------------------------------------------------------
;												   Zoom()
;-------------------------------------------------------------------------------------------------------
;zooms camera in/out
Function Zoom(z#)
	
	;if camera is not entirely zoomed in
	If EntityZ(camera) +z < 0 Then	
		;change camera zoom
		MoveEntity 		camera, 0, 0, z#
		;set flag for redrawing
		UpdateNeeded 	= True
	End If
	
End Function

;-------------------------------------------------------------------------------------------------------
;												  VDist()
;-------------------------------------------------------------------------------------------------------
;return distance (x1,y1)-(x2,y2)
Function VDist(x1#, y1#, x2#, y2#)
	
	;get distance and return it
	Return Sqr(dB(x2 - x1) + dB(y2 - y1))
	
End Function

;-------------------------------------------------------------------------------------------------------
;													dB()
;-------------------------------------------------------------------------------------------------------
;returns x^2
Function dB#(x#)
	Return x * x
End Function

;-------------------------------------------------------------------------------------------------------
;												MoveVertex()
;-------------------------------------------------------------------------------------------------------
;move a single vertex
Function MoveVertex(surf, vert, x#, y#, z#)

	If surf < 1 Then Return
	
	;get surface	
	isurf = GetSurface(mesh, surf)
	
	;set vertex coords
	VertexCoords isurf, vert, x, y, z
	
	;look for connected vertices
	For c.Connect = Each Connect
		If c\surf = surf Then
			;move them along
			If c\v1 = vert Then VertexCoords isurf, c\v2, x, y, z
			If c\v2 = vert Then VertexCoords isurf, c\v1, x, y, z
		End If
	Next
	
	;set flag for redrawing
	UpdateNeeded 	= True
	;calculate new normals
	MeshNormals 	mesh
	
End Function

;-------------------------------------------------------------------------------------------------------
;												CreateDots()
;-------------------------------------------------------------------------------------------------------
;create images for dots
Function CreateDots()

	dot = CreateImage(10, 10)
	dot2 = CreateImage(5, 5)
	
	Cls
	Color 0, 0, 255
	Rect 0, 0, 10, 10
	Color 255, 255, 255
	Rect 2, 2, 6, 6
	GrabImage dot, 0, 0
	
	Cls
	Color 255, 0, 0
	Rect 0, 0, 5, 5, 0
	GrabImage dot2, 0, 0
	
	MidHandle dot
	MidHandle dot2
				
End Function

;-------------------------------------------------------------------------------------------------------
;											   ScanMesh()
;-------------------------------------------------------------------------------------------------------
;scan mesh for overlapping vertices
Function ScanMesh(mesh)
	
	;delete each connection type
	Delete Each Connect

	;return if there is no mesh
	If mesh = 0 Then Return
	
	;scan all surfaces
	For i = 1 To CountSurfaces(mesh)
	
		surf = GetSurface(mesh, i)
		
		;scan all vertices on surface
		For j = 0 To CountVertices(surf) - 1
			
			;get coords
			vx1# = VertexX(surf, j)
			vy1# = VertexY(surf, j)
			vz1# = VertexZ(surf, j)
			
			;scan all other vertices (with higher index)
			For k = j + 1 To CountVertices(surf) - 1
								
				;get coords
				vx2# = VertexX(surf, k)
				vy2# = VertexY(surf, k)
				vz2# = VertexZ(surf, k)

				;if coords are the same
				If Cmp(vx1, vx2) And Cmp(vy1, vy2) And Cmp(vz1, vz2) Then
					;store these two vertices
					c.Connect = New Connect
					c\surf = i
					c\v1 = j
					c\v2 = k
				End If
								
			Next	
			
		Next
	
	Next
	
End Function

;-------------------------------------------------------------------------------------------------------
;												InitVars()
;-------------------------------------------------------------------------------------------------------
;initialize variables that need resetting
Function InitVars()

	selsurf = 0
	selvert = 0
	UpdateNeeded = True
	Delete Each Connect
	If mesh <> 0 Then FreeEntity mesh
	
End Function

;-------------------------------------------------------------------------------------------------------
;												SetMesh()
;-------------------------------------------------------------------------------------------------------
;accepts a new mesh
Function SetMesh(imesh)
	
	If imesh = 0 Then Return
	InitVars
	mesh = imesh
	;FitMesh mesh, -1, -1, -1, 2, 2, 2, 1
	EntityFX mesh, 16
	EntityShininess mesh, 2
	Unweld mesh
	MeshNormals mesh
	ScanMesh mesh

End Function	

;-------------------------------------------------------------------------------------------------------
;												OpenMesh()
;-------------------------------------------------------------------------------------------------------
;show dialog and load mesh
Function OpenMesh()

	If mesh <> 0 Then FreeEntity mesh
	SetMesh CreateSphere()
	
End Function

;-------------------------------------------------------------------------------------------------------
;												HandleGUI()
;-------------------------------------------------------------------------------------------------------
;handles gui activity
Function HandleGUI(button$)
	
	If button$ = "Load" Then OpenMesh()
	
End Function

;-------------------------------------------------------------------------------------------------------
;												 Compare()
;-------------------------------------------------------------------------------------------------------
;determine which vertex is closer to the camera
Function Compare(s1, i1, s2, i2)
	
	surf1 = GetSurface(mesh, s1)
	surf2 = GetSurface(mesh, s2)
	
	TFormPoint VertexX(surf1, i1), VertexY(surf1, i1), VertexZ(surf1, i1), mesh, campiv
	z1# = TFormedZ()
	TFormPoint VertexX(surf2, i2), VertexY(surf2, i2), VertexZ(surf2, i2), mesh, campiv
	z2# = TFormedZ()
	
	Return (z1 > z2)

End Function

Function Cmp(x#, y#)
	
	If Abs(x) < 0.001 Then x = 0
	If Abs(y) < 0.001 Then y = 0
	xx% = Floor(x * 100)
	yy% = Floor(y * 100)
	Return (xx = yy)
	
End Function



;by Stevie G
Function MESHnormals( mesh )

	For l = 1 To CountSurfaces(mesh )
		s = GetSurface( mesh , l )
		;calculate normals for flatshading
		For t = 0 To CountTriangles( s )-1
			v0 = TriangleVertex( s, t, 0 )
			v1 = TriangleVertex( s, t, 1 )
			v2 = TriangleVertex( s, t, 2 )
			ax# = VertexX( s, v1 ) - VertexX( s, v0 )
			ay# = VertexY( s, v1 ) - VertexY( s, v0 )	
			az# = VertexZ( s, v1 ) - VertexZ( s, v0 )	
			bx# = VertexX( s, v2 ) - VertexX( s, v1 )
			by# = VertexY( s, v2 ) - VertexY( s, v1 )	
			bz# = VertexZ( s, v2 ) - VertexZ( s, v1 )	
			Nx# = ( ay * bz ) - ( az * by )
			Ny# = ( az * bx ) - ( ax * bz )
			Nz# = ( ax * by ) - ( ay * bx )
			Ns# = Sqr( Nx * Nx + Ny*Ny + Nz*Nz )
			Nx = Nx / Ns
			Ny = Ny / Ns
			Nz = Nz / Ns
						
			For v = v0 To v2
				VertexNormal s, v, Nx, Ny, Nz 
			Next
		Next
	Next

End Function


; ID: 422
; Author: starfox
; Date: 2002-09-09 14:16:20
; Title: Unweld
; Description: This function unwelds all the points

Function Unweld(mesh)
;Unweld a mesh, retaining all of its textures coords and textures
For surfcount = 1 To CountSurfaces(mesh)
	surf = GetSurface(mesh,surfcount)

	count = CountTriangles(surf)
	bank = CreateBank((15*count)*4)
	For tricount = 0 To count-1
	off = (tricount*15)*4
	in = TriangleVertex(surf,tricount,0)
	x# = VertexX(surf,in):y#=VertexY(surf,in):z#=VertexZ(surf,in)
	u# = VertexU(surf,in):v#=VertexV(surf,in)
	PokeFloat(bank,off,x)
	PokeFloat(bank,off+4,y)
	PokeFloat(bank,off+8,z)
	PokeFloat(bank,off+12,u)
	PokeFloat(bank,off+16,v)

	in = TriangleVertex(surf,tricount,1)
	x# = VertexX(surf,in):y#=VertexY(surf,in):z#=VertexZ(surf,in)
	u# = VertexU(surf,in):v#=VertexV(surf,in)
	PokeFloat(bank,off+20,x)
	PokeFloat(bank,off+24,y)
	PokeFloat(bank,off+28,z)
	PokeFloat(bank,off+32,u)
	PokeFloat(bank,off+36,v)

	in = TriangleVertex(surf,tricount,2)
	x# = VertexX(surf,in):y#=VertexY(surf,in):z#=VertexZ(surf,in)
	u# = VertexU(surf,in):v#=VertexV(surf,in)
	PokeFloat(bank,off+40,x)
	PokeFloat(bank,off+44,y)
	PokeFloat(bank,off+48,z)
	PokeFloat(bank,off+52,u)
	PokeFloat(bank,off+56,v)

	Next
	
	ClearSurface(surf,True,True)
	
	For tricount = 0 To count-1
	off = (tricount*15)*4
	x# = PeekFloat(bank,off)
	y# = PeekFloat(bank,off+4)
	z# = PeekFloat(bank,off+8)
	u# = PeekFloat(bank,off+12)
	v# = PeekFloat(bank,off+16)
	a = AddVertex(surf,x,y,z,u,v)
	x# = PeekFloat(bank,off+20)
	y# = PeekFloat(bank,off+24)
	z# = PeekFloat(bank,off+28)
	u# = PeekFloat(bank,off+32)
	v# = PeekFloat(bank,off+36)
	b = AddVertex(surf,x,y,z,u,v)
	x# = PeekFloat(bank,off+40)
	y# = PeekFloat(bank,off+44)
	z# = PeekFloat(bank,off+48)
	u# = PeekFloat(bank,off+52)
	v# = PeekFloat(bank,off+56)
	c = AddVertex(surf,x,y,z,u,v)
	AddTriangle(surf,a,b,c)
	Next
	FreeBank bank
Next
UpdateNormals mesh
Return mesh
End Function

It is an editor, where you can drag vertices of meshes.
Drawing/hiding the vertices is working allright, however I would like to try and make it more strict. Maybe I could use small (3d) sprites to mark the vertices? Strange thing would be that the dots become very big when you zoom. :)