is vertex visible ?
Blitz3D Forums/Blitz3D Programming/is vertex visible ?
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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 |
| ||
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. |
| ||
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 |
| ||
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. :) |
| ||
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 |
| ||
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. |
| ||
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 |