now uncomment line 56 ChangeMesh() , and see the sphere part rotate around itself in x axis correctly. the procedure ChangeMesh() are from Comtois here: http://purebasic.fr/english/viewtopic.p ... 15#p417666 so i suggest to add it or an advanced version of it to purebasic functions
someone may say: why not using this procedure yourself ? because:
1- not every one know it, and several questions are asked in the forum about the models which rotate incorrectly around itself
2- it complements the RotateEntity function
3- it change the behavior of the model in an enjoyable way
4- using an explicit procedure will make the code more mysterious and longer.
Code: Select all
Enumeration
#LIGHT
#CAMERA
#WorkSphereMesh = 555
EndEnumeration
#CameraSpeed = 0.5
Define.f KeyX, KeyY, MouseX, MouseY
Global Dim MeshData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)
Global mesh
ExamineDesktops()
If OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), " ... W.... to WireFrame/ SolidFrame ......use mouse + Arrows to rotate + move Camera ", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Define.f KeyX, KeyY
Declare CreateSpherePlus(mesh, radius.f, Segments, Rings, start.f, sphereParts.f)
Declare ChangeMesh()
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)
Parse3DScripts()
InitSprite()
InitKeyboard()
InitMouse()
OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0), 0, 0, 0)
CreateCamera(#camera, 0, 0, 100, 100)
MoveCamera(#camera, 0, 0, 12, #PB_Absolute)
CameraFOV(#camera, 70)
CameraBackColor(#camera, RGB(255,200,200))
CameraLookAt(#camera,0,0,0)
CreateLight(0, RGB(255,255,255), 20, 100, 0)
AmbientColor(RGB(200, 200, 200))
CreateMaterial(5, LoadTexture(5, "fw12b.jpg"))
MaterialCullingMode(5, #PB_Material_NoCulling)
MaterialShadingMode(5, #PB_Material_Wireframe)
;CreateSpherePlus(mesh, radius.f, Segments, Rings, start, sphereParts)
CreateSpherePlus(1, 5, 32,32, 1,8) ; several rings from the sphere
CreateEntity(0, MeshID(0), MaterialID(5) , 0,0,0)
wireFrame = 0
;ChangeMesh()
Repeat
Event = WindowEvent()
If ExamineMouse()
MouseX = -MouseDeltaX()/20
MouseY = -MouseDeltaY()/20
EndIf
If ExamineKeyboard()
If KeyboardReleased(#PB_Key_W)
If wireFrame
MaterialShadingMode(5, #PB_Material_Wireframe)
wireFrame ! 1
Else
MaterialShadingMode(5, #PB_Material_Solid)
wireFrame ! 1
EndIf
EndIf
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
EndIf
RotateEntity(0,1,0,0, #PB_Relative)
RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
MoveCamera(#Camera, KeyX, 0, KeyY)
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 CreateSpherePlus(mesh, radius.f, Segments, Rings, start.f, sphereParts.f)
CreateMesh(0, #PB_Mesh_TriangleList, #True)
CreateSphere(mesh,radius,Segments, Rings)
;TransformMesh(mesh,0,0,0, 1,1,1,0,0,0)
GetMeshData(mesh,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(mesh)-1)
GetMeshData(mesh,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(mesh, 0)-1)
ArrSize = ArraySize(MeshData())
;Debug ArrSize
For c=0 To 200
x.f = MeshData(c)\x
y.f = MeshData(c)\y
z.f = MeshData(c)\z
MeshVertexPosition(x,y,z)
MeshVertexTextureCoordinate(MeshData(c)\u, MeshData(c)\v)
Next
ArrSizeInd = ArraySize(MeshDataInd())
;Debug ArrSizeInd
ArrSizeInd = ArrSizeInd / sphereParts ; sphereParts is the number of sphere divisions we want
For i=start To ArrSizeInd Step 3
indx = i-1
MeshFace(MeshDataInd(indx)\Index, MeshDataInd(indx+1)\Index,MeshDataInd(indx+2)\Index)
Next
FinishMesh(#True)
GetMeshData(0,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate, 0, MeshVertexCount(0)-1)
GetMeshData(0,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(0, 0)-1)
;ArrSize = ArraySize(MeshData())
;Debug ArrSize
EndProcedure
Procedure ChangeMesh()
Protected.f minx, miny, minz, maxx, maxy, maxz
Protected.f corx, cory, corz
minx = 999999
miny = 999999
minz = 999999
maxx = -999999
maxy = -999999
maxz = -999999
For i=0 To ArraySize(MeshData())
If MeshData(i)\x > maxx
maxx = MeshData(i)\x
EndIf
If MeshData(i)\x < minx
minx = MeshData(i)\x
EndIf
If MeshData(i)\y > maxy
maxy = MeshData(i)\y
EndIf
If MeshData(i)\y < miny
miny = MeshData(i)\y
EndIf
If MeshData(i)\z > maxz
maxz = MeshData(i)\z
EndIf
If MeshData(i)\z < minz
minz = MeshData(i)\z
EndIf
Next
corx = (-maxx - minx) /2.0
cory = (-maxy - miny) /2.0
corz = (-maxz - minz) /2.0
MessageRequester("", "minx = " + StrF(minx,2) + Chr(10) +
"miny = " + StrF(miny,2) + Chr(10) +
"minz = " + StrF(minz,2) + Chr(10) +
"maxx = " + StrF(maxx,2) + Chr(10) +
"maxy = " + StrF(maxy,2) + Chr(10) +
"maxz = " + StrF(maxz,2) + Chr(10) +
"Correction x = " + StrF(corx,2) + Chr(10) +
"Correction y = " + StrF(cory,2) + Chr(10) +
"Correction z = " + StrF(corz,2), #PB_MessageRequester_Ok )
For i=0 To ArraySize(MeshData())
MeshData(i)\x + corx
MeshData(i)\y + cory
MeshData(i)\z + corz
Next
SetMeshData(0,0, MeshData(), #PB_Mesh_Vertex, 0, MeshVertexCount(0)-1)
EndProcedure