is vertex visible ?

Blitz3D Forums/Blitz3D Programming/is vertex visible ?

b32(Posted 2006) [#1]
Is there a way to determine if a vertex is visible ? I want to highlight the vertices that are on the camera's side of the entity.
I thought it could be possible by reading the normals of the vertex. My line of thought is, that if the normal points towards the camera, the vertex would be in view. However, I'm not sure if that is true and I don't know how to do that.


Shambler(Posted 2006) [#2]
You need CameraProject I think...no scrap that idea.

Thinking more about it, you could cycle through each triangle of the mesh testing the normals, if the triangles normal points toward you then its vertices are all visible.


b32(Posted 2006) [#3]
Thanks, the method works, but I find it difficult to determine if a vector is pointing towards the camera.

When I turned on WireFrame modus, I realised the common culling is done by checking if a triangle is either clockwise or counter-clockwise. So I think I should give that a try.


b32(Posted 2006) [#4]
Sorry for double-posting, but I found an algo in the archive (by birdie) that determines CW/CCW for a 2d triangle. And it works:

Still, it is not exactly what I want. I think I should try projecting every triangle, and then checking if the projected vertex coordinate is behind any of the triangles from the cameras view.


Stevie G(Posted 2006) [#5]
This is how I would do it - slightly different from your versions. Note that one issue you may have is using updatenormals on the cube as this command averages the normals of shared verts. In this case as the normals are the same for each vertice in the triangle it's probably quicker to just loop throught the triangles rather than the verts.

	;setup graphics
	Graphics3D 800, 600, 0, 2
	SetBuffer BackBuffer()
	
	;enable wireframe	
	WireFrame 1

	;create camera	
	camera = CreateCamera()
	MoveEntity camera, 0, 0, -5
	
	;create pivot for camera	
	campiv = CreatePivot()
	EntityParent camera, campiv
	
	;create cube	
	cube = CreateCube()
	
	;Omit this Line as UpdateNormals averages cooexistent vertices
	;UpdateNormals cube
	s = GetSurface(cube, 1)
	
	Repeat
		
		;turn camera
		TurnEntity campiv, 0, 1, 0
		RenderWorld
		
		;loop through all triangles		
		For v = 0 To CountVertices( s ) - 1
		
			;get global vertex position
			TFormPoint VertexX( s, v ) , VertexY( s, v ), VertexZ( s, 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( s, v ) , VertexNY( s, v ) , VertexNZ( s, v ), cube, 0
			;dot product
			Dot# = Cx * TFormedX() + Cy * TFormedY() + Cz * TFormedZ()
			
			If Dot< 0 			
				TFormPoint VertexX( s, v ) , VertexY( s, v) , VertexZ( s, v ), cube, 0
				CameraProject camera, TFormedX(), TFormedY(), TFormedZ() 
				Color 255,0,0
				Oval ProjectedX()-1, ProjectedY()-1, 3, 3
			End If
			
		Next
							
		Flip
		
	Until KeyHit(1)
	
	End


Stevie


b32(Posted 2006) [#6]
dot product=math<>bram=thank you! I see what you mean with the UpdateNormals() problem. But for that, I can calculate face normals I suppose? Thanks again.


Stevie G(Posted 2006) [#7]
No problem. I use this function to re-calculate polygon normals rather than vertex normals .. the updatenormals function sucks in my opinion. You'll probably have to ensure the mesh has no shared verts before you use this .. but I have an unweld function if you need it.

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



b32(Posted 2006) [#8]
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:

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. :)


Stevie G(Posted 2006) [#9]
Excellent, I'm sure I could make use of this!

Here's my unweld function .. no banks but free's the existing and returns the new mesh. Incase you're interested ..

unction MESHunweld( Mesh )

	Copy = CreateMesh()
	ns = CreateSurface( Copy )
	For su = 1 To CountSurfaces( Mesh )
		s = GetSurface( Mesh , su )
		For t = 0 To CountTriangles( s ) - 1
			v0 = TriangleVertex( s, t, 0 )
			v1 = TriangleVertex( s, t, 1 )
			v2 = TriangleVertex( s, t, 2 )
			Nv0 = AddVertex( ns , VertexX( s , v0 ) , VertexY( s, v0 ) , VertexZ( s, v0 ) )
			Nv1 = AddVertex( ns , VertexX( s , v1 ) , VertexY( s, v1 ) , VertexZ( s, v1 ) )
			Nv2 = AddVertex( ns , VertexX( s , v2 ) , VertexY( s, v2 ) , VertexZ( s, v2 ) )
			VertexColor ns, Nv0 , VertexRed( s, v0 ) , VertexGreen( s, v0 ) , VertexBlue( s, v0 )
			VertexColor ns, Nv1 , VertexRed( s, v1 ) , VertexGreen( s, v1 ) , VertexBlue( s, v1 )
			VertexColor ns, Nv2 , VertexRed( s, v2 ) , VertexGreen( s, v2 ) , VertexBlue( s, v2 )
			AddTriangle ns , Nv0 , Nv1 , Nv2
		Next
	Next
	FreeEntity mesh
	Return Copy

End Function	



For the points, just Rescale the sprites based on distance to camera should sort your dot size. That's assuming you're using the camera z pos to zoom else scale based on the zoom factor.

I'll keep an eye on this.

Stevie


b32(Posted 2006) [#10]
Thanks! I tried the sprites and I even tried painting the vertices on the texture. Sprites were too slow and painting on the texture doesn't look too good. And when I use the these methods, I would still have to find out what vertices are in view. I think the best thing to do now it to write a function that checks if the vertex is behind any triangles.


b32(Posted 2006) [#11]
After a lot of attempts, this is it. I'm using cubes to mark the vertices and then use radial picking to determine what vertex is selected. Note that when two vertices are not on the same surface, they don't stick together. In a newer version, I will update the connect type