/// <summary> /// Constructs a new static physics actor. /// </summary> /// <param name="desc">Descriptor for the actor.</param> public TerrainBEPUActor(ActorDesc desc) : base(desc) { if (desc.Shapes.Count != 1) { throw new Exception("Terrain actors can only consist of one shape"); } ShapeDesc shapeDesc = desc.Shapes[0]; if (shapeDesc is HeightFieldShapeDesc) { // For height fields, we need to copy the data into an Array2D. var heightFieldDesc = shapeDesc as HeightFieldShapeDesc; float spacing = heightFieldDesc.SizeX / heightFieldDesc.HeightField.GetLength(0); this.collidable = new Terrain(heightFieldDesc.HeightField, new AffineTransform( new Vector3(spacing, 1, spacing), Quaternion.Identity, Vector3.Zero)); } else { throw new Exception("Shape description for a Terrain actor must be HeightFieldShapeDesc."); } // Tag the physics with data needed by the engine var tag = new EntityTag(this.ownerEntityID); this.collidable.Tag = tag; this.spaceObject = this.collidable; }
protected override void UpdateContainedPairs() { staticGroup.Shape.CollidableTree.GetOverlaps(compoundInfo.hierarchy.Tree, overlappedElements); for (int i = 0; i < overlappedElements.Count; i++) { TreeOverlapPair <Collidable, CompoundChild> element = overlappedElements.Elements[i]; StaticCollidable staticCollidable = element.OverlapA as StaticCollidable; TryToAdd(element.OverlapA, element.OverlapB.CollisionInformation, staticCollidable != null ? staticCollidable.Material : staticGroup.Material, element.OverlapB.Material); } overlappedElements.Clear(); }
protected override void UpdateContainedPairs() { RawList <Collidable> overlappedElements = PhysicsResources.GetCollidableList(); staticGroup.Shape.CollidableTree.GetOverlaps(mesh.boundingBox, overlappedElements); for (int i = 0; i < overlappedElements.Count; i++) { StaticCollidable staticCollidable = overlappedElements.Elements[i] as StaticCollidable; TryToAdd(overlappedElements.Elements[i], mesh, staticCollidable != null ? staticCollidable.Material : staticGroup.Material); } PhysicsResources.GiveBack(overlappedElements); }
} // Initialize #endregion #region Uninitialize /// <summary> /// Uninitialize the component. /// Is important to remove event associations and any other reference. /// </summary> internal override void Uninitialize() { cachedTransform3D = null; if (staticCollidable != null) { PhysicsManager.Scene.Remove(staticCollidable); } // Clean the entity and event reference staticCollidable = null; ((GameObject3D)Owner).Transform.WorldMatrixChanged -= OnWorldMatrixChanged; Owner.ActiveChanged -= OnActiveChanged; // Call this last because the owner information is needed. base.Uninitialize(); } // Uninitialize
} // Uninitialize #endregion #region Create Static Collidable From Model Filter /// <summary> /// Creates and assign a static mesh usign the model stored in the model filter component. /// </summary> /// <param name="triangleSidedness">A triangle can be double sided, or allow one of its sides to let interacting objects through.</param> public void CreateStaticCollidableFromModelFilter(TriangleSidedness triangleSidedness = TriangleSidedness.Counterclockwise) { ModelFilter modelFilter = ((GameObject3D)Owner).ModelFilter; if (modelFilter != null && modelFilter.Model != null && modelFilter.Model is FileModel) { Vector3[] vertices; int[] indices; TriangleMesh.GetVerticesAndIndicesFromModel(((FileModel)modelFilter.Model).Resource, out vertices, out indices); StaticMesh staticMesh = new StaticMesh(vertices, indices) { Sidedness = triangleSidedness }; StaticCollidable = staticMesh; } else { throw new InvalidOperationException("Static Collider: Model filter not present, model not present or model is not a FileModel."); } } // CreateStaticCollidableFromModelFilter
/// <summary> /// Constructs a new physics actor. /// </summary> /// <param name="desc">Descriptor for the actor.</param> public StaticBEPUActor(ActorDesc desc) : base(desc) { // Build all shapes that make up the actor. for (int i = 0; i < desc.Shapes.Count; ++i) { ShapeDesc shapeDesc = desc.Shapes[i]; var tag = new EntityTag(this.ownerEntityID); if (shapeDesc is BoxShapeDesc) { var boxDesc = shapeDesc as BoxShapeDesc; this.body.PhysicsEntity = new Box(desc.Position, boxDesc.Extents.X, boxDesc.Extents.Y, boxDesc.Extents.Z); } else if (shapeDesc is SphereShapeDesc) { var sphereDesc = shapeDesc as SphereShapeDesc; this.body.PhysicsEntity = new Sphere(desc.Position, sphereDesc.Radius); } else if (shapeDesc is CapsuleShapeDesc) { var capDesc = shapeDesc as CapsuleShapeDesc; this.body.PhysicsEntity = new Capsule(desc.Position, capDesc.Length, capDesc.Radius); } else if (shapeDesc is CylinderShapeDesc) { var cylDesc = shapeDesc as CylinderShapeDesc; this.body.PhysicsEntity = new Cylinder(desc.Position, cylDesc.Height, cylDesc.Radius); } else if (shapeDesc is TriangleMeshShapeDesc) { var triDesc = shapeDesc as TriangleMeshShapeDesc; this.collidable = new StaticMesh(triDesc.Vertices.ToArray(), triDesc.Indices.ToArray(), new AffineTransform(Quaternion.CreateFromRotationMatrix(desc.Orientation), desc.Position)); this.collidable.Tag = tag; this.spaceObject = this.collidable; } else if (shapeDesc is HeightFieldShapeDesc) { throw new Exception("To load terrain physics you must use a TerrainBEPUActor."); } else { throw new Exception("Bad shape."); } if (null != this.body.PhysicsEntity) { SetMovable(false); this.body.PhysicsEntity.Tag = tag; this.body.PhysicsEntity.CollisionInformation.Tag = tag; this.spaceObject = this.body.PhysicsEntity; } } if (this.body.PhysicsEntity != null) { this.spaceObject = this.body.PhysicsEntity; this.body.PhysicsEntity.BecomeKinematic(); this.body.PhysicsEntity.IsAffectedByGravity = desc.Dynamic; } Debug.Assert(this.spaceObject != null, "A physics entity was not properly created."); }