public TriangleMeshActor(Game game, Vector3 position, float scale, Texture2D heightMap, float[,] heightData) : base(game) { this.position = position; this.scale = new Vector3(1,1,1); _body = new Body(); _body.MoveTo(position, Matrix.Identity); Array2D field = new Array2D(heightData.GetUpperBound(0), heightData.GetUpperBound(1)); int upperZ = heightData.GetUpperBound(1); for (int x = 0; x < heightData.GetUpperBound(0); x++) { for (int z = 0; z < upperZ; z++) { field.SetAt(x, z, heightData[x, upperZ - 1 - z]); } } _skin = new CollisionSkin(null); float X = heightMap.Width / 2 * scale; float Z = heightMap.Height / 2 * scale; _skin.AddPrimitive(new Heightmap(field, X, -Z, scale, scale), new MaterialProperties(0.7f, 0.7f, 0.6f)); _skin.ExternalData = this; PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(_skin); }
public HeightMapModel2(Game game, HeightMap info, Boolean t, Vector3 pos, float scale) : base(game , null, t, pos, scale) { // Game game, Model m, Boolean t, Vector3 pos, float scale, Boolean solid //Game game, HeightMap m, Boolean t, Vector3 pos, float scale this.Visible = false; Body = new Body(); Skin = new CollisionSkin(null); //Skin.CollisionType = (int)CollisionTypes.Terrain; Array2D field = new Array2D(info.heights.GetUpperBound(0), info.heights.GetUpperBound(1)); for (int x = 0; x < info.heights.GetUpperBound(0); x++) { for (int z = 0; z < info.heights.GetUpperBound(1); z++) { field.SetAt(x, z, info.heights[x, z]); } } Body.MoveTo(new Vector3(info.heightmapPosition.X, info.heightmapPosition.Y, info.heightmapPosition.Y), Matrix.Identity); Skin.AddPrimitive(new Heightmap(field, info.heightmapPosition.X, info.heightmapPosition.Y, scale, scale), (int)MaterialTable.MaterialID.NotBouncyRough); Body.Immovable = true; PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(Skin); }
void Setup(HeightMapInfo heightMapInfo, Vector2 shift) { // A dummy. The physics object uses its position to get draw pos Body = new Body(); CollisionSkin = new CollisionSkin(null); info = heightMapInfo; Array2D field = new Array2D(heightMapInfo.Heights.GetUpperBound(0), heightMapInfo.Heights.GetUpperBound(1)); for (int x = 0; x < heightMapInfo.Heights.GetUpperBound(0); ++x) { for (int z = 0; z < heightMapInfo.Heights.GetUpperBound(1); ++z) { field.SetAt(x, z, heightMapInfo.Heights[x, z]); } } // Move dummy body. The body isn't connected to the collision skin. // But the base class should know where to draw the model. Body.MoveTo(new Vector3(shift.X, 0, shift.Y), Matrix.Identity); CollisionSkin.AddPrimitive(new Heightmap(field, shift.X, shift.Y, 1, 1), new MaterialProperties(0.7f, 0.7f, 0.6f)); PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(CollisionSkin); }
public HeightmapObject(Model model,Vector2 shift, Vector3 position) : base() { Body = new Body(); // just a dummy. The PhysicObject uses its position to get the draw pos Skin = new CollisionSkin(null); HeightMapInfo heightMapInfo = model.Tag as HeightMapInfo; Array2D field = new Array2D(heightMapInfo.heights.GetLength(0), heightMapInfo.heights.GetLength(1)); for (int x = 0; x < heightMapInfo.heights.GetLength(0); x++) { for (int z = 0; z < heightMapInfo.heights.GetLength(1); z++) { field.SetAt(x,z,heightMapInfo.heights[x,z]); } } // move the body. The body (because its not connected to the collision // skin) is just a dummy. But the base class shoudl know where to // draw the model. Body.MoveTo(new Vector3(shift.X,0,shift.Y), Matrix.Identity); Skin.AddPrimitive(new Heightmap(field, shift.X, shift.Y, heightMapInfo.terrainScale, heightMapInfo.terrainScale), new MaterialProperties(0.7f, 0.7f, 0.6f)); PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(Skin); CommonInit(position, new Vector3(1,1,1), model, false, 0); }
public override void Initialise() { base.Initialise(); // Create new bodey and collision skin m_Body = new Body(); m_Skin = new CollisionSkin(m_Body); if (m_Body != null) { // Set skin to the body m_Body.CollisionSkin = m_Skin; // Check the skin was successfully created and add this // custom dice as a primitive to the collision skin if (m_Skin != null) { Box box = new Box(Vector3.Zero, Matrix.Identity, transform.Scale); m_Skin.AddPrimitive(box, (int)MaterialTable.MaterialID.BouncyNormal); // Set mass m_Mass = SetMass(1.0f); // Move the body to correct position initially m_Body.MoveTo(transform.Position, Matrix.Identity); // Apply transform to skin m_Skin.ApplyLocalTransform(new JigLibX.Math.Transform(-m_Mass, Matrix.Identity)); // Enable body EnableBody(); } } }
public void UpdateCollision() { if (geometry.CanRender) { Body[] bodies = PhysicsHelper.PhysicsBodiesVolume(boundsWorldSpaceCollision); if(CollisionMesh == null && bodies.Length > 0) { GenerateCollisionMesh(); CollisionDeleteTime = CollisionDeleteTimeS; } else if (CollisionMesh != null) { if (bodies.Length < 1) { CollisionDeleteTime -= Time.GameTime.ElapsedTime; if (CollisionDeleteTime <= 0) { PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.RemoveCollisionSkin(Collision); Collision = null; CollisionMesh = null; } } else { CollisionDeleteTime = CollisionDeleteTimeS; } } } }
// TODO: Need to add png parameter public HeightMapModel(Game game, Model m, Boolean t, Vector3 pos, float scale) : base(game, m, t, pos, scale, true) { Body = new Body(); // just a dummy. The PhysicObject uses its position to get the draw pos Skin = new CollisionSkin(null); HeightMapInfo heightMapInfo = this.model.Tag as HeightMapInfo; Array2D field = new Array2D(heightMapInfo.heights.GetUpperBound(0), heightMapInfo.heights.GetUpperBound(1)); for (int x = 0; x < heightMapInfo.heights.GetUpperBound(0); x++) { for (int z = 0; z < heightMapInfo.heights.GetUpperBound(1); z++) { field.SetAt(x, z, heightMapInfo.heights[x, z]); } } // move the body. The body (because its not connected to the collision // skin) is just a dummy. But the base class shoudl know where to // draw the model. Body.MoveTo(this.Position, Matrix.Identity); Skin.AddPrimitive(new Heightmap(field, 0f, 0f, 1, 1), new MaterialProperties(0.7f, 0.7f, 0.6f)); PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(this.Skin); }
/// <summary> /// Default Constructor /// Initalizes the Body and a CollisionSkin /// No Primatives are added to the Body /// </summary> /// <param name="position">Initial Body Position</param> /// <param name="scale">Scale</param> public Gobject() { Body = new Body(); Skin = new CollisionSkin(Body); Body.CollisionSkin = Skin; Body.ExternalData = this; }
public override void SetSkinAndBody() { Body = new Body(); Skin = new CollisionSkin(null); Skin.AddPrimitive(new JigLibX.Geometry.Plane(Vector3.Up, 0f), new MaterialProperties(0.2f, 0.7f, 0.6f)); PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(Skin); }
public BowlingPin(Game game, Model model, Matrix orientation, Vector3 position) : base(game, model) { body = new Body(); collision = new CollisionSkin(body); // add a capsule for the main corpus Primitive capsule = new Capsule(Vector3.Zero, Matrix.Identity, 0.1f, 1.3f); // add a small box at the buttom Primitive box = new Box(new Vector3(-0.1f,-0.1f,-0.1f), Matrix.Identity, Vector3.One * 0.2f); // add a sphere in the middle Primitive sphere = new Sphere(new Vector3(0.0f, 0.0f, 0.3f), 0.3f); collision.AddPrimitive(capsule, new MaterialProperties(0.1f, 0.5f, 0.5f)); collision.AddPrimitive(box, new MaterialProperties(0.1f, 0.5f, 0.5f)); collision.AddPrimitive(sphere, new MaterialProperties(0.1f, 0.5f, 0.5f)); body.CollisionSkin = this.collision; Vector3 com = SetMass(0.5f); body.MoveTo(position, orientation); collision.ApplyLocalTransform(new Transform(-com, Matrix.Identity)); body.EnableBody(); this.scale = Vector3.One * 10.0f; }
public HeightmapObject(Game game, Model model,Vector2 shift) : base(game, model) { body = new Body(); // just a dummy. The PhysicObject uses its position to get the draw pos collision = new CollisionSkin(null); HeightMapInfo heightMapInfo = model.Tag as HeightMapInfo; Array2D field = new Array2D(heightMapInfo.heights.GetUpperBound(0), heightMapInfo.heights.GetUpperBound(1)); for (int x = 0; x < heightMapInfo.heights.GetUpperBound(0); x++) { for (int z = 0; z < heightMapInfo.heights.GetUpperBound(1); z++) { field.SetAt(x,z,heightMapInfo.heights[x,z]); } } // move the body. The body (because its not connected to the collision // skin) is just a dummy. But the base class shoudl know where to // draw the model. body.MoveTo(new Vector3(shift.X,0,shift.Y), Matrix.Identity); collision.AddPrimitive(new Heightmap(field, shift.X, shift.Y, 1, 1), new MaterialProperties(0.7f,0.7f,0.6f)); PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(collision); }
public override void OnAdd(Scene scene) { this.scene = scene; this.interactTrigger.OnAdd(scene); if (useCollisionTransform) { Transform oldTransform = Transformation; if (mesh.GetCollisionMesh() != null) { collision = new CollisionSkin(null); collision.AddPrimitive(mesh.GetCollisionMesh(), (int)MaterialTable.MaterialID.NotBouncyRough); scene.GetPhysicsEngine().CollisionSystem.AddCollisionSkin(collision); } Transformation = new CollisionTransform(this.collision, scene); Transformation.SetPosition(oldTransform.GetPosition()); Transformation.SetRotation(oldTransform.GetRotation()); Transformation.SetScale(oldTransform.GetScale()); oldTransform = null; } else base.OnAdd(scene); }
public CollDetectInfo(CollisionSkin skin0, CollisionSkin skin1, int indexPrim0, int indexPrim1) { this.IndexPrim0 = indexPrim0; this.IndexPrim1 = indexPrim1; this.Skin0 = skin0; this.Skin1 = skin1; }
public CollisionTransform(CollisionSkin collision, Scene scene) { this.scene = scene; this.collision = collision; this.collisionTransform = new JigLibX.Math.Transform(position, worldMatrix); this.oldTransform = collisionTransform; }
public Missile(ParentGame game, Model modelObj, Texture2D[] modelTextures, DrawingClass drawClass, GameplayScreen Screen) : base(game, modelObj, modelTextures) { this.drawClass = drawClass; this.Screen = Screen; _body = new Body(); _skin = new CollisionSkin(_body); _body.CollisionSkin = _skin; Box box = new Box(Vector3.Zero, Matrix.Identity, new Vector3(1f,1f,4f)); _skin.AddPrimitive(box, new MaterialProperties(0.8f, 0.8f, 0.7f)); Vector3 com = SetMass(2.0f); _body.MoveTo(position, Matrix.Identity); _skin.ApplyLocalTransform(new Transform(-com, Matrix.Identity)); _body.EnableBody(); Body.ExternalData = this; Vector3 pos = position; Vector3 forwardVec = Body.Orientation.Forward; forwardVec.Normalize(); pos -= forwardVec * 10; // Use the particle emitter helper to output our trail particles. trailEmitter = new ParticleEmitter(drawClass.projectileTrailParticles, trailParticlesPerSecond, position); rgob = new RagdollObject(parentGame, null, null, null, RagdollObject.RagdollType.Simple, 1.0f, 3); rgob.Position = position; //rgob.PutToSleep(); //rgob.limbs[0].PhysicsBody.AngularVelocity = (new Vector3(1, 1, 0) * 2000); RagdollTransforms = new List<Matrix>(); RagdollTransforms = rgob.GetWorldMatrix(); foreach (JigLibX.Objects.PhysicObject lim in rgob.limbs) DisableCollisions(lim.PhysicsBody, Body); foreach (JigLibX.Objects.PhysicObject lim in rgob.limbs) foreach (BuildingPiece pic in Screen.PieceList) DisableCollisions(lim.PhysicsBody, pic.Body); foreach (JigLibX.Objects.PhysicObject lim in rgob.limbs) foreach (Building bld in Screen.Buildings) DisableCollisions(lim.PhysicsBody, bld.Body); foreach (JigLibX.Objects.PhysicObject lim in rgob.limbs) DisableCollisions(lim.PhysicsBody, Screen.terrainActor.Body); foreach (JigLibX.Objects.PhysicObject limb0 in rgob.limbs) foreach (Missile mis in Screen.BulletList) foreach (JigLibX.Objects.PhysicObject limb1 in mis.rgob.limbs) DisableCollisions(limb1.PhysicsBody, limb0.PhysicsBody); }
public PlaneObject(Game game, Model model, float d) : base(game, model) { body = new Body(); collision = new CollisionSkin(null); collision.AddPrimitive(new JigLibX.Geometry.Plane(Vector3.Up, d), new MaterialProperties(0.2f, 0.7f, 0.6f)); PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(collision); }
public override bool ConsiderSkin(CollisionSkin skin0) { if (skin0.Owner != null && (skin0.Owner is InteractBody)) return true; else return false; }
private bool CollidedRecently = true; // we want the object to update immediately once created #endregion Fields #region Constructors /// <summary> /// Default Constructor /// Initalizes the Body and a CollisionSkin /// No Primatives are added to the Body /// </summary> /// <param name="position">Initial Body Position</param> /// <param name="scale">Scale</param> public Gobject() { Body = new Body(); Skin = new CollisionSkin(Body); Body.CollisionSkin = Skin; Body.ExternalData = this; Body.CollisionSkin.callbackFn += new CollisionCallbackFn(CollisionSkin_callbackFn); }
/// <summary> /// Adds a CollisionSkin /// </summary> /// <param name="skin"></param> public override void AddCollisionSkin(CollisionSkin skin) { if (skins.Contains(skin)) System.Diagnostics.Debug.WriteLine("Warning: tried to add skin to CollisionSystemBrute but it's already registered"); else skins.Add(skin); skin.CollisionSystem = this; }
public PlaneObject(Model model,float d, Vector3 position, int asset) : base() { Body = new Body(); Skin = new CollisionSkin(null); Skin.AddPrimitive(new JigLibX.Geometry.Plane(Vector3.Up, d), new MaterialProperties(0.2f, 0.7f, 0.6f)); PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(Skin); CommonInit(position, new Vector3(1,1,1), model, false, asset); }
public ZoneObject(string id, ObjectType objectType, Transform3D transform, Effect effect, Color color, float alpha, bool isImpenetrable) : base(id, objectType, transform, effect, color, alpha) { //set body and skin for this zone this.body = new Body(); this.body.ExternalData = this; this.collision = new CollisionSkin(this.body); this.body.CollisionSkin = this.collision; this.isImpenetrable = isImpenetrable; //we cant move through it }
public override void Initialise() { base.Initialise(); // Create new bodey and collision skin m_Body = new Body(); m_Skin = new CollisionSkin(m_Body); // Set physics controller m_PhysicsController.Initialize(m_Body); }
// Setup everything void Setup() { // We can't use InitializeBody() here because we want to add a // plane and not have it fall Body = new Body(); CollisionSkin = new CollisionSkin(null); CollisionSkin.AddPrimitive( new JigLibX.Geometry.Plane(Vector3.Up, 0.0f), new MaterialProperties(0.2f, 0.7f, 0.6f)); PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(CollisionSkin); }
public CollidableObject(string id, ObjectType objectType, Transform3D transform, Effect effect, Texture2D texture, Model model, Color color, float alpha) : base(id, objectType, transform, effect, texture, model, color, alpha) { this.body = new Body(); this.body.ExternalData = this; this.collision = new CollisionSkin(this.body); this.body.CollisionSkin = this.collision; //register for callback collision to see who just walked into the zone //we will only normally register for this event in a class that sub-classes CollidableObject e.g. PickupCollidableObject or PlayerCollidableObject this.Body.CollisionSkin.callbackFn += CollisionSkin_callbackFn; }
public bool Collision_callbackFn(CollisionSkin collider, CollisionSkin collidee) { if (collidee.Owner.ExternalData is PlayerObject) { //change Camera EventDispatcher.Publish(new CameraEventData(this.ID, this, EventType.OnCameraChanged, this.cameraLayout, this.cameraID)); } this.Body.DisableBody(); this.Remove(); return this.IsImpenetrable; }
public SphereObject(Game game, Model model,float radius, Matrix orientation, Vector3 position) : base(game, model) { body = new Body(); collision = new CollisionSkin(body); collision.AddPrimitive(new Sphere(Vector3.Zero * 5.0f,radius), new MaterialProperties(0.5f,0.7f,0.6f)); body.CollisionSkin = this.collision; Vector3 com = SetMass(10.0f); body.MoveTo(position + com, orientation); // collision.ApplyLocalTransform(new Transform(-com, Matrix.Identity)); body.EnableBody(); this.scale = Vector3.One * radius; }
public virtual bool Collision_callbackFn(CollisionSkin collider, CollisionSkin collidee) { if (collidee.Owner.ExternalData is PlayerObject) { PlayerObject playerObject = collidee.Owner.ExternalData as PlayerObject; //Console.WriteLine("Zone: " + playerObject.ID); //Event, Sound, Pickup //Event, ID, Remove //Event, UI, Bullet/Health, Increment } return this.IsImpenetrable; }
public BoxObject(Game game,Model model,Vector3 sideLengths, Matrix orientation, Vector3 position) : base(game,model) { body = new Body(); collision = new CollisionSkin(body); collision.AddPrimitive(new Box(- 0.5f * sideLengths, orientation, sideLengths), new MaterialProperties(0.8f, 0.8f, 0.7f)); body.CollisionSkin = this.collision; Vector3 com = SetMass(1.0f); body.MoveTo(position, Matrix.Identity); collision.ApplyLocalTransform(new Transform(-com, Matrix.Identity)); body.EnableBody(); this.scale = sideLengths; }
public CapsuleObject(Game game, Model model,float radius,float length, Matrix orientation, Vector3 position) : base(game, model) { body = new Body(); collision = new CollisionSkin(body); collision.AddPrimitive(new Capsule(Vector3.Transform(new Vector3(-0.5f,0,0), orientation),orientation,radius,length),(int)MaterialTable.MaterialID.BouncyNormal); body.CollisionSkin = this.collision; Vector3 com = SetMass(10.0f); body.MoveTo(position + com, Matrix.Identity); collision.ApplyLocalTransform(new Transform(-com,Matrix.Identity)); body.EnableBody(); this.scale = new Vector3(radius, radius, length / 2); }
public override void OnAdd(Scene scene) { base.OnAdd(scene); if (false == true && mesh.GetCollisionMesh() != null) { Matrix currOrientation = Transformation.GetTransform(); currOrientation.Translation = Vector3.Zero; Vector3 currPosition = Transformation.GetPosition(); collisionTransform = new JigLibX.Math.Transform(currPosition, currOrientation); collision = new CollisionSkin(null); collision.AddPrimitive(mesh.GetCollisionMesh(), (int)MaterialTable.MaterialID.NotBouncyRough); scene.GetPhysicsEngine().CollisionSystem.AddCollisionSkin(collision); collision.SetNewTransform(ref collisionTransform); } }
/// <summary> /// Whenever a skin changes position it will call this to let us /// update our internal state. /// </summary> /// <param name="skin"></param> public abstract void CollisionSkinMoved(CollisionSkin skin);
/// <summary> /// Don't add skins whilst doing detection! /// </summary> /// <param name="collisionSkin"></param> public abstract void AddCollisionSkin(CollisionSkin collisionSkin);
/// <summary> /// Decides whether a pair of skins should be considered for collision /// or not. /// </summary> /// <param name="skin0"></param> /// <param name="skin1"></param> /// <returns>True if the pair should be considered otherwise false.</returns> public abstract bool ConsiderSkinPair(CollisionSkin skin0, CollisionSkin skin1);
/// <summary> /// Intersect a segment with the world. If non-zero the predicate /// allows certain skins to be excluded /// </summary> /// <param name="fracOut"></param> /// <param name="skinOut"></param> /// <param name="posOut"></param> /// <param name="normalOut"></param> /// <param name="seg"></param> /// <param name="collisionPredicate"></param> /// <returns>bool</returns> public abstract bool SegmentIntersect(out float fracOut, out CollisionSkin skinOut, out Vector3 posOut, out Vector3 normalOut, Segment seg, CollisionSkinPredicate1 collisionPredicate);
/// <summary> /// CollDetect /// </summary> /// <param name="infoOrig"></param> /// <param name="collTolerance"></param> /// <param name="collisionFunctor"></param> public override void CollDetect(CollDetectInfo infoOrig, float collTolerance, CollisionFunctor collisionFunctor) { // get the skins in the order that we're expectiing CollDetectInfo info = infoOrig; if (info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0).Type == this.Type1) { CollisionSkin skinSwap = info.Skin0; info.Skin0 = info.Skin1; info.Skin1 = skinSwap; int primSwap = info.IndexPrim0; info.IndexPrim0 = info.IndexPrim1; info.IndexPrim1 = primSwap; } Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero; Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero; // todo - proper swept test Capsule oldCapsule = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Capsule; Capsule newCapsule = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Capsule; Segment oldSeg = new Segment(oldCapsule.Position, oldCapsule.Length * oldCapsule.Orientation.Backward); Segment newSeg = new Segment(newCapsule.Position, newCapsule.Length * newCapsule.Orientation.Backward); float radius = oldCapsule.Radius; Box oldBox = info.Skin1.GetPrimitiveOldWorld(info.IndexPrim1) as Box; Box newBox = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as Box; float oldSegT; float oldBoxT0, oldBoxT1, oldBoxT2; float oldDistSq = Distance.SegmentBoxDistanceSq(out oldSegT, out oldBoxT0, out oldBoxT1, out oldBoxT2, oldSeg, oldBox); float newSegT; float newBoxT0, newBoxT1, newBoxT2; float newDistSq = Distance.SegmentBoxDistanceSq(out newSegT, out newBoxT0, out newBoxT1, out newBoxT2, newSeg, newBox); if (MathHelper.Min(oldDistSq, newDistSq) < ((radius + collTolerance) * (radius + collTolerance))) { Vector3 segPos = oldSeg.GetPoint(oldSegT); Vector3 boxPos = oldBox.GetCentre() + oldBoxT0 * oldBox.Orientation.Right + oldBoxT1 * oldBox.Orientation.Up + oldBoxT2 * oldBox.Orientation.Backward; float dist = (float)System.Math.Sqrt((float)oldDistSq); float depth = radius - dist; Vector3 dir; if (dist > JiggleMath.Epsilon) { dir = segPos - boxPos; JiggleMath.NormalizeSafe(ref dir); } else if ((segPos - oldBox.GetCentre()).LengthSquared() > JiggleMath.Epsilon) { dir = segPos - oldBox.GetCentre(); JiggleMath.NormalizeSafe(ref dir); } else { // todo - make this not random dir = Vector3.Transform(Vector3.Backward, Matrix.CreateFromAxisAngle(Vector3.Up, MathHelper.ToRadians(random.Next(360)))); } unsafe { SmallCollPointInfo collInfo = new SmallCollPointInfo(boxPos - body0Pos, boxPos - body1Pos, depth); collisionFunctor.CollisionNotify(ref info, ref dir, &collInfo, 1); } } }
/// <summary> /// Decides whether a CollisionSkin should be considered while /// doing SegmentIntersecting tests or not. /// </summary> /// <param name="skin0">Skin to be considered.</param> /// <returns>True if the skin should be considered otherwise false.</returns> public abstract bool ConsiderSkin(CollisionSkin skin0);
/// <summary> /// Detect BoxHeightmap Collisions. /// </summary> /// <param name="infoOrig"></param> /// <param name="collTolerance"></param> /// <param name="collisionFunctor"></param> public override void CollDetect(CollDetectInfo infoOrig, float collTolerance, CollisionFunctor collisionFunctor) { CollDetectInfo info = infoOrig; if (info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0).Type == this.Type1) { CollisionSkin skinSwap = info.Skin0; info.Skin0 = info.Skin1; info.Skin1 = skinSwap; int primSwap = info.IndexPrim0; info.IndexPrim0 = info.IndexPrim1; info.IndexPrim1 = primSwap; } Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero; Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero; // todo - proper swept test Box oldBox = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Box; Box newBox = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Box; Heightmap oldHeightmap = info.Skin1.GetPrimitiveOldWorld(info.IndexPrim1) as Heightmap; Heightmap newHeightmap = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as Heightmap; Vector3[] oldPts, newPts; oldBox.GetCornerPoints(out oldPts); newBox.GetCornerPoints(out newPts); SmallCollPointInfo[] collPtArray = SCPIStackAlloc(); int numCollPts = 0; Vector3 collNormal = Vector3.Zero; for (int i = 0; i < 8; ++i) { Vector3 newPt = newPts[i]; float newDist; Vector3 normal; newHeightmap.GetHeightAndNormal(out newDist, out normal, newPt); if (newDist < collTolerance) { Vector3 oldPt = oldPts[i]; float oldDist = oldHeightmap.GetHeight(oldPt); #region REFERENCE: collPts.Add(new CollPointInfo(oldPt - body0Pos, oldPt - body1Pos, -oldDist)); Vector3 pt0; Vector3 pt1; Vector3.Subtract(ref oldPt, ref body0Pos, out pt0); Vector3.Subtract(ref oldPt, ref body1Pos, out pt1); if (numCollPts < MaxLocalStackSCPI) { // BEN-OPTIMISATION: Now reuses existing collPts instead of reallocating. collPtArray[numCollPts].R0 = pt0; collPtArray[numCollPts].R1 = pt1; collPtArray[numCollPts++].InitialPenetration = -oldDist; } #endregion #region REFERENCE: collNormal += normal; Vector3.Add(ref collNormal, ref normal, out collNormal); #endregion } } if (numCollPts > 0) { JiggleMath.NormalizeSafe(ref collNormal); collisionFunctor.CollisionNotify(ref info, ref collNormal, collPtArray, numCollPts); } FreeStackAlloc(collPtArray); }
/// <summary> /// Not needed /// </summary> /// <param name="skin"></param> public override void CollisionSkinMoved(CollisionSkin skin) { // not needed }
/// <summary> /// CollDetect /// </summary> /// <param name="info"></param> /// <param name="collTolerance"></param> /// <param name="collisionFunctor"></param> public override void CollDetect(CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor) { if (info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0).Type == this.Type1) { CollisionSkin skinSwap = info.Skin0; info.Skin0 = info.Skin1; info.Skin1 = skinSwap; int primSwap = info.IndexPrim0; info.IndexPrim0 = info.IndexPrim1; info.IndexPrim1 = primSwap; } Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero; Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero; // todo - proper swept test Capsule oldCapsule = (Capsule)info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0); Capsule newCapsule = (Capsule)info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0); JigLibX.Geometry.Plane oldPlane = (JigLibX.Geometry.Plane)info.Skin1.GetPrimitiveOldWorld(info.IndexPrim1); JigLibX.Geometry.Plane newPlane = (JigLibX.Geometry.Plane)info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1); Matrix newPlaneInvTransform = newPlane.InverseTransformMatrix; Matrix oldPlaneInvTransform = oldPlane.InverseTransformMatrix; unsafe { #if USE_STACKALLOC SmallCollPointInfo *collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI]; #else SmallCollPointInfo[] collPtArray = SCPIStackAlloc(); fixed(SmallCollPointInfo *collPts = collPtArray) #endif { int numCollPts = 0; // the start { Vector3 oldCapsuleStartPos = Vector3.Transform(oldCapsule.Position, oldPlaneInvTransform); Vector3 newCapsuleStartPos = Vector3.Transform(newCapsule.Position, newPlaneInvTransform); float oldDist = Distance.PointPlaneDistance(oldCapsuleStartPos, oldPlane); float newDist = Distance.PointPlaneDistance(newCapsuleStartPos, newPlane); if (MathHelper.Min(newDist, oldDist) < collTolerance + newCapsule.Radius) { float oldDepth = oldCapsule.Radius - oldDist; // calc the world position based on the old position8(s) Vector3 worldPos = oldCapsule.Position - oldCapsule.Radius * oldPlane.Normal; // BEN-OPTIMISATION: Now reuses existing collPts instead of reallocating. collPts[numCollPts].R0 = worldPos - body0Pos; collPts[numCollPts].R1 = worldPos - body1Pos; collPts[numCollPts++].InitialPenetration = oldDepth; } } // the end { Vector3 oldCapsuleEndPos = Vector3.Transform(oldCapsule.GetEnd(), oldPlaneInvTransform); Vector3 newCapsuleEndPos = Vector3.Transform(newCapsule.GetEnd(), newPlaneInvTransform); float oldDist = Distance.PointPlaneDistance(oldCapsuleEndPos, oldPlane); float newDist = Distance.PointPlaneDistance(newCapsuleEndPos, newPlane); if (System.Math.Min(newDist, oldDist) < collTolerance + newCapsule.Radius) { float oldDepth = oldCapsule.Radius - oldDist; // calc the world position based on the old position(s) Vector3 worldPos = oldCapsule.GetEnd() - oldCapsule.Radius * oldPlane.Normal; // BEN-OPTIMISATION: Now reuses existing collPts instead of reallocating. collPts[numCollPts].R0 = worldPos - body0Pos; collPts[numCollPts].R1 = worldPos - body1Pos; collPts[numCollPts++].InitialPenetration = oldDepth; } if (numCollPts > 0) { collisionFunctor.CollisionNotify(ref info, ref oldPlane.normal, collPts, numCollPts); } } } #if !USE_STACKALLOC FreeStackAlloc(collPtArray); #endif } }
/// <summary> /// CollDetect /// </summary> /// <param name="infoOrig"></param> /// <param name="collTolerance"></param> /// <param name="collisionFunctor"></param> public override void CollDetect(CollDetectInfo infoOrig, float collTolerance, CollisionFunctor collisionFunctor) { // get the skins in the order that we're expecting CollDetectInfo info = infoOrig; if (info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0).Type == this.Type1) { CollisionSkin skinSwap = info.Skin0; info.Skin0 = info.Skin1; info.Skin1 = skinSwap; int primSwap = info.IndexPrim0; info.IndexPrim0 = info.IndexPrim1; info.IndexPrim1 = primSwap; } Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero; Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero; // todo - proper sweep test Sphere oldSphere = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Sphere; Sphere newSphere = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Sphere; Box oldBox = info.Skin1.GetPrimitiveOldWorld(info.IndexPrim1) as Box; Box newBox = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as Box; Vector3 oldBoxPoint; Vector3 newBoxPoint; float oldDist = oldBox.GetDistanceToPoint(out oldBoxPoint, oldSphere.Position); float newDist = newBox.GetDistanceToPoint(out newBoxPoint, newSphere.Position); // normally point will be outside float oldDepth = oldSphere.Radius - oldDist; float newDepth = newSphere.Radius - newDist; if (System.Math.Max(oldDepth, newDepth) > -collTolerance) { Vector3 dir; if (oldDist < -JiggleMath.Epsilon) { dir = oldBoxPoint - oldSphere.Position - oldBoxPoint; JiggleMath.NormalizeSafe(ref dir); } else if (oldDist > JiggleMath.Epsilon) { dir = oldSphere.Position - oldBoxPoint; JiggleMath.NormalizeSafe(ref dir); } else { dir = oldSphere.Position - oldBox.GetCentre(); JiggleMath.NormalizeSafe(ref dir); } unsafe { SmallCollPointInfo collInfo = new SmallCollPointInfo(oldBoxPoint - body0Pos, oldBoxPoint - body1Pos, oldDepth); collisionFunctor.CollisionNotify(ref info, ref dir, &collInfo, 1); } } #endregion }
/// <summary> /// Don't remove skins whilst doing detection! /// </summary> /// <param name="collisionSkin"></param> public abstract bool RemoveCollisionSkin(CollisionSkin collisionSkin);