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