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