projectile physics (with ellipsoid / with linepick)
Attention! 👉Starting November 2024, BlitzCoder.org will now be BlitzBasic.org.
Tweet blitz3d collision-detection physics code-archives miscellaneous
an example with linepicks and pickables :
;projectile physics (with linepick and pickables) 20181004
Graphics3D(1000,624,32,2)
HidePointer()
SeedRnd(MilliSecs())
Global MXDiff%
Global MYDiff%
;camera
Global Camera = CreateCamera()
CameraRange(Camera,1,1000)
CameraClsColor(Camera,001,001,001)
;origine
Origine = CreateCube()
ScaleMesh(Origine,0.03/2,0.03/2,0/03.2)
EntityColor(Origine,255,000,255)
EntityFX(Origine,1)
Global GhostRoot
Global GhostRootYaw#
Global GhostEyes
Global GhostEyesPitch#
AddGhost()
;room
Global Room = CreateCube() ;CreateCube() CreateCylinder(4) CreateCylinder(8) CreateSphere(2) CreateSphere(4) CreateSphere(8)
FlipMesh(Room)
ScaleMesh(Room,100.0/2,50.0/2,100.0/2)
PositionMesh(Room,50,25,50)
For GX% = 0 To 90 Step 10
For GZ% = 0 To 90 Step 10
TPart = CreateCube()
ScaleMesh(TPart,10.0/2,50.0/2,10.0/2)
PositionMesh(TPart,10.0/2,-50.0/2,10.0/2)
PositionMesh(TPart,GX,Rand(1,12),GZ)
AddMesh(TPart,Room) : FreeEntity(TPart)
Next
Next
PositionEntity(Room,0,0,0,True)
EntityColor(Room,125,125,125)
;projectiles
Global ProjectilesCount%
Type Projectile
Field State%
Field Shape
Field Radius#
Field Gravity#
Field VX#, VY#, VZ#
Field VLength#
End Type
Const CIdle% = 1
Const CTranslate% = 2
Global Pivot = CreatePivot()
EntityPickMode(Room,2)
DLight = CreateLight(1)
LightColor(DLight,255,255,255)
PositionEntity(DLight,50,1000,-1000)
RotateEntity(DLight,45,0,0)
AmbientLight(064,064,064)
PositionEntity(GhostRoot,50,25+1.65,90,True)
GhostRootYaw = 180
Global MainLoopTimer = CreateTimer(30)
;mainloop
Main()
End()
Function Main()
Repeat
MainLoopMilliStart% = MilliSecs()
MXDiff = MouseXSpeed()
MYDiff = MouseYSpeed()
UpdateGhost()
;update projectiles
UpdateProjectiles()
PositionRotateEntityLikeOtherEntity(Camera,GhostEyes)
;wireframe mode off/on
WireFrame(False)
If( KeyDown(2)=True )
WireFrame(True)
EndIf
;render
SetBuffer(BackBuffer())
RenderWorld()
Color(255,255,255)
Text(0,0,"ProjectilesCount = "+ProjectilesCount)
PhysicsCount% = 0
For pr.Projectile = Each Projectile
If( pr\State = CTranslate )
PhysicsCount = PhysicsCount + 1
EndIf
Next
Text(0,15,"Physics active on "+PhysicsCount+" projectiles")
Text(500,0,"Tris = "+TrisRendered())
Text(500,16,"FPS = "+FPS)
;display the result on the screen
;Flip(1)
WaitTimer(MainLoopTimer)
VWait():Flip(False)
MainLoopMilliTime = MilliSecs() - MainLoopMilliStart
If( MainLoopMilliTime < 1 )
MainLoopMilliTime = 1
EndIf
FPS% = 1000.0/MainLoopMilliTime
Until( KeyDown(1)=1 )
End Function
Function PositionEntityLikeOtherEntity(Entity,OEntity)
PositionEntity(Entity,EntityX(OEntity,True),EntityY(OEntity,True),EntityZ(OEntity,True),True)
End Function
Function RotateEntityLikeOtherEntity(Entity,OEntity)
RotateEntity(Entity,EntityPitch(OEntity,True),EntityYaw(OEntity,True),EntityRoll(OEntity,True),True)
End Function
Function PositionRotateEntityLikeOtherEntity(Entity,OEntity)
PositionEntity(Entity,EntityX(OEntity,True),EntityY(OEntity,True),EntityZ(OEntity,True),True)
RotateEntity(Entity,EntityPitch(OEntity,True),EntityYaw(OEntity,True),EntityRoll(OEntity,True),True)
End Function
Function Distance2D#(PAX#,PAZ#,PBX#,PBZ#)
Distance2D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) )
Return Distance2D
End Function
Function Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#)
Distance3D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBY - PAY ) * ( PBY - PAY ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) )
Return Distance3D
End Function
Function Angle3D#(V1X#,V1Y#,V1Z#,V2X#,V2Y#,V2Z#)
D# = (V1X*V2X) + (V1Y*V2Y) + (V1Z*V2Z)
M# = Sqr( V1X*V1X + V1Y*V1Y + V1Z*V1Z ) * Sqr( V2X*V2X + V2Y*V2Y + V2Z*V2Z )
A# = ACos(D#/M#)
Return A#
End Function
Function AddGhost()
GhostRoot = CreatePivot()
GhostEyes = CreatePivot()
PositionRotateEntityLikeOtherEntity(GhostEyes,GhostRoot)
EntityParent(GhostEyes,GhostRoot,True)
End Function
Function UpdateGhost()
MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2)
GhostEyesPitch = GhostEyesPitch + Float(MYDiff)/10
If( GhostEyesPitch < -89 )
GhostEyesPitch = -89
Else If( GhostEyesPitch > 89 )
GhostEyesPitch = 89
EndIf
RotateEntity(GhostEyes,GhostEyesPitch,0,0,False)
GhostRootYaw = GhostRootYaw - Float(MXDiff)/10
RotateEntity(GhostRoot,0,GhostRootYaw,0,False)
If( KeyDown(42) = 0 And KeyDown(29) = 0 )
Speed# = 0.1
Else If( KeyDown(42) = 1 And KeyDown(29) = 0 )
Speed# = 1
Else If( KeyDown(42) = 0 And KeyDown(29) = 1 )
Speed# = 0.01
EndIf
If( KeyDown(17)=1 )
MoveEntity(GhostRoot,0,0,Speed)
Else If( KeyDown(31)=1 )
MoveEntity(GhostRoot,0,0,-Speed)
EndIf
If( KeyDown(30)=1 )
MoveEntity(GhostRoot,-Speed,0,0)
Else If( KeyDown(32)=1 )
MoveEntity(GhostRoot,Speed,0,0)
EndIf
If( KeyDown(16)=1 )
MoveEntity(GhostRoot,0,-Speed,0)
Else If( KeyDown(18)=1 )
MoveEntity(GhostRoot,0,Speed,0)
EndIf
If( MouseHit(1)=1 )
DebugLog("")
;create a new projectile
ProjectilesCount = ProjectilesCount + 1
pr.Projectile = New Projectile
pr\Radius# = Rnd(0.05,0.5)/2*10
pr\Shape = CreateSphere(16)
ScaleMesh(pr\Shape,pr\Radius,pr\Radius,pr\Radius)
ThrowForce# = 46.940*2.0/30.0
pr\Gravity = 0
;calculate translation vector (whole vector)
TFormVector(0,0,+ThrowForce,GhostEyes,0)
pr\VX = TFormedX() : pr\VY = TFormedY() : pr\VZ = TFormedZ()
;calculate translation length (whole length)
pr\VLength = Sqr( pr\VX*pr\VX + pr\VY*pr\VY + pr\VZ*pr\VZ )
PositionEntity(pr\Shape,EntityX(GhostEyes,True),EntityY(GhostEyes,True),EntityZ(GhostEyes,True),True)
;state = translate
pr\State = CTranslate
EntityColor(pr\Shape,000,000,255)
EntityRadius(pr\Shape,pr\Radius-0.01)
EntityPickMode(pr\Shape,1)
EndIf
End Function
Function UpdateProjectiles()
For pr.Projectile = Each Projectile
If( pr\State = CIdle )
;
Else If( pr\State = CTranslate )
;calculate new Whole vector
;increase gravity force
pr\Gravity = 9.81/30.0/2
;add gravity force to Whole vector
pr\VX = pr\VX : pr\VY = pr\VY-pr\Gravity : pr\VZ = pr\VZ
;(add air friction to Whole vector)
;pr\VX = pr\VX*0.999 : pr\VY = pr\VY*0.999 : pr\VZ = pr\VZ*0.999
;calculate new Whole length
pr\VLength = Sqr( pr\VX*pr\VX + pr\VY*pr\VY + pr\VZ*pr\VZ )
;initialize Remaining vector
RVX# = pr\VX : RVY# = pr\VY : RVZ# = pr\VZ
;initialize Remaining length
RLength# = pr\VLength
Repeat
;store Before position
befX# = EntityX(pr\Shape,True) : befY# = EntityY(pr\Shape,True) : befZ# = EntityZ(pr\Shape,True)
;check if there is an obstacle in this direction at the Remaining length (+radius)
picEnt% = LinePick(befX,befY,befZ,RVX,RVY,RVZ,pr\Radius)
;if yes
If( picEnt <> 0 )
;store pic position
picX# = PickedX() : picY# = PickedY() : picZ# = PickedZ()
;store pic normal
picNX# = PickedNX() : picNY# = PickedNY() : picNZ# = PickedNZ()
;calculate When position
PositionEntity(Pivot,picX,picY,picZ,True) : AlignToVector(Pivot,picNX,picNY,picNZ,3,1.0) : MoveEntity(Pivot,0,0,pr\Radius)
wheX# = EntityX(Pivot,True) : wheY# = EntityY(Pivot,True) : wheZ# = EntityZ(Pivot,True)
;calculate Before length (Before position -> When position)
BLength# = Distance3D(befX,befY,befZ,wheX,wheY,wheZ)
;calculate Before coef (BLength/RLength)
BCoef# = BLength/RLength
;calculate Before vector
BVX# = RVX*BCoef : BVY# = RVY*BCoef : BVZ# = RVZ*BCoef
;translate entity with Before vector
TranslateEntity(pr\Shape,BVX,BVY,BVZ,True)
;calculate New vector (reflection vector)
DP# = RVX*picNX + RVY*picNY + RVZ*picNZ
NFX# = -2.0*picNX*DP : NFY# = -2.0*picNY*DP : NFZ# = -2.0*picNZ*DP
NVX# = RVX+NFX*1.1 : NVY# = RVY+NFY*1.1 : NVZ# = RVZ+NFZ*1.1
;calculate angle between Remaining vector and New vector
A# = Angle3D(RVX,RVY,RVZ,NVX,NVY,NVZ)
;attenuate New vector depending on angle
AttCoef# = (1.0-(A/180.0))
;DebugLog(A+" "+AttCoef)
NVX = NVX*AttCoef : NVY = NVY*AttCoef : NVZ = NVZ*AttCoef
;attenuate New vector depending on arbitrary coef
;NVX = NVX*0.9 : NVY = NVY*0.9 : NVZ = NVZ*0.9
;calculate New length
NLength# = Sqr( NVX*NVX + NVY*NVY + NVZ*NVZ )
;initialize Remaining vector
RVX = NVX : RVY = NVY : RVZ = NVZ
;initialize Remaining length
RLength = NLength
;
pr\VX = NVX : pr\VY = NVY : pr\VZ = NVZ
pr\VLength = NLength
;check if Remaining length is inferior or equal to gravityforce
;if yes
If( RLength < pr\Gravity )
EntityColor(pr\Shape,125,255,255)
;check if the ground below is near or far
picEnt% = LinePick(wheX,wheY,wheZ,0,-100,0,pr\Radius)
If( picEnt <> 0 )
picX# = PickedX() : picY# = PickedY() : picZ# = PickedZ()
;if near
If( wheY-picY < pr\Radius+pr\Gravity )
;0 Remaining vector
RVX = 0 : RVY = 0 : RVZ = 0
;0 Remaining length
RLength = 0
;0 gravity force
pr\Gravity = 0
;state = idle
pr\State = CIdle
EntityColor(pr\Shape,125,125,255)
EndIf
;if far
;
EndIf
EndIf
Else If( picEnt = 0 )
;translate entity with Remaining vector
TranslateEntity(pr\Shape,RVX,RVY,RVZ,True)
;0 Remaining vector
RVX = 0 : RVY = 0 : RVZ = 0
;0 Remaining length
RLength = 0
EndIf
Until( Rlength = 0 )
EndIf
If( pr <> Null )
If( EntityY(pr\Shape,True) < -100 )
ProjectilesCount = ProjectilesCount - 1
FreeEntity(pr\Shape) : Delete(pr)
EndIf
EndIf
Next
End Function
an example with ellipsoids and collidables :
;projectile physics (with ellipsoid and collidables) 20181004
Graphics3D(1000,624,32,2)
HidePointer()
SeedRnd(MilliSecs())
Global MXDiff%
Global MYDiff%
;camera
Global Camera = CreateCamera()
CameraRange(Camera,1,1000)
CameraClsColor(Camera,001,001,001)
;origine
Origine = CreateCube()
ScaleMesh(Origine,0.03/2,0.03/2,0/03.2)
EntityColor(Origine,255,000,255)
EntityFX(Origine,1)
Global GhostRoot
Global GhostRootYaw#
Global GhostEyes
Global GhostEyesPitch#
AddGhost()
;room
Global Room = CreateCube() ;CreateCube() CreateCylinder(4) CreateCylinder(8) CreateSphere(2) CreateSphere(4) CreateSphere(8)
FlipMesh(Room)
ScaleMesh(Room,100.0/2,50.0/2,100.0/2)
PositionMesh(Room,50,25,50)
For GX% = 0 To 90 Step 10
For GZ% = 0 To 90 Step 10
TPart = CreateCube()
ScaleMesh(TPart,10.0/2,50.0/2,10.0/2)
PositionMesh(TPart,10.0/2,-50.0/2,10.0/2)
PositionMesh(TPart,GX,Rand(1,12),GZ)
AddMesh(TPart,Room) : FreeEntity(TPart)
Next
Next
PositionEntity(Room,0,0,0,True)
EntityColor(Room,125,125,125)
;projectiles
Global ProjectilesCount%
Type Projectile
Field State%
Field Shape
Field Radius#
Field Gravity#
Field VX#, VY#, VZ#
Field VLength#
Field befX#, befY#, befZ#
End Type
Const CIdle% = 1
Const CTranslate% = 2
Global Pivot = CreatePivot()
Const GRoom% = 1
Const GProjectile% = 2
EntityType(Room,GRoom)
Collisions(GProjectile,GRoom,2,1)
Collisions(GProjectile,GProjectile,1,1)
EntityPickMode(Room,2)
DLight = CreateLight(1)
LightColor(DLight,255,255,255)
PositionEntity(DLight,50,1000,-1000)
RotateEntity(DLight,45,0,0)
AmbientLight(064,064,064)
PositionEntity(GhostRoot,50,25+1.65,90,True)
GhostRootYaw = 180
Global MainLoopTimer = CreateTimer(30)
;mainloop
Main()
End()
Function Main()
Repeat
MainLoopMilliStart% = MilliSecs()
MXDiff = MouseXSpeed()
MYDiff = MouseYSpeed()
UpdateGhost()
;update projectiles
UpdateProjectilesBefore()
UpdateWorld()
UpdateProjectilesAfter()
PositionRotateEntityLikeOtherEntity(Camera,GhostEyes)
;wireframe mode off/on
WireFrame(False)
If( KeyDown(2)=True )
WireFrame(True)
EndIf
;render
SetBuffer(BackBuffer())
RenderWorld()
Color(255,255,255)
Text(0,0,"ProjectilesCount = "+ProjectilesCount)
PhysicsCount% = 0
For pr.Projectile = Each Projectile
If( pr\State = CTranslate )
PhysicsCount = PhysicsCount + 1
EndIf
Next
Text(0,15,"Physics active on "+PhysicsCount+" projectiles")
Text(500,0,"Tris = "+TrisRendered())
Text(500,16,"FPS = "+FPS)
;display the result on the screen
;Flip(1)
WaitTimer(MainLoopTimer)
VWait():Flip(False)
MainLoopMilliTime = MilliSecs() - MainLoopMilliStart
If( MainLoopMilliTime < 1 )
MainLoopMilliTime = 1
EndIf
FPS% = 1000.0/MainLoopMilliTime
Until( KeyDown(1)=1 )
End Function
Function PositionEntityLikeOtherEntity(Entity,OEntity)
PositionEntity(Entity,EntityX(OEntity,True),EntityY(OEntity,True),EntityZ(OEntity,True),True)
End Function
Function RotateEntityLikeOtherEntity(Entity,OEntity)
RotateEntity(Entity,EntityPitch(OEntity,True),EntityYaw(OEntity,True),EntityRoll(OEntity,True),True)
End Function
Function PositionRotateEntityLikeOtherEntity(Entity,OEntity)
PositionEntity(Entity,EntityX(OEntity,True),EntityY(OEntity,True),EntityZ(OEntity,True),True)
RotateEntity(Entity,EntityPitch(OEntity,True),EntityYaw(OEntity,True),EntityRoll(OEntity,True),True)
End Function
Function Distance2D#(PAX#,PAZ#,PBX#,PBZ#)
Distance2D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) )
Return Distance2D
End Function
Function Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#)
Distance3D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBY - PAY ) * ( PBY - PAY ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) )
Return Distance3D
End Function
Function Angle3D#(V1X#,V1Y#,V1Z#,V2X#,V2Y#,V2Z#)
D# = (V1X*V2X) + (V1Y*V2Y) + (V1Z*V2Z)
M# = Sqr( V1X*V1X + V1Y*V1Y + V1Z*V1Z ) * Sqr( V2X*V2X + V2Y*V2Y + V2Z*V2Z )
A# = ACos(D#/M#)
Return A#
End Function
Function AddGhost()
GhostRoot = CreatePivot()
GhostEyes = CreatePivot()
PositionRotateEntityLikeOtherEntity(GhostEyes,GhostRoot)
EntityParent(GhostEyes,GhostRoot,True)
End Function
Function UpdateGhost()
MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2)
GhostEyesPitch = GhostEyesPitch + Float(MYDiff)/10
If( GhostEyesPitch < -89 )
GhostEyesPitch = -89
Else If( GhostEyesPitch > 89 )
GhostEyesPitch = 89
EndIf
RotateEntity(GhostEyes,GhostEyesPitch,0,0,False)
GhostRootYaw = GhostRootYaw - Float(MXDiff)/10
RotateEntity(GhostRoot,0,GhostRootYaw,0,False)
If( KeyDown(42) = 0 And KeyDown(29) = 0 )
Speed# = 0.1
Else If( KeyDown(42) = 1 And KeyDown(29) = 0 )
Speed# = 1
Else If( KeyDown(42) = 0 And KeyDown(29) = 1 )
Speed# = 0.01
EndIf
If( KeyDown(17)=1 )
MoveEntity(GhostRoot,0,0,Speed)
Else If( KeyDown(31)=1 )
MoveEntity(GhostRoot,0,0,-Speed)
EndIf
If( KeyDown(30)=1 )
MoveEntity(GhostRoot,-Speed,0,0)
Else If( KeyDown(32)=1 )
MoveEntity(GhostRoot,Speed,0,0)
EndIf
If( KeyDown(16)=1 )
MoveEntity(GhostRoot,0,-Speed,0)
Else If( KeyDown(18)=1 )
MoveEntity(GhostRoot,0,Speed,0)
EndIf
If( MouseHit(1)=1 )
DebugLog("")
;create a new projectile
ProjectilesCount = ProjectilesCount + 1
pr.Projectile = New Projectile
pr\Radius# = Rnd(0.05,0.5)/2*10
pr\Shape = CreateSphere(16)
ScaleMesh(pr\Shape,pr\Radius,pr\Radius,pr\Radius)
ThrowForce# = 46.940*2.0/30.0
pr\Gravity = 0
;calculate translation vector (whole vector)
TFormVector(0,0,+ThrowForce,GhostEyes,0)
pr\VX = TFormedX() : pr\VY = TFormedY() : pr\VZ = TFormedZ()
;calculate translation length (whole length)
pr\VLength = Sqr( pr\VX*pr\VX + pr\VY*pr\VY + pr\VZ*pr\VZ )
PositionEntity(pr\Shape,EntityX(GhostEyes,True),EntityY(GhostEyes,True),EntityZ(GhostEyes,True),True)
;state = translate
pr\State = CTranslate
EntityColor(pr\Shape,000,000,255)
EntityRadius(pr\Shape,pr\Radius-0.01)
EntityType(pr\Shape,GProjectile)
EntityPickMode(pr\Shape,2)
EndIf
End Function
Function UpdateProjectilesBefore()
For pr.Projectile = Each Projectile
If( pr\State = CIdle )
;
Else If( pr\State = CTranslate )
;calculate new Whole vector
;increase gravity force
pr\Gravity = 9.81/30.0/2
;add gravity force to Whole vector
pr\VX = pr\VX : pr\VY = pr\VY-pr\Gravity : pr\VZ = pr\VZ
;(add air friction to Whole vector)
;pr\VX = pr\VX*0.999 : pr\VY = pr\VY*0.999 : pr\VZ = pr\VZ*0.999
;calculate new Whole length
pr\VLength = Sqr( pr\VX*pr\VX + pr\VY*pr\VY + pr\VZ*pr\VZ )
;store Before position
pr\befX# = EntityX(pr\Shape,True) : pr\befY# = EntityY(pr\Shape,True) : pr\befZ# = EntityZ(pr\Shape,True)
;translate entity with whole vector
TranslateEntity(pr\Shape,pr\VX,pr\VY,pr\VZ,True)
EndIf
If( pr <> Null )
If( EntityY(pr\Shape,True) < -100 )
ProjectilesCount = ProjectilesCount - 1
FreeEntity(pr\Shape) : Delete(pr)
EndIf
EndIf
Next
End Function
Function UpdateProjectilesAfter()
For pr.Projectile = Each Projectile
If( pr\State = CIdle )
;
Else If( pr\State = CTranslate )
;check if a collision happened when translating entity along whole vector
nc% = CountCollisions(pr\Shape)
;if yes
If( nc > 0 )
;collision detected, get infos about the collision
colEnt% = CollisionEntity(pr\Shape,1)
;store collision position
colX# = CollisionX(pr\Shape,1) : colY# = CollisionY(pr\Shape,1) : colZ# = CollisionZ(pr\Shape,1)
;store collision normal
colNX# = CollisionNX(pr\Shape,1) : colNY# = CollisionNY(pr\Shape,1) : colNZ# = CollisionNZ(pr\Shape,1)
;calculate When position
wheX# = EntityX(pr\Shape,True) : wheY# = EntityY(pr\Shape,True) : wheZ# = EntityZ(pr\Shape,True)
;calculate New vector (reflection vector)
DP# = pr\VX*colNX + pr\VY*colNY + pr\VZ*colNZ
NFX# = -2.0*colNX*DP : NFY# = -2.0*colNY*DP : NFZ# = -2.0*colNZ*DP
NVX# = pr\VX+NFX*1.1 : NVY# = pr\VY+NFY*1.1 : NVZ# = pr\VZ+NFZ*1.1
;calculate angle between Remaining vector and New vector
A# = Angle3D(pr\VX,pr\VY,pr\VZ,NVX,NVY,NVZ)
;attenuate New vector depending on angle
AttCoef# = (1.0-(A/180.0))
;DebugLog(A+" "+AttCoef)
NVX = NVX*AttCoef : NVY = NVY*AttCoef : NVZ = NVZ*AttCoef
;calculate New length
NLength# = Sqr( NVX*NVX + NVY*NVY + NVZ*NVZ )
pr\VX = NVX : pr\VY = NVY : pr\VZ = NVZ
pr\VLength = NLength
;check if Remaining length is inferior or equal to gravityforce
;if yes
If( pr\VLength < pr\Gravity )
EntityColor(pr\Shape,125,255,255)
;check if the ground below is near or far
picEnt% = LinePick(wheX,wheY,wheZ,0,-100,0,pr\Radius-0.01)
If( picEnt <> 0 )
picX# = PickedX() : picY# = PickedY() : picZ# = PickedZ()
;if near
If( wheY-picY < pr\Radius+pr\Gravity )
;0 Remaining vector
pr\VX = 0 : pr\VY = 0 : pr\VZ = 0
;0 Remaining length
pr\VLength = 0
;0 gravity force
pr\Gravity = 0
;state = idle
pr\State = CIdle
EntityColor(pr\Shape,125,125,255)
EndIf
;if far
;
EndIf
EndIf
Else If( collEnt = 0 )
;
EndIf
EndIf
Next
End Function
Reply To Topic (minimum 10 characters)
Please log in to reply