4 using System.Collections.Generic;
7 using SiliconStudio.Core;
8 using SiliconStudio.Core.Collections;
9 using SiliconStudio.Core.Mathematics;
10 using SiliconStudio.Paradox.Effects;
11 using SiliconStudio.Paradox.Effects.Modules;
12 using SiliconStudio.Paradox.Engine;
13 using SiliconStudio.Paradox.EntityModel;
14 using SiliconStudio.Paradox.Games;
15 using SiliconStudio.Paradox.Graphics;
16 using SiliconStudio.Paradox.Threading;
29 readonly FastList<PhysicsElement> elements =
new FastList<PhysicsElement>();
30 readonly FastList<PhysicsElement> characters =
new FastList<PhysicsElement>();
36 : base(new
PropertyKey[] { PhysicsComponent.Key, TransformationComponent.Key })
53 element.UpdateTransformationComponent(physicsTransform);
60 physicsTransform = element.DerivePhysicsTransformation();
65 if (element.
Shape == null)
return;
67 var shape = element.Shape.Shape;
70 element.BoneIndex = -1;
75 for (var index = 0; index < data.ModelComponent.ModelViewHierarchy.Nodes.Length; index++)
77 var node = data.ModelComponent.ModelViewHierarchy.Nodes[index];
79 element.BoneIndex = index;
83 if (element.BoneIndex == -1)
85 throw new Exception(
"The specified LinkedBoneName doesn't exist in the model hierarchy.");
90 if (element.BoneIndex != -1)
92 throw new NotImplementedException(
"Physics on complex hierarchy model's bones is not implemented yet.");
95 var defaultGroups = element.CanCollideWith == 0 || element.CollisionGroup == 0;
99 case PhysicsElement.Types.PhantomCollider:
101 var c = physicsSystem.PhysicsEngine.CreateCollider(shape);
103 element.Collider = c;
104 element.Collider.EntityObject = entity;
105 element.UpdatePhysicsTransformation();
111 physicsSystem.PhysicsEngine.AddCollider(c);
119 case PhysicsElement.Types.StaticCollider:
121 var c = physicsSystem.PhysicsEngine.CreateCollider(shape);
123 element.Collider = c;
124 element.Collider.EntityObject = entity;
125 element.UpdatePhysicsTransformation();
131 physicsSystem.PhysicsEngine.AddCollider(c);
139 case PhysicsElement.Types.StaticRigidBody:
141 var rb = physicsSystem.PhysicsEngine.CreateRigidBody(shape);
143 rb.EntityObject = entity;
144 rb.GetWorldTransformCallback = (out
Matrix transform) => RigidBodyGetWorldTransform(element, out transform);
145 rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform);
146 element.Collider = rb;
147 element.UpdatePhysicsTransformation();
149 rb.Type = RigidBodyTypes.Static;
153 physicsSystem.PhysicsEngine.AddRigidBody(rb);
161 case PhysicsElement.Types.DynamicRigidBody:
163 var rb = physicsSystem.PhysicsEngine.CreateRigidBody(shape);
165 rb.EntityObject = entity;
166 rb.GetWorldTransformCallback = (out
Matrix transform) => RigidBodyGetWorldTransform(element, out transform);
167 rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform);
168 element.Collider = rb;
169 element.UpdatePhysicsTransformation();
171 rb.Type = RigidBodyTypes.Dynamic;
176 physicsSystem.PhysicsEngine.AddRigidBody(rb);
184 case PhysicsElement.Types.KinematicRigidBody:
186 var rb = physicsSystem.PhysicsEngine.CreateRigidBody(shape);
188 rb.EntityObject = entity;
189 rb.GetWorldTransformCallback = (out
Matrix transform) => RigidBodyGetWorldTransform(element, out transform);
190 rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform);
191 element.Collider = rb;
192 element.UpdatePhysicsTransformation();
194 rb.Type = RigidBodyTypes.Kinematic;
199 physicsSystem.PhysicsEngine.AddRigidBody(rb);
207 case PhysicsElement.Types.CharacterController:
209 var ch = physicsSystem.PhysicsEngine.CreateCharacter(shape, element.StepHeight);
211 element.Collider = ch;
212 element.Collider.EntityObject = entity;
213 element.UpdatePhysicsTransformation();
217 physicsSystem.PhysicsEngine.AddCharacter(ch);
224 characters.Add(element);
229 elements.Add(element);
235 if (element.
Collider == null)
return;
237 var toDispose =
new List<IDisposable>();
239 elements.Remove(element);
241 switch (element.
Type)
243 case PhysicsElement.Types.PhantomCollider:
244 case PhysicsElement.Types.StaticCollider:
246 physicsSystem.PhysicsEngine.RemoveCollider(element.Collider);
249 case PhysicsElement.Types.StaticRigidBody:
250 case PhysicsElement.Types.DynamicRigidBody:
251 case PhysicsElement.Types.KinematicRigidBody:
254 var constraints = rb.LinkedConstraints.ToArray();
255 foreach (var c
in constraints)
257 physicsSystem.PhysicsEngine.RemoveConstraint(c);
261 physicsSystem.PhysicsEngine.RemoveRigidBody(rb);
264 case PhysicsElement.Types.CharacterController:
266 characters.Remove(element);
272 toDispose.Add(element.Collider);
273 element.Collider = null;
278 TaskList.Dispatch(toDispose, 4, 128, (i, disposable) => disposable.Dispose());
282 foreach (var d
in toDispose)
291 if (!physicsSystem.PhysicsEngine.Initialized)
return;
295 NewElement(element, data, entity);
301 if (!physicsSystem.PhysicsEngine.Initialized)
return;
305 DeleteElement(element,
true);
311 if (!physicsSystem.PhysicsEngine.Initialized)
return;
313 var elements = entity.Get(PhysicsComponent.Key).Elements;
315 foreach (var element
in elements.Where(element => element.Collider != null))
317 element.Collider.Enabled = enabled;
324 renderSystem = Services.GetSafeServiceAs<
RenderSystem>();
328 physicsSystem.PhysicsEngine.DebugGraphicsDevice = gfxDevice.GraphicsDevice;
331 renderSystem.Pipeline.EndPass += DebugShapesDraw;
337 foreach (var element
in elements)
339 DeleteElement(element);
345 for (var i = 0; i < compound.Count; i++)
347 var subShape = compound[i];
348 switch (subShape.Type)
350 case ColliderShapeTypes.StaticPlane:
352 case ColliderShapeTypes.Compound:
357 var physTrans = element.BoneIndex == -1 ? element.Collider.PhysicsWorldTransform : element.BoneWorldMatrix;
358 physTrans = Matrix.Multiply(subShape.PositiveCenterMatrix, physTrans);
362 Matrix.Multiply(ref subShape.DebugPrimitiveScaling, ref physTrans, out worldTrans);
364 physicsSystem.PhysicsEngine.DebugEffect.WorldViewProj = worldTrans * viewProj;
365 physicsSystem.PhysicsEngine.DebugEffect.Color = element.Collider.IsActive ? Color.Green : Color.Red;
366 physicsSystem.PhysicsEngine.DebugEffect.UseUv = subShape.Type != ColliderShapeTypes.ConvexHull;
368 physicsSystem.PhysicsEngine.DebugEffect.Apply();
370 subShape.DebugPrimitive.Draw();
379 if (!physicsSystem.PhysicsEngine.CreateDebugPrimitives ||
380 !physicsSystem.PhysicsEngine.RenderDebugPrimitives ||
381 !physicsSystem.PhysicsEngine.Initialized ||
382 physicsSystem.PhysicsEngine.DebugGraphicsDevice == null ||
383 physicsSystem.PhysicsEngine.DebugEffect == null)
387 if (renderSystem.Pipeline.Parameters.ContainsKey(
TransformationKeys.
View) && renderSystem.Pipeline.Parameters.ContainsKey(TransformationKeys.Projection))
389 viewProj = renderSystem.Pipeline.Parameters.Get(TransformationKeys.View) * renderSystem.Pipeline.Parameters.Get(
TransformationKeys.
Projection);
396 var rasterizers = physicsSystem.PhysicsEngine.DebugGraphicsDevice.RasterizerStates;
397 physicsSystem.PhysicsEngine.DebugGraphicsDevice.SetRasterizerState(rasterizers.CullNone);
399 foreach (var element
in elements)
401 var shape = element.Shape.Shape;
405 DrawDebugCompound(ref viewProj, (CompoundColliderShape)shape, element);
409 var physTrans = element.BoneIndex == -1 ? element.Collider.PhysicsWorldTransform : element.BoneWorldMatrix;
413 Matrix.Multiply(ref element.Shape.Shape.DebugPrimitiveScaling, ref physTrans, out worldTrans);
415 physicsSystem.PhysicsEngine.DebugEffect.WorldViewProj = worldTrans * viewProj;
416 physicsSystem.PhysicsEngine.DebugEffect.Color = element.Collider.IsActive ? Color.Green : Color.Red;
417 physicsSystem.PhysicsEngine.DebugEffect.UseUv = shape.Type != ColliderShapeTypes.ConvexHull;
419 physicsSystem.PhysicsEngine.DebugEffect.Apply();
421 shape.DebugPrimitive.Draw();
425 physicsSystem.PhysicsEngine.DebugGraphicsDevice.SetRasterizerState(rasterizers.CullBack);
430 if (!physicsSystem.PhysicsEngine.Initialized)
return;
433 physicsSystem.PhysicsEngine.Update((float)time.
Elapsed.TotalSeconds);
436 foreach (var element
in characters.Where(element => element.Collider.Enabled))
438 element.UpdateTransformationComponent(element.Collider.PhysicsWorldTransform);
Service providing method to access GraphicsDevice life-cycle.
List< PhysicsElement > Elements
Elements describing the physical colliders/rigidbodies/character of this entity Any runtime dynamic c...
Game entity. It usually aggregates multiple EntityComponent
string LinkedBoneName
Gets or sets the link (usually a bone).
override void OnEntityRemoved(Entity entity, AssociatedData data)
override void Update(GameTime time)
override void OnSystemAdd()
Entity processor, triggered on various EntitySystem events such as Entity and Component additions and...
PhysicsColliderShape Shape
override void OnSystemRemove()
ModelComponent ModelComponent
Current timing used for variable-step (real time) or fixed-step (game time) games.
Thread-local storage context used during rendering.
Renders its RenderSystem.Pipeline, which will usually result in drawing all meshes, UI, etc...
CollisionFilterGroups1 CollisionGroup
Gets or sets the collision group.
CollisionFilterGroups CanCollideWith
Gets or sets the can collide with.
TransformationComponent TransformationComponent
override AssociatedData GenerateAssociatedData(Entity entity)
Add a Model to an Entity, that will be used during rendering.
PhysicsComponent PhysicsComponent
override void OnEntityAdding(Entity entity, AssociatedData data)
using SiliconStudio.Paradox. Physics
override void OnEnabledChanged(Entity entity, bool enabled)
TimeSpan Elapsed
Gets the elapsed game time since the last update
bool Sprite
Gets or sets a value indicating whether this PhysicsElement is representing a sprite.
A class that represents a tag propety.
Represents a 4x4 mathematical matrix.