removed buggy code !
removed buggy code!
;projectile physics (with linepick and pickables) 20181004Graphics3D(1000,624,32,2)HidePointer()SeedRnd(MilliSecs())Global MXDiff%Global MYDiff%;cameraGlobal Camera = CreateCamera()CameraRange(Camera,1,1000)CameraClsColor(Camera,001,001,001);origineOrigine = CreateCube()ScaleMesh(Origine,0.03/2,0.03/2,0/03.2)EntityColor(Origine,255,000,255)EntityFX(Origine,1)Global GhostRootGlobal GhostRootYaw#Global GhostEyesGlobal GhostEyesPitch#AddGhost();roomGlobal 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) NextNextPositionEntity(Room,0,0,0,True)EntityColor(Room,125,125,125);projectilesGlobal ProjectilesCount%Type Projectile Field State% Field Shape Field Radius# Field Gravity# Field VX#, VY#, VZ# Field VLength#End TypeConst CIdle% = 1Const CTranslate% = 2Global 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 = 180Global MainLoopTimer = CreateTimer(30);mainloopMain()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 FunctionFunction PositionEntityLikeOtherEntity(Entity,OEntity) PositionEntity(Entity,EntityX(OEntity,True),EntityY(OEntity,True),EntityZ(OEntity,True),True)End FunctionFunction RotateEntityLikeOtherEntity(Entity,OEntity) RotateEntity(Entity,EntityPitch(OEntity,True),EntityYaw(OEntity,True),EntityRoll(OEntity,True),True)End FunctionFunction 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 FunctionFunction Distance2D#(PAX#,PAZ#,PBX#,PBZ#) Distance2D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) ) Return Distance2DEnd FunctionFunction Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#) Distance3D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBY - PAY ) * ( PBY - PAY ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) ) Return Distance3DEnd FunctionFunction 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 FunctionFunction AddGhost() GhostRoot = CreatePivot() GhostEyes = CreatePivot() PositionRotateEntityLikeOtherEntity(GhostEyes,GhostRoot) EntityParent(GhostEyes,GhostRoot,True)End FunctionFunction 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 FunctionFunction 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 NextEnd Function
;projectile physics (with ellipsoid and collidables) 20181004Graphics3D(1000,624,32,2)HidePointer()SeedRnd(MilliSecs())Global MXDiff%Global MYDiff%;cameraGlobal Camera = CreateCamera()CameraRange(Camera,1,1000)CameraClsColor(Camera,001,001,001);origineOrigine = CreateCube()ScaleMesh(Origine,0.03/2,0.03/2,0/03.2)EntityColor(Origine,255,000,255)EntityFX(Origine,1)Global GhostRootGlobal GhostRootYaw#Global GhostEyesGlobal GhostEyesPitch#AddGhost();roomGlobal 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) NextNextPositionEntity(Room,0,0,0,True)EntityColor(Room,125,125,125);projectilesGlobal ProjectilesCount%Type Projectile Field State% Field Shape Field Radius# Field Gravity# Field VX#, VY#, VZ# Field VLength# Field befX#, befY#, befZ#End TypeConst CIdle% = 1Const CTranslate% = 2Global Pivot = CreatePivot()Const GRoom% = 1Const GProjectile% = 2EntityType(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 = 180Global MainLoopTimer = CreateTimer(30);mainloopMain()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 FunctionFunction PositionEntityLikeOtherEntity(Entity,OEntity) PositionEntity(Entity,EntityX(OEntity,True),EntityY(OEntity,True),EntityZ(OEntity,True),True)End FunctionFunction RotateEntityLikeOtherEntity(Entity,OEntity) RotateEntity(Entity,EntityPitch(OEntity,True),EntityYaw(OEntity,True),EntityRoll(OEntity,True),True)End FunctionFunction 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 FunctionFunction Distance2D#(PAX#,PAZ#,PBX#,PBZ#) Distance2D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) ) Return Distance2DEnd FunctionFunction Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#) Distance3D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBY - PAY ) * ( PBY - PAY ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) ) Return Distance3DEnd FunctionFunction 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 FunctionFunction AddGhost() GhostRoot = CreatePivot() GhostEyes = CreatePivot() PositionRotateEntityLikeOtherEntity(GhostEyes,GhostRoot) EntityParent(GhostEyes,GhostRoot,True)End FunctionFunction 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 FunctionFunction 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 NextEnd FunctionFunction 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 NextEnd Function