public void treasureDetection() { Object3D tempTreasure = findClosestTreasure(this.stage.getTreasure); float distance = Vector3.Distance(tempTreasure.Translation, this.agentObject.Translation); if (distance < (tempTreasure.ObjectBoundingSphereRadius + detectionRadius)) { NavNode closestNode = this.stage.graph.findClosestNavNodeInGraph(this.agentObject.Translation); NavNode treasureNode = this.stage.graph.getNavNode((int)tempTreasure.Translation.X, (int)tempTreasure.Translation.Z); Path aStarPath = new Path(this.stage, this.stage.graph.aStarPathFinding(closestNode, treasureNode), Path.PathType.SINGLE); path = aStarPath; } }
/// <summary> /// Algorithm to find the nearest treasure /// and returns an Object3D /// </summary> /// <param name="t">treasure</param> public Object3D findClosestTreasure(Treasure t) { int nTreasures = t.Instance.Count; int closest = 0; float [] distances = new float[nTreasures]; for (int i = 1; i < nTreasures; i++) { if (Vector3.Distance(this.agentObject.Translation, t.Instance[i].Translation) < Vector3.Distance(this.agentObject.Translation, t.Instance[closest].Translation)) { closest = i; } } treasureTargetObject = t.Instance[closest]; return(t.Instance[closest]); }
public Vector3 getCohesionVector(Object3D dog) { // gets the distance between the passed dog and leader float distance = Vector3.Distance(dog.Translation, leader.Translation); float cohesionBoundingArea = 2000.0f; // checks distance is greater than the cohesion bounding area if so adjust cohesion vector if (distance > cohesionBoundingArea) { Vector3 dogPosition = new Vector3(dog.Translation.X, 0, dog.Translation.Z); Vector3 leaderPosition = new Vector3(leader.Translation.X, 0, leader.Translation.Z); Vector3 cohesionVector = leaderPosition - dogPosition; return(Vector3.Normalize(cohesionVector)); } return(Vector3.Zero); }
/// <summary> /// Calculates the cohesion force by looking at the leader and dogs distance. /// </summary> /// <returns>The cohesion.</returns> /// <param name="obj">Object.</param> public Vector3 calcCohesion(Object3D obj) { float dist = Vector3.Distance(obj.Translation, leader.Translation); Vector3 objLoc, leaderLoc, toLeader; if (dist > 3000.0f) { objLoc = new Vector3(obj.Translation.X, 0, obj.Translation.Z); leaderLoc = new Vector3(leader.Translation.X, 0, leader.Translation.Z); toLeader = leaderLoc - objLoc; return(Vector3.Normalize(toLeader)); } else { return(Vector3.Zero); } }
public void packing(Object3D dog) { Vector3 alignmentVector = getAlignmentVector(dog); Vector3 cohesionVector = getCohesionVector(dog); Vector3 separationVector = getSeparationVector(dog); Vector3 dogForward = dog.Forward; Vector3 flockingVector = alignmentVector + cohesionVector + separationVector; float angle = (float)(Math.PI / 180); dog.Yaw = 0.0f; flockingVector.Normalize(); dogForward.Normalize(); if (flockingVector == Vector3.Zero) { return; } if (Vector3.Distance(dogForward, flockingVector) <= 0.01) { return; } if (Vector3.Distance(Vector3.Negate(dogForward), flockingVector) <= 0.01) { dogForward.X += 0.05f; dogForward.Z += 0.05f; dogForward.Normalize(); } // gets the axis of rotation Vector3 AoR = Vector3.Cross(dogForward, flockingVector); AoR.Normalize(); if (AoR.X + AoR.Y + AoR.Z < 0) { angle = -angle; } dog.Yaw += angle; }
/// <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, 0 }, { 7, -4 }, { -5, -2 }, { -7, 4 }, { 5, 2 } }; 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.5 + 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 freeRoam(Object3D dog) { float angle = 0.3f; foreach (Object3D obj in instance) { obj.Yaw = 0.0f; // change direction 4 time a second 0.07 = 4/60 if (random.NextDouble() < 0.07) { if (random.NextDouble() < 0.5) { dog.Yaw -= angle; // turn left } else { dog.Yaw += angle; // turn right } } } }
/// <summary> /// Sets the Object3D's height value to the corresponding surface position's height. /// (Added by David Kopp) If lerp is enabled then the all MoveableModel3D will get /// height by linear interpolation. /// </summary> /// <param name="anObject3D"> has Translation.X and Translation.Y values</param> public void setSurfaceHeight(Object3D anObject3D) { if (LerpFlag) // check for lerp is enabled - by David Kopp { float xY, zY, dX, dZ; int x, z; x = (int)(anObject3D.Translation.X / spacing); // Get indices for 2d array - by David Kopp z = (int)(anObject3D.Translation.Z / spacing); // Get indices for 2d array - by David Kopp Vector3 A = new Vector3(x * spacing, terrain.surfaceHeight(x, z), z * spacing); // Vertex A of the square the object is on - by David Kopp Vector3 B = new Vector3((x * spacing) + spacing, terrain.surfaceHeight(x + 1, z), z * spacing); // Vertex B of the square the object is on - by David Kopp Vector3 C = new Vector3(x * spacing, terrain.surfaceHeight(x, z + 1), (z * spacing) + spacing); // Vertex C of the square the object is on - by David Kopp Vector3 D = new Vector3((x * spacing) + spacing, terrain.surfaceHeight(x + 1, z + 1), (z * spacing) + spacing); // Vertex D of the square the object is on - by David Kopp Vector3 aPos = anObject3D.Translation; dX = aPos.X - C.X; // x difference away from vertex C - by David Kopp dZ = C.Z - aPos.Z; // z difference away from vertex C - by David Kopp if (dX < dZ) // In the top triangle - by David Kopp { xY = Vector3.Lerp(A, B, ((float)(aPos.X - A.X)) / spacing).Y - A.Y; zY = Vector3.Lerp(A, C, ((float)(aPos.Z - A.Z)) / spacing).Y - A.Y; } else // In the bottom triangle - by David Kopp { xY = Vector3.Lerp(C, D, ((float)(aPos.X - C.X)) / spacing).Y - C.Y; zY = Vector3.Lerp(B, D, ((float)(aPos.Z - B.Z)) / spacing).Y - B.Y; } aPos.Y = A.Y + xY + zY; // Lerp approximate of the objects height at current location - by David Kopp anObject3D.Translation = aPos; } else { float terrainHeight = terrain.surfaceHeight( (int)(anObject3D.Translation.X / spacing), (int)(anObject3D.Translation.Z / spacing)); anObject3D.Translation = new Vector3(anObject3D.Translation.X, terrainHeight, anObject3D.Translation.Z); // Set the objects vector to a vector containing the height from lerp approximation - by David Kopp } }
public Camera(Stage aScene, Object3D anAgentObject, CameraEnum cameraType) { scene = aScene; agent = anAgentObject; cameraCase = cameraType; }