/// <summary> /// Sets the Object3D's height value to the corresponding surface position's height /// </summary> /// <param name="anObject3D"> has Translation.X and Translation.Y values</param> public void setSurfaceHeight(Object3D anObject3D) { float terrainHeight; if (!lerp) // defaulted to no lerping, regular jerky movement { terrainHeight = terrain.surfaceHeight( (int)(anObject3D.Translation.X / spacing), (int)(anObject3D.Translation.Z / spacing)); } else // lerping enabled, smooth terrain movement { Vector3 TL = anObject3D.TopLeft; // all the corner vertices Vector3 TR = anObject3D.TopRight; Vector3 BL = anObject3D.BottomLeft; Vector3 BR = anObject3D.BottomRight; // determine if player is on top left triangle bottom right triangle // x and z coords used for distance if (Vector2.Distance(new Vector2(TL.X, TL.Z), new Vector2(anObject3D.Translation.X, anObject3D.Translation.Z)) < Vector2.Distance(new Vector2(BR.X, BR.Z), new Vector2(anObject3D.Translation.X, anObject3D.Translation.Z))) { float xY = TL.Y - Vector3.Lerp(TL, TR, (TL.X - anObject3D.Translation.X) / spacing).Y; float zY = TL.Y - Vector3.Lerp(TL, BL, (TL.Z - anObject3D.Translation.Z) / spacing).Y; terrainHeight = TL.Y + xY + zY; } else { float xY = BR.Y - Vector3.Lerp(BR, BL, (anObject3D.Translation.X - BR.X) / spacing).Y; float zY = BR.Y - Vector3.Lerp(BR, TR, (anObject3D.Translation.Z - BR.Z) / spacing).Y; terrainHeight = BR.Y + xY + zY; } } anObject3D.Translation = new Vector3(anObject3D.Translation.X, terrainHeight, anObject3D.Translation.Z); }
/// <summary> /// Construct a pack with an Object3D leader /// </summary> /// <param name="theStage"> the scene </param> /// <param name="label"> name of pack</param> /// <param name="meshFile"> model of a pack instance</param> /// <param name="xPos, zPos"> approximate position of the pack </param> /// <param name="aLeader"> alpha dog can be used for flock center and alignment </param> public Pack(Stage theStage, string label, string meshFile, int nDogs, int xPos, int zPos, Object3D theLeader) : base(theStage, label, meshFile) { isCollidable = true; random = new Random(); leader = theLeader; int spacing = stage.Spacing; // initial vertex offset of dogs around (xPos, zPos) int[,] position = { { 0, 11 }, { 1, 10 }, { 2, 9 }, { 3, 8 }, { 4, 7 }, { 5, 6 }, { 6, 5 }, { 7, 4 }, { 8, 3 }, { 9, 2 }, { 10, 1 }, { 11, 0 } }; for (int i = 0; i < position.GetLength(0); i++) { int x = xPos + position[i, 0]; int z = zPos + position[i, 1]; float scale = (float)(0.25 + random.NextDouble()); addObject(new Vector3(x * spacing, stage.surfaceHeight(x, z), z * spacing), new Vector3(0, 1, 0), 0.0f, new Vector3(scale, scale, scale)); } }
public void flocking(Object3D crab) { Vector3 flockingVector = Vector3.Zero; Vector3 forwardVector; Vector3 alignmentVector; Vector3 cohesionVector; Vector3 seperationVector; Vector3 rotationAxis; float turningAngle = 0.1f; forwardVector = crab.Forward; alignmentVector = leader.Forward; cohesionVector = Vector3.Zero; seperationVector = Vector3.Zero; distance = Vector3.Distance(crab.Translation, leader.Translation); //gives you the distance between the agent and the crabs (ESSENTIAL) // SEPERATION VECTOR if (distance < seperationEnd) { foreach (Object3D model in instance) { if (model == leader) { seperationVector = seperationVector - model.Translation - crab.Translation; } } seperationVector = seperationVector - leader.Translation - crab.Translation; if (distance > seperationDecline && distance < seperationEnd) { weight = weightCalculator(distance, seperationDecline, SAhalf); } seperationVector = seperationVector * weight; Vector3.Normalize(seperationVector); } // ALIGNMENT VECTOR if ((distance > alignmentStart) && (distance < alignmentEnd)) { if (distance > alignmentStart && distance < alignmentPeak) { weight = weightCalculator(distance, seperationDecline, SAhalf); weight = InverseWeightCalculator(weight); } else if (distance > alignmentDecline && distance < alignmentEnd) { weight = weightCalculator(distance, alignmentDecline, AChalf); } alignmentVector = alignmentVector * weight; Vector3.Normalize(alignmentVector); } // COHESION VECTOR if (distance > cohesionStart) { cohesionVector = leader.Translation - crab.Translation; if (distance > cohesionPeak) { weight = 1; } else if (distance > cohesionStart && distance < cohesionPeak) { weight = weightCalculator(distance, alignmentDecline, AChalf); weight = InverseWeightCalculator(weight); } cohesionVector = cohesionVector * weight; Vector3.Normalize(cohesionVector); } // FLOCKING VECTOR flockingVector = alignmentVector + cohesionVector + seperationVector; Vector3.Normalize(flockingVector); rotationAxis = Vector3.Cross(forwardVector, flockingVector); Vector3.Normalize(flockingVector); if (rotationAxis.X + rotationAxis.Y + rotationAxis.Z < 0) { turningAngle = -turningAngle; } crab.Yaw += turningAngle; crab.updateMovableObject(); stage.setSurfaceHeight(crab); }