Code archives/3D Graphics - Maths/capsule collider using one pivot + several ellipsoids + collidables
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
for characters, for vehicles, using Blitz3d collision system | |||||
Graphics3D(800,600,32,2) SeedRnd(MilliSecs()) Origine = CreateCube() ScaleMesh(Origine,0.01/2,0.01/2,0.01/2) EntityColor(Origine,255,000,000) ;Input Const CUp% = 1 Const CToDown% = 2 Const CDown% = 3 Const CToUp% = 4 Global MPX% = 0 Global MPY% = 0 Global MXDiff# = 0 Global MYDiff# = 0 Global MZOld% = 0 Global MZCur% = 0 Global MWheel% = 0 Global Camera = CreateCamera() CameraRange(Camera,0.1,100) Global TerrainRenderer Global TerrainCollidable BuildTerrain() BuildingsMaxCount% = 100 Global BuildingsCount% ;Dim BuildingHeight#(BuildingsMaxCount) Dim BuildingRenderer(BuildingsMaxCount) Dim BuildingCollidable(BuildingsMaxCount) BuildBuildings() PlatformsMaxCount% = 100 Global PlatformsCount% Dim PlatformRenderer(PlatformsMaxCount) Dim PlatformCollidable(PlatformsMaxCount) BuildPlatforms() CharactersMaxCount% = 10 Global CharactersCount% Dim CharacterFeet(CharactersMaxCount) Dim CharacterEyes(CharactersMaxCount) Dim CharacterRenderer(CharactersMaxCount) Dim CharacterCollider(CharactersMaxCount,10) Dim DebugCharacterCollider(CharactersMaxCount,10) Dim CharacterState%(CharactersMaxCount) Dim CharacterTarget(CharactersMaxCount) BuildCharacters() Global PlayerId% PlayerId = Rand(1,10) SetEntityAsFree(Camera) PositionRotateEntityLikeOtherEntity(Camera,CharacterEyes(PlayerId)) MoveEntity(Camera,0,0,-3) SetEntityAsChildOfOtherEntity(Camera,CharacterEyes(PlayerId)) RotateEntity(CharacterEyes(PlayerId),22.5,0,0) ;PositionEntity(Camera,0,0,-3) DLight = CreateLight(1) LightColor(DLight,200,200,200) PositionEntity(DLight,-1000,1000,-1000) RotateEntity(DLight,45,-45,0) AmbientLight(050,050,050) Global CollidedCollidable% Global CollidedName$ Global CollidedKind$ Global CollidedId% Const GroupTerrainsR% = 1 Const GroupBuildingsR% = 2 Const GroupPlatformsR% = 3 Const GroupCharactersER% = 100 Global UpdateCollidersTime% Global UpdateCollisionsTime% Main() EndGraphics() End() Function PositionRotateEntityLikeOtherEntity(Entity,OtherEntity) PositionEntity(Entity,EntityX(OtherEntity,True),EntityY(OtherEntity,True),EntityZ(OtherEntity,True)) RotateEntity(Entity,EntityPitch(OtherEntity,True),EntityYaw(OtherEntity,True),EntityRoll(OtherEntity,True)) End Function Function PositionEntityLikeOtherEntity(Entity,OtherEntity) PositionEntity(Entity,EntityX(OtherEntity,True),EntityY(OtherEntity,True),EntityZ(OtherEntity,True)) End Function Function RotateEntityLikeOtherEntity(Entity,OtherEntity) RotateEntity(Entity,EntityPitch(OtherEntity,True),EntityYaw(OtherEntity,True),EntityRoll(OtherEntity,True)) End Function Function SetEntityAsChildOfOtherEntity(Entity,OtherEntity) EntityParent(Entity,OtherEntity,True) End Function Function SetEntityAsFree(Entity) EntityParent(Entity,0) End Function Function Distance2D#(PAX#,PAZ#,PBX#,PBZ#) VX# = PBX - PAX VZ# = PBZ - PAZ Distance2D# = Sqr((VX*VX)+(VZ*VZ)) Return Distance2D End Function Function Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#) VX# = PBX - PAX VY# = PBY - PAY VZ# = PBZ - PAZ Distance3D# = Sqr((VX*VX)+(VY*VY)+(VZ*VZ)) Return Distance3D End Function Function BuildTerrain() TerrainRenderer = CreateTerrain(128) For VX% = 0 To 128-1 For VZ% = 0 To 128-1 HeightRGB% = Rand(030,033) Height# = 1.0/255*HeightRGB ModifyTerrain(TerrainRenderer,VX,VZ,Height,False) Next Next ScaleEntity(TerrainRenderer,1,25.5,1) TerrainDetail(TerrainRenderer,4000,True) TerrainShading(TerrainRenderer,True) PositionEntity(TerrainRenderer,0,0,0) EntityColor(TerrainRenderer,000,100,000) NameEntity(TerrainRenderer,"TER"+Str(1)) End Function Function BuildBuildings() For i% = 1 To 100 BuildingsCount = BuildingsCount + 1 BId% = BuildingsCount TWidth# = Rnd(1,5) TDepth# = Rnd(1,5) THeight# = Rnd(0.25,15) BuildingRenderer(BId) = CreateMesh() TPart = CreateCube() ScaleMesh(TPart,TWidth/2,0.3/2,TDepth/2) PositionMesh(TPart,0,-0.15,0) AddMesh(TPart,BuildingRenderer(BId)) FreeEntity(TPart) TPart = CreateCube() ScaleMesh(TPart,TWidth/2,THeight/2,TDepth/2) PositionMesh(TPart,0,THeight/2,0) AddMesh(TPart,BuildingRenderer(BId)) FreeEntity(TPart) EntityColor(BuildingRenderer(BId),100,100,100) BuildingCollidable(BId) = CopyMesh(BuildingRenderer(BId)) EntityAlpha(BuildingCollidable(BId),0.25) NameEntity(BuildingCollidable(BId),"BUI"+Str(BId)) .LineChooseBuildingPosition TX# = Rnd(1+TWidth/2,100-1-TWidth/2) TY# = 3.3 TZ# = Rnd(1+TDepth/2,100-1-TDepth/2) PositionEntity(BuildingCollidable(BId),TX,TY,TZ) For OBId% = 1 To BuildingsCount If(OBId <> BId) If(MeshesIntersect(BuildingCollidable(BId),BuildingCollidable(OBId))=True) Goto LineChooseBuildingPosition EndIf EndIf Next PositionEntity(BuildingRenderer(BId),TX,TY,TZ) Next End Function Function BuildPlatforms() For i% = 1 To 100 PlatformsCount = PlatformsCount + 1 PId % = PlatformsCount TWidth# = Rnd(0.5,3) TDepth# = Rnd(0.5,3) PlatformRenderer(PId) = CreateMesh() TPart = CreateCube() ScaleMesh(TPart,TWidth/2,0.1/2,TDepth/2) PositionMesh(TPart,0,0.05,0) AddMesh(TPart,PlatformRenderer(PId)) FreeEntity(TPart) EntityColor(PlatformRenderer(PId),100,100,100) PlatformCollidable(PId) = CopyMesh(PlatformRenderer(PId)) EntityAlpha(PlatformCollidable(PId),0.25) NameEntity(PlatformCollidable(PId),"PLA"+Str(PId)) .LineChoosePlatformPosition TX# = Rand(1+TWidth/2,100-1-TWidth/2) TY# = Rnd(3.3,10) TZ# = Rand(1+TDepth/2,100-1-TDepth/2) PositionEntity(PlatformCollidable(PId),TX,TY,TZ) For BId% = 1 To BuildingsCount If(MeshesIntersect(PlatformCollidable(PId),BuildingCollidable(BId))=True) Goto LineChoosePlatformPosition EndIf Next For OPId% = 1 To PlatformsCount If(OPId <> PId) If(MeshesIntersect(PlatformCollidable(PId),PlatformCollidable(OPId))=True) Goto LineChoosePlatformPosition EndIf EndIf Next PositionEntity(PlatformRenderer(PId),TX,TY,TZ) Next End Function Function BuildCharacters() For i% = 1 To 10 CharactersCount = CharactersCount + 1 CId% = CharactersCount R% = Rand(050,250) G% = Rand(050,250) B% = Rand(050,250) ;Feet CharacterFeet(CId) = CreatePivot() PositionEntity(CharacterFeet(CId),0,0,0) ;Eyes CharacterEyes(CId) = CreatePivot() PositionRotateEntityLikeOtherEntity(CharacterEyes(CId),CharacterFeet(CId)) SetEntityAsChildOfOtherEntity(CharacterEyes(CId),CharacterFeet(CId)) MoveEntity(CharacterEyes(CId),0,1.6,0.15) DebugCharacterEyes = CreateCube() ScaleMesh(DebugCharacterEyes,0.14/2,0.04/2,0.08/2) PositionMesh(DebugCharacterEyes,0,0,0.04) PositionRotateEntityLikeOtherEntity(DebugCharacterEyes,CharacterEyes(CId)) SetEntityAsChildOfOtherEntity(DebugCharacterEyes,CharacterEyes(CId)) EntityColor(DebugCharacterEyes,R,G,B) ;Mesh CharacterRenderer(CId) = CreateCube() ScaleMesh(CharacterRenderer(CId),0.5/2,1.7/2,0.25/2) PositionMesh(CharacterRenderer(CId),0,1.7/2,0) PositionRotateEntityLikeOtherEntity(CharacterRenderer(CId),CharacterFeet(CId)) SetEntityAsChildOfOtherEntity(CharacterRenderer(CId),CharacterFeet(CId)) EntityColor(CharacterRenderer(CId),R,G,B) ;DebugColliderEs For ii% = 1 To 10 DebugCharacterCollider(CId,ii%) = CreateSphere(8) ScaleMesh(DebugCharacterCollider(CId,ii%),0.25,0.25,0.25) EntityAlpha(DebugCharacterCollider(CId,ii%),0.5) Next ;ColliderEs For EId% = 1 To 6 VY# = 0+(EId*0.25) CharacterCollider(CId,EId) = CreatePivot() PositionRotateEntityLikeOtherEntity(CharacterCollider(CId,EId),CharacterFeet(CId)) MoveEntity(CharacterCollider(CId,EId),0,VY,0) SetEntityAsChildOfOtherEntity(CharacterCollider(CId,EId),CharacterFeet(CId)) PositionRotateEntityLikeOtherEntity(DebugCharacterCollider(CId,EId),CharacterFeet(CId)) MoveEntity(DebugCharacterCollider(CId,EId),0,VY,0) SetEntityAsChildOfOtherEntity(DebugCharacterCollider(CId,EId),CharacterFeet(CId)) NameEntity(CharacterCollider(CId,EId),"CHA"+Str(CId)) Next ;Target CharacterTarget(CId) = CreatePivot() DebugCharacterTarget = CreateCylinder(8) ScaleMesh(DebugCharacterTarget,0.5/2,0.001/2,0.5/2) PositionRotateEntityLikeOtherEntity(DebugCharacterTarget,CharacterTarget(CId)) SetEntityAsChildOfOtherEntity(DebugCharacterTarget,CharacterTarget(CId)) EntityColor(DebugCharacterTarget,R,G,B) PositionEntity(CharacterFeet(CId),32.0/(12)*i,3.3+0.001,0.5) PositionEntityLikeOtherEntity(CharacterTarget(CId),CharacterFeet(CId)) Next End Function Function Main() While(KeyDown(1)<>1) GetInputvBasic() If(KeyHit(3)>0) PlayerId = PlayerId + 1 If(PlayerId > 10) PlayerId = 1 EndIf SetEntityAsFree(Camera) PositionRotateEntityLikeOtherEntity(Camera,CharacterEyes(PlayerId)) SetEntityAsChildOfOtherEntity(Camera,CharacterEyes(PlayerId)) MoveEntity(Camera,0,0,-3) RotateEntity(CharacterEyes(PlayerId),22.5,0,0) EndIf UpdateColliders() UpdatePlayerBC() UpdateBotsBC() UpdateCollisionsStart% = MilliSecs() UpdateWorld(0) UpdateCollisionsTime% = MilliSecs() - UpdateCollisionsStart UpdatePlayerAC() UpdateBotsAC() If(KeyDown(2)=1) WireFrame(True) Else WireFrame(False) EndIf SetBuffer(BackBuffer()) RenderWorld() Text(0,0,"Triangles = "+TrisRendered()) Text(0,20,"FPS = "+Str(FPS)) Text(0,40,"CollidedCollidable = "+Str(CollidedCollidable)) Text(0,60,"CollidedName = "+CollidedName) Text(0,80,"CollidedKind = "+CollidedKind) Text(0,100,"CollidedId = "+Str(CollidedId)) Text(0,260,"UpdateCollidersTime = "+Str(UpdateCollidersTime)) Text(0,280,"UpdateCollisionsTime = "+Str(UpdateCollisionsTime)) Flip(1) Wend End Function Function GetInputvBasic() ;MouseWheel MWheel = 0 MZCur = MouseZ() If(MZCur > MZOld) MWheel = + 1 MZOld = MZCur ;DebugLog("MWheel = "+MWheel) ElseIf(MZCur < MZOld) MWheel = - 1 MZOld = MZCur ;DebugLog("MWheel = "+MWheel) EndIf ;Mouse picker properties MXDiff = MouseXSpeed() MYDiff = MouseYSpeed() MPX = MouseX() MPY = MouseY() End Function Function UpdateColliders() UpdateCollidersStart% = MilliSecs() ;Delete Colliders For CId% = 1 To CharactersCount For EId% = 1 To 6 SetEntityAsFree(CharacterCollider(CId,EId)) SetEntityAsFree(DebugCharacterCollider(CId,EId)) FreeEntity(CharacterCollider(CId,EId)) CharacterCollider(CId,EId) = 0 Next Next ;Recreate Colliders For CId% = 1 To CharactersCount ;ColliderEs For EId% = 1 To 6 VY# = 0+(EId*0.25) CharacterCollider(CId,EId) = CreatePivot() PositionRotateEntityLikeOtherEntity(CharacterCollider(CId,EId),CharacterFeet(CId)) MoveEntity(CharacterCollider(CId,EId),0,VY,0) SetEntityAsChildOfOtherEntity(CharacterCollider(CId,EId),CharacterFeet(CId)) PositionRotateEntityLikeOtherEntity(DebugCharacterCollider(CId,EId),CharacterFeet(CId)) MoveEntity(DebugCharacterCollider(CId,EId),0,VY,0) SetEntityAsChildOfOtherEntity(DebugCharacterCollider(CId,EId),CharacterFeet(CId)) NameEntity(CharacterCollider(CId,EId),"CHA"+Str(CId)) Next Next ;give each collider and each collidable a collision group EntityType(TerrainRenderer,GroupTerrainsR) For BId% = 1 To BuildingsCount EntityType(BuildingCollidable(BId),GroupBuildingsR) Next For PId% = 1 To PlatformsCount EntityType(PlatformCollidable(PId),GroupPlatformsR) Next For CId% = 1 To CharactersCount For EId% = 1 To 6 EntityRadius(CharacterCollider(CId,EId),0.25) EntityType(CharacterCollider(CId,EId),GroupCharactersER+CId) NameEntity(CharacterCollider(CId,EId),"CHA"+Str(CId)) Next Next ClearCollisions() ;define collision detection and response between different collision groups For CId% = 1 To CharactersCount Collisions(GroupCharactersER+CId,GroupTerrainsR,2,1) Collisions(GroupCharactersER+CId,GroupBuildingsR,2,1) Collisions(GroupCharactersER+CId,GroupPlatformsR,2,1) For OCId% = 1 To CharactersCount If(OCId <> CId) Collisions(GroupCharactersER+CId,GroupCharactersER+OCId,1,1) EndIf Next Next UpdateCollidersTime = MilliSecs() - UpdateCollidersStart End Function Function UpdatePlayerBC() Id% = PlayerId If(KeyDown(30)=1) TurnEntity(CharacterFeet(Id),0,1.5,0) ElseIf(KeyDown(32)=1) TurnEntity(CharacterFeet(Id),0,-1.5,0) EndIf If(KeyDown(17)=1) MoveEntity(CharacterFeet(Id),0,0,0.1) ElseIf(KeyDown(31)=1) MoveEntity(CharacterFeet(Id),0,0,-0.1) EndIf If(KeyDown(16)=1) MoveEntity(CharacterFeet(Id),0,-0.1,0) ElseIf(KeyDown(18)=1) MoveEntity(CharacterFeet(Id),0,0.1,0) EndIf If(KeyDown(44)=1) MoveEntity(CharacterFeet(Id),-0.1,0,0) ElseIf(KeyDown(45)=1) MoveEntity(CharacterFeet(Id),0.1,0,0) EndIf End Function Function UpdatePlayerAC() Id% = PlayerId For EId% = 1 To 6 CC% = CountCollisions(CharacterCollider(Id,EId)) If(CC% > 0) CollidedCollidable = CollisionEntity(CharacterCollider(Id,EId),1) If(CollidedCollidable <> 0) TName$ = EntityName(CollidedCollidable) TKind$ = Left(TName,3) TId% = Right(TName,Len(TName)-3) VY# = 0+(EId*0.25) TFormPoint(0,-VY,0,CharacterCollider(Id,EId),0) PositionEntity(CharacterFeet(Id),TFormedX(),TFormedY(),TFormedZ()) Goto LineEndCheckCollisions EndIf EndIf Next .LineEndCheckCollisions End Function Function UpdateBotsBC() For Id% = 1 To CharactersCount If(Id <> PlayerId) EndIf Next End Function Function UpdateBotsAC() For Id% = 1 To CharactersCount If(Id <> PlayerId) EndIf Next End Function |
Comments
| ||
I will update this code in the future so that it has better controls, possible actions, but for now this may help some of you understand what i mean by "several ellipsoids childs of one pivot and turn move the pivot". |
Code Archives Forum