Edit Mesh with Mouse and Keyboard

Everything related to 3D programming
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Edit Mesh with Mouse and Keyboard

Post by J. Baker »

Code updated Sept. 9, 2016

Issues:
Line 62: GetMeshData() crashes on OS X.
OpenGL doesn't work in Windows.

Comtois has an alternative method in this link.

Code: Select all

;Sept. 9, 2016 - J. Baker & applePi
;PureBasic v5.43 - Tested on Windows XP - Crashes on OS X (possible bug with GetMeshData())
;Use mouse to select vertex. Move vertex with arrow keys.

#CameraSpeed = 0.4

Global Dim MeshVertexData.PB_MeshVertex(0)

Declare UpdateMatrix()

Global x.f, y.f, z.f, Entity.i, Verts.i

Procedure UpdateVertColor()
  For Verts = 1 To MeshVertexCount(0)
    SetEntityMaterial(Verts, MaterialID(1))
  Next
EndProcedure

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

If InitEngine3D()
 
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/GUI", #PB_3DArchive_FileSystem)
  Parse3DScripts()
 
  InitSprite()
  InitKeyboard()
  InitMouse()
 
  If Screen3DRequester()
         
    MaterialFilteringMode(#PB_Default, #PB_Material_Anisotropic, 8)
   
      CreateMaterial(0, LoadTexture(0, "Caisse.png"))
      SetMaterialColor(0, #PB_Material_SelfIlluminationColor, RGB(255, 255, 255))
      MaterialCullingMode(0, #PB_Material_NoCulling)
     
      GetScriptMaterial(1, "Color/Red")
      SetMaterialColor(1, #PB_Material_SelfIlluminationColor, RGB(255, 0, 0))
     
      GetScriptMaterial(2, "Color/Yellow")
      SetMaterialColor(2, #PB_Material_SelfIlluminationColor, RGB(255, 255, 0))
     
    CreateMesh(0, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
   
      MeshVertexPosition(-128,128,0)
        MeshVertexTextureCoordinate(0,0)
      MeshVertexPosition(128,128,0)
        MeshVertexTextureCoordinate(0,1)
      MeshVertexPosition(128,-128,0)
        MeshVertexTextureCoordinate(1,1)
      MeshVertexPosition(-128,-128,0)
        MeshVertexTextureCoordinate(1,0)
       
      MeshFace(2,1,0)
      MeshFace(0,3,2)
   
    FinishMesh(#True) ;-texture doesn't show when false but then you can not edit
    SetMeshMaterial(0, MaterialID(0))
    CreateEntity(0, MeshID(0), #PB_Material_None)
   
    GetMeshData(0, 0, MeshVertexData(), #PB_Mesh_Vertex, 0, MeshVertexCount(0) -1)
    For Verts = 1 To MeshVertexCount(0)
      CreateCube(Verts, 8)
      CreateEntity(Verts, MeshID(Verts), MaterialID(1), MeshVertexData(Verts-1)\x, MeshVertexData(Verts-1)\y, MeshVertexData(Verts-1)\z)
    Next
   
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 0, 500, #PB_Absolute)
   
    ShowGUI(128, 1)
   
    Repeat
      Screen3DEvents()
     
      ExamineKeyboard()
     
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
       
        InputEvent3D(MouseX(), MouseY(), MouseButton(#PB_MouseButton_Left))
   
        If MouseButton(#PB_MouseButton_Left) <> 0
            Entity = MousePick(0, MouseX(), MouseY())
            SetWindowTitle(0, "Entity = " + Str(Entity))
          If Entity > 0
            UpdateVertColor()
            MoveVert = 1
            SetEntityMaterial(Entity, MaterialID(2))
          ElseIf Entity = -1
            MoveVert = 0
            UpdateVertColor()
          EndIf
        EndIf
      EndIf
     
      If KeyboardReleased(#PB_Key_W)
          If wire = 0
            MaterialShadingMode(0,#PB_Material_Wireframe)
            wire ! 1
          Else
            MaterialShadingMode(0,#PB_Material_Solid)
            wire ! 1
          EndIf
      EndIf
       
      If MoveVert = 1
        If KeyboardPushed(#PB_Key_Left)
          MoveEntity(Entity, -5, 0, 0, #PB_Relative)
          x = MeshVertexData(Entity -1)\x: y = MeshVertexData(Entity -1)\y
          x = EntityX(Entity) :UpdateMatrix()
        ElseIf KeyboardPushed(#PB_Key_Right)
          MoveEntity(Entity, 5, 0, 0, #PB_Relative)
          x = MeshVertexData(Entity -1)\x: y = MeshVertexData(Entity -1)\y
          x = EntityX(Entity) :UpdateMatrix()
        ElseIf KeyboardPushed(#PB_Key_Up)
          MoveEntity(Entity, 0, 5, 0, #PB_Relative)
          x = MeshVertexData(Entity -1)\x: y = MeshVertexData(Entity -1)\y
          y = EntityY(Entity):UpdateMatrix()
        ElseIf KeyboardPushed(#PB_Key_Down)
          MoveEntity(Entity, 0, -5, 0, #PB_Relative)
          x = MeshVertexData(Entity -1)\x: y = MeshVertexData(Entity -1)\y
          y = EntityY(Entity) :UpdateMatrix()
         
        EndIf
      EndIf
     
      RenderWorld()
     
      FlipBuffers()
     
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
   
  EndIf
 
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End

Procedure UpdateMatrix()
  MeshVertexData(Entity -1)\x = x
  MeshVertexData(Entity -1)\y = y
  MeshVertexData(Entity -1)\z = z
  SetMeshData(0,0, MeshVertexData(), #PB_Mesh_Vertex, 0, MeshVertexCount(0)-1)
EndProcedure
Last edited by J. Baker on Sat Sep 10, 2016 6:03 pm, edited 7 times in total.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: Move mesh vertices with mouse?

Post by J. Baker »

Maybe I'm getting tired but the entity keeps changing to -1 when moving it with the mouse. The lines commented out haven't been tested yet.

EDIT: Old code removed. Update in first post.
Last edited by J. Baker on Sat Sep 10, 2016 2:17 am, edited 6 times in total.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Move mesh vertices with mouse?

Post by applePi »

but the entity keeps changing to -1 when moving it with the mouse
this happened only when the mouse over an empty space , but if you move the mouse slowly so it will always over the entities it will not change to -1
Move mesh vertices with mouse
i thought first you want to deform the mesh with the mouse since there is no such example any where, i think 80% of the solution to the deforming mesh by the mouse available in the PB example ConvertWorldToLocalPosition.pb the other 20% is a mathematics problems. i am still don't know how to do this but this is the start point.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: Move mesh vertices with mouse?

Post by J. Baker »

Well I figured out how to get around the mouse issue. After selecting a vertex with the mouse, use the arrow keys to adjust. One issue though. I'm not sure you can edit a textured mesh? Updated code.

EDIT: Old code removed. Update in first post.
Last edited by J. Baker on Sat Sep 10, 2016 2:17 am, edited 3 times in total.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Move mesh vertices with mouse?

Post by applePi »

if you means to stretch the texture with the stretched mesh dynamically whenever we move the small red cubes, the following seems to work. it is not far than your commented code in the second code, the texture stretch by Ogre engine without any need to edit it
select the small red cube at the top right and move it with arrow keys. to switch wire or solid frame press W
hope this is what is needed

Code: Select all

#CameraSpeed = 0.4

Global Dim MeshVertexData.PB_MeshVertex(0)

Declare UpdateMatrix()
Global x.f
Global y.f
Global z.f

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

If InitEngine3D()
 
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/GUI", #PB_3DArchive_FileSystem)
  Parse3DScripts()
 
  InitSprite()
  InitKeyboard()
  InitMouse()
 
  If Screen3DRequester()
         
    MaterialFilteringMode(#PB_Default, #PB_Material_Anisotropic, 8)
   
      CreateMaterial(0, LoadTexture(0, "Caisse.png"))
      SetMaterialColor(0, #PB_Material_SelfIlluminationColor, RGB(255, 255, 255))
      MaterialCullingMode(0, #PB_Material_NoCulling)
      
      GetScriptMaterial(1, "Color/Red")
      SetMaterialColor(1, #PB_Material_SelfIlluminationColor, RGB(255, 0, 0))
      
      GetScriptMaterial(2, "Color/Yellow")
      SetMaterialColor(2, #PB_Material_SelfIlluminationColor, RGB(255, 255, 0))
      
    CreateMesh(0, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
   
      MeshVertexPosition(-128,128,0)
        MeshVertexTextureCoordinate(0,0)
      MeshVertexPosition(128,128,0)
        MeshVertexTextureCoordinate(0,1)
      MeshVertexPosition(128,-128,0)
        MeshVertexTextureCoordinate(1,1)
      MeshVertexPosition(-128,-128,0)
        MeshVertexTextureCoordinate(1,0)
       
      MeshFace(2,1,0)
      MeshFace(0,3,2)
   
    FinishMesh(#True) ;-texture doesn't show when false but then you can not edit
    SetMeshMaterial(0, MaterialID(0))
    CreateEntity(0, MeshID(0), #PB_Material_None)
    
    GetMeshData(0, 0, MeshVertexData(), #PB_Mesh_Vertex, 0, MeshVertexCount(0) -1)
    For Verts = 1 To MeshVertexCount(0)
      CreateCube(Verts, 8)
      CreateEntity(Verts, MeshID(Verts), MaterialID(1), MeshVertexData(Verts-1)\x, MeshVertexData(Verts-1)\y, MeshVertexData(Verts-1)\z)
    Next
   
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 0, 500, #PB_Absolute)
    
    ShowGUI(128, 1)
    
;MaterialShadingMode(0, #PB_Material_Wireframe)
    
    Repeat
      Screen3DEvents()
     
      ExamineKeyboard()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
        
        InputEvent3D(MouseX(), MouseY(), MouseButton(#PB_MouseButton_Left))
   
        If MouseButton(#PB_MouseButton_Left) <> 0
            Entity = MousePick(0, MouseX(), MouseY())
            SetWindowTitle(0, "Entity = " + Str(Entity))
          If Entity > 0
            ;MoveEntity(Entity, PickX(), PickY(), 0, #PB_Absolute)
            MoveVert = 1
            SetEntityMaterial(Entity, MaterialID(2))
          ElseIf Entity = -1
            MoveVert = 0
            For Verts = 1 To MeshVertexCount(0)
              SetEntityMaterial(Verts, MaterialID(1))
            Next
          EndIf
        EndIf
      EndIf
      
      If KeyboardReleased(#PB_Key_W)
          If wire = 0
            MaterialShadingMode(0,#PB_Material_Wireframe)
            wire ! 1
          Else
            MaterialShadingMode(0,#PB_Material_Solid)
            wire ! 1
          EndIf
      EndIf
        
      If MoveVert = 1
        If KeyboardPushed(#PB_Key_Left)
          MoveEntity(Entity, -5, 0, 0, #PB_Relative)
          x = MeshVertexData(1)\x: y = MeshVertexData(1)\y
          x = EntityX(Entity) :UpdateMatrix()
          
        ElseIf KeyboardPushed(#PB_Key_Right)
          MoveEntity(Entity, 5, 0, 0, #PB_Relative)
          x = MeshVertexData(1)\x: y = MeshVertexData(1)\y
          x = EntityX(Entity) :UpdateMatrix()
        ElseIf KeyboardPushed(#PB_Key_Up)
          MoveEntity(Entity, 0, 5, 0, #PB_Relative)
          x = MeshVertexData(1)\x: y = MeshVertexData(1)\y
          y = EntityY(Entity):UpdateMatrix()
        ElseIf KeyboardPushed(#PB_Key_Down)
          MoveEntity(Entity, 0, -5, 0, #PB_Relative)
          x = MeshVertexData(1)\x: y = MeshVertexData(1)\y
          y = EntityY(Entity) :UpdateMatrix()
          
        EndIf
      EndIf
      
      RenderWorld()
     
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
  EndIf
 
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End

Procedure UpdateMatrix()
      MeshVertexData(1)\x = x
      MeshVertexData(1)\y = y
      MeshVertexData(1)\z = z
      ;SetMeshData(#Mesh, SubMesh, DataArray(), Flags, FirstIndex, LastIndex)
      SetMeshData(0,0, MeshVertexData(), #PB_Mesh_Vertex, 0, MeshVertexCount(0)-1)
      
    EndProcedure
   
Edit: the code edited
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: Move mesh vertices with mouse?

Post by Comtois »

Another way

Code: Select all

#CameraSpeed = 0.4

Global Dim MeshVertexData.PB_MeshVertex(0)

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

If InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/GUI", #PB_3DArchive_FileSystem)
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
    MaterialFilteringMode(#PB_Default, #PB_Material_Anisotropic, 8)
    
    CreateMaterial(0, LoadTexture(0, "Caisse.png"))
    SetMaterialColor(0, #PB_Material_SelfIlluminationColor, RGB(255, 255, 255))
    
    GetScriptMaterial(1, "Color/Red")
    SetMaterialColor(1, #PB_Material_SelfIlluminationColor, RGB(255, 0, 0))
    
    GetScriptMaterial(2, "Color/Yellow")
    SetMaterialColor(2, #PB_Material_SelfIlluminationColor, RGB(255, 255, 0))
    
    CreateMesh(0, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
    
    MeshVertexPosition(-128,128,0)
    MeshVertexTextureCoordinate(0,0)
    MeshVertexPosition(128,128,0)
    MeshVertexTextureCoordinate(0,1)
    MeshVertexPosition(128,-128,0)
    MeshVertexTextureCoordinate(1,1)
    MeshVertexPosition(-128,-128,0)
    MeshVertexTextureCoordinate(1,0)
    
    MeshFace(2,1,0)
    MeshFace(0,3,2)
    
    FinishMesh(#True) ;-texture doesn't show when false but then you can not edit
    SetMeshMaterial(0, MaterialID(0))
    CreateEntity(0, MeshID(0), #PB_Material_None)
    
    GetMeshData(0, 0, MeshVertexData(), #PB_Mesh_Vertex, 0, MeshVertexCount(0) -1)
    
    
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 0, 500, #PB_Absolute)
    
    ShowGUI(128, 1)
    
    CreateSprite(0,7,7)
    StartDrawing(SpriteOutput(0))
    Circle(3,3,3,#Red)
    StopDrawing()
    
    CreateSprite(1,11,11)
    StartDrawing(SpriteOutput(1))
    ;DrawingMode(#PB_2DDrawing_Outlined)
    Circle(5,5,5,#Yellow)
    Circle(5,5,3,#Black)
    StopDrawing()   
    Repeat
      Screen3DEvents()
      
      ExamineKeyboard()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
        
        InputEvent3D(MouseX(), MouseY(), MouseButton(#PB_MouseButton_Left))
        
        If MouseButton(#PB_MouseButton_Left) 
          MouseLeft = #True
        Else
          MouseLeft = #False
          Vertex = -1
        EndIf
      EndIf
      
      
      
      RenderWorld()
      
      For i=0 To MeshVertexCount(0)-1      
        x = CameraProjectionX(0, MeshVertexData(i)\x, MeshVertexData(i)\y, MeshVertexData(i)\z) 
        y = CameraProjectionY(0, MeshVertexData(i)\x, MeshVertexData(i)\y, MeshVertexData(i)\z) 
        DisplayTransparentSprite(0, x-SpriteWidth(0)/2, y-SpriteHeight(0)/2)
        dx.f = x-MouseX()
        dy.f = y-MouseY()
        distance.f = Sqr(dx*dx + dy*dy)
        
        If  distance < 5 
          DisplayTransparentSprite(1, x-SpriteWidth(1)/2, y-SpriteHeight(1)/2)
          If MouseLeft
            Vertex = i
     
          EndIf
   
        EndIf  
      Next
      If Vertex > -1
        MeshVertexData(Vertex)\x + MouseDeltaX()
        MeshVertexData(Vertex)\y - MouseDeltaY()
        SetMeshData(0,0, MeshVertexData(), #PB_Mesh_Vertex, 0, MeshVertexCount(0)-1)
      EndIf
      
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End
Please correct my english
http://purebasic.developpez.com/
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: Move mesh vertices with mouse?

Post by J. Baker »

Nice additions applePi and Comtois! :D

I've updated it even further. Update in first post. All vertices can be moved now (only top-right previously). Only selected vert color is yellow now (previously selected verts stayed yellow). I think that's it. ;)
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Edit Mesh with Mouse and Keyboard

Post by applePi »

Thanks J. Baker and Comtois, i have a very slow snail brain, just now i have recognized the importance of Comtois example, it is a real mesh editing, i have tried it with some meshes which have one submesh like a sphere and a cube (cubes in version < 5.50), and was able to damage the cube (we must use MaterialCullingMode(0, #PB_Material_NoCulling ) to see inside the damaged cube, also was able to make spikes on the sphere. when we edit the object vertices it is easier to move or rotate the camera on demand and not the object
also the approach by J. Baker have value by attaching tiny cubes to the vertices of meshes and submeshes, i see many usages of this approach
the other usage is to deform pictures .
the new thread title "Edit Mesh with Mouse and Keyboard" describe exactly the situation
thanks for all
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: Edit Mesh with Mouse and Keyboard

Post by J. Baker »

Yeah, I like both methods. It just all comes down to, what you plan to do and how you want to do it. That's why I made a link to Comtois example in the first post. At least we now have examples that allows someone to get an idea of how it works. More coding would be needed for larger or multiple meshes, of course.

I just realized that OpenGL doesn't work in Windows with the first example. May have to report another bug to be fixed.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Edit Mesh with Mouse and Keyboard

Post by applePi »

Picking Mesh Triangle (making holes)
deleting the mesh triangles:
the Ideas: position the sprites or cubes over the triangles center, then when mouse click we know the index of the first vertex of the specific triangle, we then pass this index to the deleteTriangle procedure which will draw all the mesh again except the triangle with that index

the first example using Comtois demo with a 10X10 Plane, Sleep_(150) is necessary else every click will delete several triangles , wish there is MouseReleased in the same sense of KeyboardReleased
key W: toggle wire/solid view,.... space: toggle rotation
using mouse: click on any red sprite to delete one mesh triangle beneath it

Code: Select all

#CameraSpeed = 0.4
#NbX = 10: #NbZ = 10 ; plane size 10x10

Declare DeleteTri()
Declare Plane()

Global Dim MeshVertexData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)
Global ind.i ; index of the first vertex of every triangle

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

If InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/GUI", #PB_3DArchive_FileSystem)
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
    MaterialFilteringMode(#PB_Default, #PB_Material_Anisotropic, 8)
    
    CreateMaterial(0, LoadTexture(0, "Caisse.png"))
    SetMaterialColor(0, #PB_Material_SelfIlluminationColor, RGB(255, 255, 255))
    MaterialCullingMode(0, #PB_Material_NoCulling)
    
    GetScriptMaterial(1, "Color/Red")
    SetMaterialColor(1, #PB_Material_SelfIlluminationColor, RGB(255, 0, 0))
    
    GetScriptMaterial(2, "Color/Yellow")
    SetMaterialColor(2, #PB_Material_SelfIlluminationColor, RGB(255, 255, 0))
    
    CreateMesh(0, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
    Plane() ; plane making 10x10
    CreateEntity(0, MeshID(0), MaterialID(0))
        
    SetMeshMaterial(0, MaterialID(0))
    CreateEntity(0, MeshID(0), #PB_Material_None)
    
    ;SetMeshData(0,0, MeshVertexData(), #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(0)-1)
    GetMeshData(0, 0, MeshVertexData(), #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate, 0, MeshVertexCount(0) -1)
    GetMeshData(0,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(0, 0)-1)
    
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 0, 13, #PB_Absolute)
    
    ShowGUI(128, 1)
    
    CreateSprite(0,7,7)
    StartDrawing(SpriteOutput(0))
    Circle(3,3,3,#Red)
    StopDrawing()
    
    CreateSprite(1,11,11)
    StartDrawing(SpriteOutput(1))
    ;DrawingMode(#PB_2DDrawing_Outlined)
    Circle(5,5,5,#Yellow)
    Circle(5,5,3,#Black)
    StopDrawing()   
    Repeat
      Screen3DEvents()
      
      ExamineKeyboard()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
        
        InputEvent3D(MouseX(), MouseY(), MouseButton(#PB_MouseButton_Left))
        
        If MouseButton(#PB_MouseButton_Left) 
         
          MouseLeft = #True
          Sleep_(150)
          
          
        Else
          MouseLeft = #False
          Ind = -1
        EndIf
      EndIf
      
      If KeyboardReleased(#PB_Key_W)
          If wire = 0
            MaterialShadingMode(0,#PB_Material_Wireframe)
            wire ! 1
          Else
            MaterialShadingMode(0,#PB_Material_Solid)
            wire ! 1
          EndIf
        EndIf
        
        If KeyboardReleased(#PB_Key_Space)
        rot ! 1
        
        EndIf
      RotateEntity(0, 0,rot,0, #PB_Relative)
      
      RenderWorld()
      
      For i=0 To MeshIndexCount(0)-1 Step 3
        x1 = MeshVertexData(MeshDataInd(i)\Index)\x
        y1 = MeshVertexData(MeshDataInd(i)\Index)\y
        z1 = MeshVertexData(MeshDataInd(i)\Index)\z
        
        x2 = MeshVertexData(MeshDataInd(i+1)\Index)\x
        y2 = MeshVertexData(MeshDataInd(i+1)\Index)\y
        z2 = MeshVertexData(MeshDataInd(i+1)\Index)\z
        
        x3 = MeshVertexData(MeshDataInd(i+2)\Index)\x
        y3 = MeshVertexData(MeshDataInd(i+2)\Index)\y
        z3 = MeshVertexData(MeshDataInd(i+2)\Index)\z
        
        ;x = CameraProjectionX(0, MeshVertexData(i)\x, MeshVertexData(i)\y, MeshVertexData(i)\z) 
        ;y = CameraProjectionY(0, MeshVertexData(i)\x, MeshVertexData(i)\y, MeshVertexData(i)\z) 
        x = CameraProjectionX(0, (x1+x2+x3)/3,(y1+y2+y3)/3,(z1+z2+z3)/3)
        y = CameraProjectionY(0, (x1+x2+x3)/3,(y1+y2+y3)/3,(z1+z2+z3)/3)
        
        DisplayTransparentSprite(0, x-SpriteWidth(0)/2, y-SpriteHeight(0)/2)
        ;DisplayTransparentSprite(0, x, y)
        dx.f = x-MouseX()
        dy.f = y-MouseY()
        distance.f = Sqr(dx*dx + dy*dy)
        
        If  distance < 7
          DisplayTransparentSprite(1, x-SpriteWidth(1)/2, y-SpriteHeight(1)/2)
          ;DisplayTransparentSprite(1, x, y)
          
          If MouseLeft
             Ind = i ; ind is the index of the first vertex (from 3) of the triangle
             MouseLeft = 0
          EndIf
   
        EndIf  
      Next
      If Ind > -1
        DeleteTri()
        
      EndIf
      
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End

Procedure DeleteTri()
  GetMeshData(0,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(0, 0)-1)
  vertexNumbers = MeshVertexCount(0)
  FreeEntity(0)
  FreeMesh(0)
  CreateMesh(0, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
  ;just a placeHolders to fill later with mesh vertex data with SetMeshData(...) function
  For i=1 To vertexNumbers
  MeshVertexPosition(0,0,0)
  MeshVertexTextureCoordinate(0,0)
  Next
  
  SetMeshData(0,0, MeshVertexData(), #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(0)-1)
      
  ArrSizeInd = ArraySize(MeshDataInd()) 
  ;Debug ArrSizeInd
  For i=0 To ArrSizeInd Step 3
    If i<>ind ; ind is the index of the first vertex (from 3) of the triangle
      MeshFace(MeshDataInd(i)\Index, MeshDataInd(i+1)\Index,MeshDataInd(i+2)\Index)
      ;ie bypass the triangle which have index ind    
    EndIf  
  
   Next
   FinishMesh(#True) ;-texture doesn't show when false but then you can not edit
   
    SetMeshMaterial(0, MaterialID(0))
    CreateEntity(0, MeshID(0), #PB_Material_None)
    
   GetMeshData(0,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(0, 0)-1)
   SetMeshData(0,0, MeshVertexData(), #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(0)-1)
   SetMeshData(0,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(0, 0)-1)
   ;UpdateMeshBoundingBox(0)
 EndProcedure
 
 Procedure Plane() ; from purebasic examples, make a plane
  Protected.l a, b, c, Nb
  Protected.w P1, P2, P3, P4
  
  For b=0 To #NbZ
    For a=0 To #NbX
      MeshVertexPosition(a - #NbX/2, 0, b - #NbZ/2)
      MeshVertexNormal(0,1,0)
      MeshVertexTextureCoordinate(a/#NbX, b/#NbZ)
    Next a
  Next b
 
  Nb=#NbX+1
  For b=0 To #NbZ-1
    For a=0 To #NbX-1
      P1=a+(b*Nb)
      P2=P1+1
      P3=a+(b+1)*Nb
      P4=P3+1
     
      MeshFace(P3, P2, P1)
      MeshFace(P2, P3, P4)
    Next
  Next
  FinishMesh(#True)
  SetMeshMaterial(0, MaterialID(0))
  TransformMesh(0,0,0,0,1,1,1,90,0,0) ; just to rotate the plane 90 degree
EndProcedure 
the second example with a sphere (i was not able to position the sprites in the middle of the triangles so i have used J.Baker approach)
as a proof: i have made what is like a Halloween Pumpkin, download it with a mesh viewer from here https://www.mediafire.com/?evac6orgekdvvs1 W: toggle wire/solid view

usage:
with mouse click on the red cubes to delete the triangles beneath it
keys:
W: toggle wire/solid view
A: activate mouse rotation and keyboard for the camera
C: toggle scene from above or side of the sphere
H: toggle hide of the green plane (needed for seeing better the triangles)
Space: toggle rotation
S: save mesh as sphereWithHole.mesh

Code: Select all

#CameraSpeed = 0.5
#NbX = 10: #NbZ = 10
Define.f KeyX, KeyY

Global Dim MeshVertexData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)


Declare UpdateMatrix()
Declare DeleteTri()
Declare Plane()
Declare cubesPositions()

Global x.f, y.f, z.f, Entity.i, Verts.i , ind.i, tri.i, triangle.i, cubes.i

Procedure UpdatePlaceHolderColor()
  SetEntityMaterial(Entity, MaterialID(2))
EndProcedure

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

If InitEngine3D()
 
  Add3DArchive(".", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/GUI", #PB_3DArchive_FileSystem)
  Parse3DScripts()
 
  InitSprite()
  InitKeyboard()
  InitMouse()
 
  If Screen3DRequester()
         
    MaterialFilteringMode(#PB_Default, #PB_Material_Anisotropic, 8)
   
      CreateMaterial(0, LoadTexture(0, "Caisse.png"))
      SetMaterialColor(0, #PB_Material_SelfIlluminationColor, RGB(255, 255, 255))
      MaterialCullingMode(0, #PB_Material_NoCulling)
     
      GetScriptMaterial(1, "Color/Red")
      SetMaterialColor(1, #PB_Material_SelfIlluminationColor, RGB(255, 0, 0))
     
      GetScriptMaterial(2, "Color/Green")
      SetMaterialColor(2, #PB_Material_SelfIlluminationColor, RGB(0, 255, 0))
      CreateLight(0, RGB(255,255,255), 0, 100,50)
      ;WorldShadows( #PB_Shadow_Modulative)
      ;CreateMesh(5000, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
      CreateSphere(5000,5)
      ;LoadMesh(5000, "sphereWithHole.mesh")
      ;Plane() ; call plane making procedure  
      
   
      CreateEntity(5000, MeshID(5000), MaterialID(0))
            
   
    GetMeshData(5000, 0, MeshVertexData(), #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(5000) -1)
    GetMeshData(5000,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(5000, 0)-1)
    
    ;making small cubes with numbers from 0 to number of triangles in the mesh
    
    CreateCube(0, 0.2)
    triangle= 0
    
    For i=0 To MeshIndexCount(5000)-1 Step 3
        
        x1.f = MeshVertexData(MeshDataInd(i)\Index)\x
        y1.f = MeshVertexData(MeshDataInd(i)\Index)\y
        z1.f = MeshVertexData(MeshDataInd(i)\Index)\z
        
        x2.f = MeshVertexData(MeshDataInd(i+1)\Index)\x
        y2.f = MeshVertexData(MeshDataInd(i+1)\Index)\y
        z2.f = MeshVertexData(MeshDataInd(i+1)\Index)\z
        
        x3.f = MeshVertexData(MeshDataInd(i+2)\Index)\x
        y3.f = MeshVertexData(MeshDataInd(i+2)\Index)\y
        z3.f = MeshVertexData(MeshDataInd(i+2)\Index)\z
        CreateEntity(triangle, MeshID(0), MaterialID(1), (x1+x2+x3)/3,(y1+y2+y3)/3,(z1+z2+z3)/3)
      triangle + 1  
    Next
    ;Debug triangle
    cubes = MeshIndexCount(5000)/3
    ;Debug cubes
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 5, 12, #PB_Absolute)
    CameraLookAt(0, 0, 0, 0)
    ;CameraBackColor(0, RGB(10, 10, 10))
   
    ShowGUI(128, 1)
    
    ;MaterialShadingMode(0,#PB_Material_Wireframe)
    CreatePlane(6000,15, 15, 10, 10, 1,1)
    CreateEntity(6000, MeshID(6000), MaterialID(2) )
    Repeat
      Screen3DEvents()
          
      ExamineKeyboard()
          
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.1
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.1
       
        InputEvent3D(MouseX(), MouseY(), MouseButton(#PB_MouseButton_Left))
   
        If MouseButton(#PB_MouseButton_Left) <> 0
          Entity = MousePick(0, MouseX(), MouseY())
          ind = Entity*3 ; get the index of the first vertex of the triangle since Entity is numbered 0,1,2,3,4...
            SetWindowTitle(0, "triangle = " + Str(Entity))
          If Entity >= 0
            ;UpdatePlaceHolderColor()
            ;selectedCube = 1
            DeleteTri()
          ElseIf Entity = -1
            ;selectedCube = 0
           
          EndIf
        EndIf
      EndIf
      If KeyboardReleased(#PB_Key_C)
        If cam = 0
        MoveCamera(0, 0, 15, 2, #PB_Absolute)
        CameraLookAt(0, 0, 0, 0)
        cam ! 1  
      Else 
        MoveCamera(0, 0, 5, 12, #PB_Absolute)
        CameraLookAt(0, 0, 0, 0)
        cam ! 1
      EndIf
    EndIf
    
      
      If KeyboardReleased(#PB_Key_W)
          If wire = 0
            MaterialShadingMode(0,#PB_Material_Wireframe)
            wire ! 1
          Else
            MaterialShadingMode(0,#PB_Material_Solid)
            wire ! 1
          EndIf
        EndIf
        
        If KeyboardReleased(#PB_Key_Space)
        rot ! 1
        
      EndIf
      
      If KeyboardReleased(#PB_Key_S)
        UpdateMeshBoundingBox(5000)
        SaveMesh(5000, "sphereWithHole.mesh")
      EndIf
      
      If KeyboardReleased(#PB_Key_H)
        hide ! 1
        HideEntity(6000,hide)
      EndIf
      
      
      If KeyboardReleased(#PB_Key_A)
        mouse ! 1
      EndIf
      
      If mouse
      If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf
        MoveCamera  (0, KeyX, 0, KeyY)
        RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      EndIf 
      
      RotateEntity(5000, 0,rot,0, #PB_Relative)
       
      ;If selectedCube = 1
      ;If KeyboardReleased(#PB_Key_D)
        ;DeleteTri()
        
      ;EndIf
      ;EndIf
           
      RenderWorld()
     
      FlipBuffers()
     
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
   
  EndIf
 
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End


Procedure DeleteTri()
  GetMeshData(5000,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(5000, 0)-1)
  vertexNumbers = MeshVertexCount(5000)
  FreeEntity(5000)
  FreeMesh(5000)
  CreateMesh(5000, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
  ;just a placeHolders to fill later with mesh vertex data with SetMeshData(...) function
  For i=1 To vertexNumbers
  MeshVertexPosition(0,0,0)
  MeshVertexTextureCoordinate(0,0)
  Next
  
  SetMeshData(5000,0, MeshVertexData(), #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(5000)-1)
      
  ArrSizeInd = ArraySize(MeshDataInd()) 
  ;Debug ArrSizeInd
  For i=0 To ArrSizeInd Step 3
    If i<>ind 
      MeshFace(MeshDataInd(i)\Index, MeshDataInd(i+1)\Index,MeshDataInd(i+2)\Index)
          
    EndIf  
  
   Next
   FinishMesh(#True) 
  
   cubesPositions() ; call to redraw cubes over the trianhles since its indices changed
    SetMeshMaterial(5000, MaterialID(0))
    CreateEntity(5000, MeshID(5000), #PB_Material_None)
    
   GetMeshData(5000,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(5000, 0)-1)
   SetMeshData(5000,0, MeshVertexData(), #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(5000)-1)
   SetMeshData(5000,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(5000, 0)-1)
   ;UpdateMeshBoundingBox(5000) ; sotimes hanges the cubes selections
 EndProcedure
 
 ;-Procedures
Procedure Plane()
  Protected.l a, b, c, Nb
  Protected.w P1, P2, P3, P4
  ;#NbX = 5: #NbZ = 5
  ;CreateMesh(5000)
  For b=0 To #Nbz
    For a=0 To #NbX
      MeshVertexPosition(a - #NbX/2, 0, b - #Nbz/2)
      MeshVertexNormal(0,1,0)
      MeshVertexTextureCoordinate(a/#NbX, b/#Nbz)
    Next a
  Next b
 
  Nb=#NbX+1
  For b=0 To #NbZ-1
    For a=0 To #NbX-1
      P1=a+(b*Nb)
      P2=P1+1
      P3=a+(b+1)*Nb
      P4=P3+1
     
      MeshFace(P3, P2, P1)
      MeshFace(P2, P3, P4)
    Next
  Next
  FinishMesh(#True)
  SetMeshMaterial(5000, MaterialID(0))
  TransformMesh(5000,0,0,0,1,1,1,90,0,0) ; just to rotate the plane 90 degree
EndProcedure 

Procedure cubesPositions()
  GetMeshData(5000,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(5000, 0)-1)
  For i=0 To cubes-1
    
    FreeEntity(i)
  Next
  cubes - 1
  
  triangle= 0
    
    For i=0 To MeshIndexCount(5000)-1 Step 3
        
        x1.f = MeshVertexData(MeshDataInd(i)\Index)\x
        y1.f = MeshVertexData(MeshDataInd(i)\Index)\y
        z1.f = MeshVertexData(MeshDataInd(i)\Index)\z
        
        x2.f = MeshVertexData(MeshDataInd(i+1)\Index)\x
        y2.f = MeshVertexData(MeshDataInd(i+1)\Index)\y
        z2.f = MeshVertexData(MeshDataInd(i+1)\Index)\z
        
        x3.f = MeshVertexData(MeshDataInd(i+2)\Index)\x
        y3.f = MeshVertexData(MeshDataInd(i+2)\Index)\y
        z3.f = MeshVertexData(MeshDataInd(i+2)\Index)\z
        ;FreeEntity(triangle)
        CreateEntity(triangle, MeshID(0), MaterialID(1), (x1+x2+x3)/3,(y1+y2+y3)/3,(z1+z2+z3)/3)
      triangle + 1  
    Next
    
  EndProcedure
  

Notes:
works only with meshes have one submesh
to convert a mesh with several submeshes to only one submesh (number zero) look the last example here: http://purebasic.fr/english/viewtopic.php?f=36&t=66068
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: Edit Mesh with Mouse and Keyboard

Post by J. Baker »

Nice examples! I will have to study them further after a bit. ;)
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
Post Reply