now it is easy to cover the above sphere hair with tubes (or lets say rods) , due to the success in plotting tubes in the coordinate geometry space exactly like we draw lines from x1,y1,z1 point to x2,y2,z2 point . the code are documented except the frenet magical procedures which i know nothing how it works. (may be only William Rowan Hamilton who can imagine exactly how quaternions, rotations, vectors , matrices, and so on, how they works exactly in practice and not only in the exam, i read that several programmers admits they don't understand this mathematical subject but they say who cares just use it, no need to know how the CPU works exactly to use your computer)
and you will see a weird triangular sphere with spikes.
notes: such 3D compound shapes use it in Geometry demonstration, and not physics, unless you manage to accept the collision are only to the big sphere
(...) , i hope the compound object will be real virtual physical object in the future, and we can discover this if when we use
should contains all the other objects added to it and not only the mother sphere. i think then we can load sphere.mesh and use it in the physics demos correctly like the other models we make with modeling software
see you the next year and happy new year for all .
Code: Select all
#CameraSpeed = 1
Enumeration
#Window
#Plane = 970
#Camera
#Light1
#Light2
#sphere
EndEnumeration
Structure vector3d
x.f
y.f
z.f
EndStructure
Structure vertex
x.f
y.f
z.f
EndStructure
Declare DrawTube (x.f, y.f,z.f, x2.f, y2.f, z2.f, RadiusS.f, RadiusE.f, TubeShape)
Declare TubeXYZ (tube, x.f, y.f, z.f, x2.f, y2.f, z2.f, RadiusS.f, RadiusE.f, TubeShape, Material)
;beginning of frenet sqaure approximation 5 procedures
Procedure vector_cross(*v1.vector3d, *v2.vector3d, *vout.vector3d)
*vout\x = (*v1\y * *v2\z) - (*v2\y * *v1\z)
*vout\y = (*v1\z * *v2\x) - (*v2\z * *v1\x)
*vout\z = (*v1\x * *v2\y) - (*v2\x * *v1\y)
EndProcedure
Procedure.f vector_magnitude(*v.vector3d)
mag.f
mag = Sqr(*v\x * *v\x + *v\y * *v\y + *v\z * *v\z)
If mag = 0:mag = 1:EndIf
ProcedureReturn mag
EndProcedure
Procedure vector_normalize (*v.vector3d)
mag.f
mag = vector_magnitude(*v)
*v\x = *v\x / mag
*v\y = *v\y / mag
*v\z = *v\z / mag
EndProcedure
Procedure vector_add (*v1.vector3d, *v2.vector3d, *vout.vector3d)
*vout\x = *v1\x + *v2\x
*vout\y = *v1\y + *v2\y
*vout\z = *v1\z + *v2\z
EndProcedure
Procedure vector_sub (*v1.vector3d, *v2.vector3d, *vout.vector3d)
*vout\x = *v1\x - *v2\x
*vout\y = *v1\y - *v2\y
*vout\z = *v1\z - *v2\z
EndProcedure
;end of frenet sqaure approximation 5 procedures
Global Dim MeshData.PB_MeshVertex(0)
Global xx.f, yy.f
Global ArrSize
Define.f KeyX, KeyY, MouseX, MouseY
If InitEngine3D()
Add3DArchive("\", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Models", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Scripts",#PB_3DArchive_FileSystem)
Parse3DScripts()
InitSprite()
InitKeyboard()
InitMouse()
ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)
If OpenWindow(#Window, 0, 0, DesktopW, DesktopH, "spikey , W toggle wireFrame...., . Space toggle rotation, ... mouse/arrow keys: rotate/move camera ")
If OpenWindowedScreen(WindowID(#Window), 0, 0, DesktopW, DesktopH, 0, 0, 0)
CreateMaterial(3, LoadTexture(3, "snow_1024.jpg"))
DisableMaterialLighting(3, #False)
SetMaterialColor(3, #PB_Material_AmbientColor, RGB(250, 255, 0))
SetMaterialColor(3, #PB_Material_SpecularColor, RGB(255, 255, 0))
CreatePlane(#Plane, 150, 150, 1, 1, 10, 10)
CreateEntity(#Plane,MeshID(#Plane),MaterialID(3),0.1,-10,0.2)
CreateMaterial(0, LoadTexture(0, "White.jpg"))
DisableMaterialLighting(0, #True)
CreateMaterial(1, LoadTexture(1, "Dirt.jpg"))
MaterialCullingMode(1, #PB_Material_NoCulling)
CreateMaterial(2, LoadTexture(2, "RustySteel.jpg"))
MaterialCullingMode(2, #PB_Material_NoCulling)
CreateMaterial(4, LoadTexture(4, "ground_diffuse.png"))
MaterialCullingMode(4, #PB_Material_NoCulling)
CreateMaterial(5, LoadTexture(5, "Geebee2.bmp"))
MaterialCullingMode(5, #PB_Material_NoCulling)
CreateSphere(#sphere,3,6,6)
CreateEntity(#sphere,MeshID(#sphere), MaterialID(1),0,0,0 )
NormalizeMesh(#sphere)
;getting info about the big sphere data
GetMeshData(#sphere,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal , 0, MeshVertexCount(#sphere)-1)
ArrSize = ArraySize(MeshData())
;Debug ArrSize
For c=0 To ArrSize ;42
CopyEntity(#sphere, c) ; making tiny spheres to position later into the big sphere vertices
ScaleEntity(c, 0.05, 0.05, 0.05)
SetEntityMaterial(c, MaterialID(5))
Next c
;spikes in the form of thin Lines, note that we use (#PB_Mesh_LineList)
CreateMesh(0, #PB_Mesh_LineList , #PB_Mesh_Static)
For c=0 To ArrSize ;42
;getting the vertices positions data which makes the big sphere
x.f = MeshData(c)\x
y.f = MeshData(c)\y
z.f = MeshData(c)\z
x2.f = 3*MeshData(c)\x ; getting the virtual points so we can make a line from the sphere center to ...
y2.f = 3*MeshData(c)\y ; the sphere vertex and extending the line to this point outside the sphere
z2.f = 3*MeshData(c)\z ; we will only draw the line from a sphere vertex to this point, ignoring the line to the center
MeshVertexColor(RGB(255,0,0))
MeshVertexPosition(x, y, z)
MeshVertexPosition(x2, y2, z2)
MoveEntity(c, x,y,z, #PB_Absolute) ; move the tiny red spheres we mada before to every sphere vertex position
AttachEntityObject(#sphere, "", EntityID(c)) ; we attach the tiny red spheres to the big sphere
Next c
FinishMesh(#True)
SetMeshMaterial(0, MaterialID(0))
CreateEntity(0,MeshID(0),MaterialID(0))
AttachEntityObject(#sphere,"",EntityID(0))
tube = 200 ; we begins the tubes mesh numbering from 200 because the numbering from 0 to ... are reserved for other entities made before
; making the tubes at the same position of the Lines using the function TubeXYZ(...)
For c=0 To ArrSize
; getting data of sphere vertices positions to use this in drawing the tubes with TubeXYZ(...) function
x.f = MeshData(c)\x
y.f = MeshData(c)\y
z.f = MeshData(c)\z
x2.f = 3*MeshData(c)\x
y2.f = 3*MeshData(c)\y
z2.f = 3*MeshData(c)\z
CreateMesh(tube , #PB_Mesh_TriangleList, #PB_Mesh_Static )
;TubeXYZ (tube, x.f, y.f, z.f, x2.f, y2.f, z2.f, RadiusS.f, RadiusE.f, TubeShape, Material)
TubeXYZ (tube, x.f, y.f,z.f, x2.f, y2.f,z2.f, 0.3, 0.3, 8, 4) ; call the tube making function
AttachEntityObject(#sphere,"",EntityID(tube))
tube + 1 ; next tube mesh numbering
Next c
;;oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
CreateCamera(#Camera, 0, 0, 100, 100)
MoveCamera(#Camera, 0, 5, 28, #PB_Absolute)
CameraLookAt(#Camera,0,0,0)
CameraBackColor(#Camera, RGB(0,100,0))
CreateLight(#Light1, RGB(0, 0, 0), -20, 40, 20)
SetLightColor(#Light1, #PB_Light_DiffuseColor, RGB(255,255,255))
CreateLight(#Light2, RGB(0, 0, 0), 20, 40, 20)
SetLightColor(#Light2, #PB_Light_DiffuseColor, RGB(0,0,255))
AmbientColor(RGB(255, 255, 255))
EndIf
EndIf
;HideEntity(#sphere,1)
wireFrame = 1: rot=1
Repeat
Event = WindowEvent()
If ExamineMouse()
MouseX = -MouseDeltaX()/20
MouseY = -MouseDeltaY()/20
EndIf
If ExamineKeyboard()
If KeyboardPushed(#PB_Key_Left)
KeyX = -0.2
ElseIf KeyboardPushed(#PB_Key_Right)
KeyX = 0.2
Else
KeyX = 0
EndIf
If KeyboardPushed(#PB_Key_Up)
KeyY = -0.2
ElseIf KeyboardPushed(#PB_Key_Down)
KeyY = 0.2
Else
KeyY = 0
EndIf
If KeyboardReleased(#PB_Key_W)
If wireFrame
MaterialShadingMode(1, #PB_Material_Wireframe)
MaterialShadingMode(4, #PB_Material_Wireframe)
wireFrame ! 1
Else
MaterialShadingMode(1, #PB_Material_Solid)
MaterialShadingMode(4, #PB_Material_Solid)
wireFrame ! 1
EndIf
EndIf
EndIf
RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
MoveCamera(#Camera, KeyX, 0, KeyY)
RotateEntity(#sphere, 0,rot,0,#PB_Relative)
If KeyboardReleased(#PB_Key_Space)
rot ! 1
;SaveMesh(#sphere, "sphere.mesh"); it saves only the mother sphere discarding what we have added to it previously
EndIf
RenderWorld()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
Else
MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
End
Procedure DrawTube (x.f, y.f,z.f, x2.f, y2.f,z2.f, RadiusS.f, RadiusE.f, TubeShape)
#Rings = 2
Dim vertx.vertex(2)
lineVec.vector3d
u.f: r.f
txu.f : txv.f
x1.f = x
y1.f = y
z1.f = z
bands = TubeShape ; 2 flat tube, 3 triangular tube, 4 rectangular, 8 almost cylindrical tube
;vector of the line between start vertex and the end vertex
lineVec\x = x2 - x1
lineVec\y = y2 - y1
lineVec\z = z2 - z1
tt.f = 0
For i=0 To 2
x = x1 + lineVec\x * tt
y = y1 + lineVec\y * tt
z = z1 + lineVec\z * tt
tt + 1
vertx(i)\x = x
vertx(i)\y = y
vertx(i)\z = z
Next
current_point.vector3d
next_point.vector3d
T.vector3d
B.vector3d
N.vector3d
p.f
For i = 0 To 1
If i=0 ; to manage the radius of tube start and tube end
Radius.f = RadiusS
Else
Radius.f=RadiusE
EndIf
;center point
current_point\x = vertx(i)\x
current_point\y = vertx(i)\y
current_point\z = vertx(i)\z
;next point For Frenet square
next_point\x = vertx(i+1)\x
next_point\y = vertx(i+1)\y
next_point\z = vertx(i+1)\z
;T = P' - P
vector_sub(next_point, current_point, T)
;N = P' + P
vector_add(next_point, current_point, N)
;B = T x N
vector_cross(T, N, B)
;N = B x T
vector_cross(B, T, N)
;Normalize vectors Or Else it won't work
vector_normalize(B)
vector_normalize(N)
For j = 0 To bands
new_point_x.f
new_point_y.f
;rotate around the current point using normal rotation makes bands
new_point_x = Sin(j * (#PI*2) / bands) * Radius
new_point_y = Cos(j * (#PI*2) / bands) * Radius
;this is the coordinates of our point along the curve
x = N\x * new_point_x + B\x * new_point_y + current_point\x
y = N\y * new_point_x + B\y * new_point_y + current_point\y
z = N\z * new_point_x + B\z * new_point_y + current_point\z
MeshVertexPosition(x, y, z)
MeshVertexTextureCoordinate(txu, txv)
MeshVertexNormal(x, y, z)
txv = txv + 1/#Rings
Next
txv = 0
txu = txu + 1/bands
Next
v.l
For j = 0 To bands -1
MeshFace(v,v+1,v + bands+1)
MeshFace(v + bands+1,v + bands+2,v+1 )
v + 1
Next
EndProcedure
Procedure TubeXYZ (tube, x.f, y.f,z.f, x2.f, y2.f,z2.f, RadiusS.f, RadiusE.f, TubeShape, Material)
x.f+0.00001 : y.f+0.00001 : z.f+0.00001 ; +0.00001 necessary if x,y,z or x2,y2,z2 are zero !!!
x2.f+0.00001 : y2.f+0.00001 : z2.f+0.00001
CreateMesh(tube , #PB_Mesh_TriangleList, #PB_Mesh_Dynamic )
DrawTube (x, y, z, x2, y2, z2, RadiusS, RadiusE, TubeShape)
FinishMesh(tube)
NormalizeMesh(tube)
BuildMeshTangents(tube)
CreateEntity(tube,MeshID(tube),MaterialID(Material))
EndProcedure