Not a PB bug. You're trying to extract more vertices than are present:
call.
.
The ratio between faces and vertices is unlikely to be 1:3 as vertices will often be shared/reused.
Here's an adjustment of your example, demonstrating successful copying of each triangular face from a given mesh out to their own entities:
Code: Select all
ExamineDesktops()
RX=1280:RY=720
InitEngine3D()
InitSprite():InitKeyboard():InitMouse()
OpenWindow(0,0,0,RX,RY,"Title",#PB_Window_BorderLess|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0),0,0,DesktopScaledX(RX),DesktopScaledY(RY),1,0,0,#PB_Screen_WaitSynchronization)
Enumeration; Camaras
#Camara
EndEnumeration
Enumeration; Luces
#Luz
EndEnumeration
Enumeration; Texturas
#Textura
EndEnumeration
Enumeration; Materiales
#Material
EndEnumeration
Enumeration; Mallas
#Object0malla
#Object1malla=100
EndEnumeration
Enumeration; Entidades
#Object0
#Object1=100
EndEnumeration
Enumeration; Nodos
#Pivotcamara
EndEnumeration
CreateLight(#luz,$EEEEEE,4,4,2,#PB_Light_Point)
CreateCamera(#Camara,0,0,100,100):CameraRange(#Camara,0.1,10000):CameraBackColor(#Camara,$181911)
MoveCamera(#Camara,0,0,6,#PB_Absolute)
;CameraRenderMode(#Camara,#PB_Camera_Wireframe)
CreateIcoSphere(#Object0malla,1,1)
CreateEntity(#Object0,MeshID(#Object0malla),#PB_Material_None,-2,0,0)
; Accepts a given mesh and copies each face to a new entity.
;
; - meshToCopy : Mesh from which faces should be copied.
; - submeshToCopy : Submesh from which faces should be copied.
; - outEntities : Array which will be resized and filled with entities built.
; - faceIndex : Index of the mesh face to start copying from. 0-based.
; - faceCount : Count of faces to copy to their own entities, starting from `faceIndex`.
;
; Returns: the total count of entities created.
Procedure.i copyMeshFacesToIndividualEntities(meshToCopy.i, submeshToCopy.i, Array outEntities.i(1), faceIndex.i = 0, faceCount.i = -1)
Protected numSrcVertices = MeshVertexCount(meshToCopy, submeshToCopy)
Protected numSrcIndices = MeshIndexCount(meshToCopy, submeshToCopy)
Protected numSrcFaces = numSrcIndices / 3
; Apply zero base index given OOB value.
If faceIndex < 0
faceIndex = 0
EndIf
; Apply default face count given OOB value.
If faceCount < 0 Or faceCount > numSrcFaces
faceCount = numSrcFaces
EndIf
; Calculate number of faces available after the target index.
; We can exit immediately if there are no such faces.
; Additionally, we must make sure to restrict the number of out faces based upon this
; (so we don't read past the end of our mesh data).
Define numFacesAfterIndex = numSrcFaces - faceIndex
If numFacesAfterIndex <= 0
Goto fail
ElseIf numFacesAfterIndex < faceCount
faceCount = numFacesAfterIndex
EndIf
ReDim outEntities(faceCount - 1)
; Extract all vertices ahead of time, since faces could arbitrarily reference these.
Dim vertices.MeshVertex(numSrcVertices - 1)
If Not GetMeshData(meshToCopy, submeshToCopy, vertices(), #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Color | #PB_Mesh_Tangent, 0, numSrcVertices - 1)
Debug "Failed to read mesh vertex data!"
Goto fail
EndIf
; Extract only indices we're interested in.
Dim indices.MeshFace(faceCount * 3 - 1)
If Not GetMeshData(meshToCopy, submeshToCopy, indices(), #PB_Mesh_Face, faceIndex * 3, (faceIndex + faceCount) * 3 - 1)
Debug "Failed to read mesh face data!"
Goto fail
EndIf
Define x = 0, y = 0
Define idx = 0
For x = 0 To faceCount - 1
Define currentOutFaceMesh = CreateMesh(#PB_Any, #PB_Mesh_TriangleList)
For y = 0 To 2
Define *currentSrcVertex.MeshVertex = vertices(indices(idx)\Index)
MeshVertex(*currentSrcVertex\x,
*currentSrcVertex\y,
*currentSrcVertex\z,
*currentSrcVertex\u,
*currentSrcVertex\v,
*currentSrcVertex\Color,
*currentSrcVertex\NormalX,
*currentSrcVertex\NormalY,
*currentSrcVertex\NormalZ)
MeshVertexTangent(*currentSrcVertex\TangentX, *currentSrcVertex\TangentY, *currentSrcVertex\TangentZ)
idx + 1
Next y
MeshFace(0, 1, 2)
FinishMesh(1)
outEntities(x) = currentOutFaceMesh
Next x
ProcedureReturn faceCount
fail:
ReDim outEntities(0)
ProcedureReturn 0
EndProcedure
Dim faceEntities.i(0)
Define numFaces = copyMeshFacesToIndividualEntities(#Object0malla, 0, faceEntities())
; Create an entity for each cloned face.
For x = 0 To numFaces - 1
CreateEntity(#Object1 + x + 2, MeshID(faceEntities(x)), #PB_Material_None, 2, 0, 0)
Next x
; Create an extremely basic cursor sprite.
Define cursorSprite = CreateSprite(#PB_Any, 16, 16)
StartDrawing(SpriteOutput(cursorSprite))
Box(0, 0, OutputWidth(), OutputHeight(), $ff00ff)
StopDrawing()
Define mouseX, mouseY
Define highlightedEntity = -1
Define matDefault = CreateMaterial(#PB_Any, 0, $ffffff)
Define matHighlight = CreateMaterial(#PB_Any, #Null, $ff00ff)
Repeat
; Make sure to drain the event queue!
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
Break 2
Case #PB_Event_None
Break
EndSelect
ForEver
ExamineKeyboard()
If ExamineMouse()
mouseX = MouseX()
mouseY = MouseY()
EndIf
RotateEntity(#Object0,-1,0.25,-0.5,#PB_Relative)
; Rotate each cloned face.
For x = 0 To numFaces - 1
RotateEntity(#Object1 + x + 2,-1,0.25,-0.5,#PB_Relative)
Next x
RenderWorld()
; Render our simple cursor.
DisplaySprite(cursorSprite, mouseX, mouseY)
; Highlight any actively hovered entity.
Define currentHoveredEntity = MousePick(#Camara, mouseX, mouseY)
If currentHoveredEntity <> highlightedEntity
; Clear previously highlighted entity since we've a change.
If highlightedEntity >= 0
SetEntityMaterial(highlightedEntity, MaterialID(matDefault))
highlightedEntity = -1
EndIf
; Apply highlight if we've an entity actively hovered.
If currentHoveredEntity >= 0
highlightedEntity = currentHoveredEntity
SetEntityMaterial(highlightedEntity, MaterialID(matHighlight))
EndIf
EndIf
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
You can hover over the cloned entities to have the active face highlighted. (Mesh-per-face isn't an optimal approach for this scenario, but it solves OP if I've understood correctly.)
fixed doc typo, removed extra event query.