/// <summary> /// Create a CONE marker, with the tip at posn /// </summary> /// <param name="color"></param> /// <param name="posn"></param> /// <param name="angle"></param> /// <param name="height"></param> /// <param name="orientation"></param> private Marker(Color color, Vector3 posn, Orientation orientation, float angle, float height) { // Work out the width of the base from the angle float radius = (float)Math.Tan(angle) * height; // Create the mesh, centred at 0,0,0 mesh = Mesh.Cylinder(Engine.Device,0,radius,height,16,1); // Shift the cone so that the tip is at 0,0,0 // and orient it to be aligned with the Y axis (which is how Truespace objects come out when at a YPR of 0,0,0) Matrix mat = Matrix.Translation(0,0,height/2) * Matrix.RotationYawPitchRoll(0,-(float)Math.PI/2,0); VertexBuffer vb = mesh.VertexBuffer; // Retrieve the vertex buffer data CustomVertex.PositionNormal[] vert; // get the input vertices as an array (in case I want to modify them) vert = (CustomVertex.PositionNormal[])vb.Lock(0, typeof(CustomVertex.PositionNormal), 0, mesh.NumberVertices); for (int i=0; i<mesh.NumberVertices; i++) { //vert[i].Z = vert[i].Z + height / 2; vert[i].Position = Vector3.TransformCoordinate(vert[i].Position,mat); vert[i].Normal = Vector3.TransformNormal(vert[i].Normal, mat); } vb.Unlock(); // create the material material.Ambient = color; material.Diffuse = color; material.Specular = color; material.Emissive = color; Goto(posn, orientation); }
private float totalMass = 0; // sum of all cell masses #endregion Fields #region Constructors /// <summary> /// Construct a Creature instance from a genome /// </summary> /// <param name="genotype">The name of the xml file defining this creature, or "" if the creature is being created in the editor</param> /// <param name="location">world location of creature (Y should be zero)</param> /// <param name="orientation">world orientation of creature</param> public Organism(string genotype, Vector3 location, Orientation orientation) { Debug.WriteLine("Creating new Creature from genome: "+genotype); // Set relevant Renderable.FlagBits Dynamic = true; // (Most) creatures respond to forces // Set basic members this.location = location; this.orientation = Quaternion.RotationYawPitchRoll(orientation.Yaw,orientation.Pitch,orientation.Roll); instance = instanceCount++; // get a unique instance number name = genotype+instance.ToString("000"); // give the creature a unique name (valid filename) // Set up other members if (genotype == "") this.genome = new Genome(); // if no genotype supplied, create a default genome (Core cell only, for putting on the clamp) else this.genome = new Genome(genotype); // otherwise, create our unique Genome object and store its ref // Load all the Cells from disk or the Cell Library, using the recipe in the Creature's genome // and establish their connection points partList = new Cell[1024]; // Create an initial partlist (will scrunch later) rootCell = GetCells(genome.Root, null); // read the parts from the genome to create both the tree and partlist Cell[] shorter = new Cell[numParts]; // scrunch the partlist to the right size Array.Copy(partList,shorter,numParts); partList = shorter; // Now that the whole cell tree exists, allow the cells to connect up their channels rootCell.ClearAllChannels(); rootCell.WireUpAllChannels(); // Give the cells an absolute position in space so that we can calculate CG, bounds, etc. rootCell.Locate(Matrix.Translation(location)); // locate root cell temporarily at 0,0,0 RecursiveUpdateFrames(rootCell); // update the combined frames // Find out which cell is to act as the centre of gravity for the system CalculateCG(); // Register the creature with the map and position it properly in space Map.Add(this); MoveTo(location); // Calculate the initial center and radius of the Creature's bounding sphere now it is located ComputeBoundingSphere(); CheckMaps(); // And check maps again, because this requires sphere! // Calculate any aggregate properties required for sensor requests etc. SetAggregateProperties(); // Set the SlowUpdate() timer to a random value, so that organisms do their slow updates // at different times SlowUpdateTimer = Rnd.Float(SLOWUPDATERATE); }
/// <summary> /// Construct the underlying Organism /// </summary> /// <param name="genotype"></param> /// <param name="location"></param> /// <param name="orientation"></param> public CameraShip(string genotype, Vector3 location, Orientation orientation) : base(genotype, location, orientation) { }
/// <summary> /// Extract the Euler angles from the rotation in a transformation matrix /// </summary> /// <param name="m">the transform matrix containing the rotations</param> /// <returns>the oriention implied by the matrix</returns> public static Orientation GetYPR(Matrix m) { Orientation or = new Orientation(0,0,0); or.Yaw = (float)Math.Asin(m.M13); // get the yaw from the matrix float c = (float)Math.Cos(or.Yaw); if ((c<-0.005)||(c>0.005)) // if c is zero we're gimbal locked { or.Pitch = (float)Math.Atan2( -m.M23/c, m.M33/c); or.Roll = (float)Math.Atan2(-m.M12/c, m.M11/c); } else { // gimbal lock has occurred - pitch and roll axes are aligned or.Pitch = or.Roll = (float)Math.Atan2(m.M21, m.M22); } return or; }
/// <summary> /// Addition operator: add a ROTATION to an orientation /// </summary> /// <param name="op1">orientation</param> /// <param name="op2">rotation</param> /// <returns></returns> public static Orientation operator +(Orientation op1,Rotation op2) { Orientation or = new Orientation (op1.Pitch+op2.Pitch,op1.Yaw+op2.Yaw,op1.Roll+op2.Roll); or.Normalise(); return or; }
/// <summary> /// Move and orient this marker /// </summary> /// <param name="locn"></param> /// <param name="orient"></param> public void Goto(Vector3 locn, Orientation orient) { location = locn; orientation = orient; SetMatrix(); }
/// <summary> /// Create a new SPHERE marker /// </summary> /// <param name="color">ARGB value (use A for transparency)</param> /// <param name="posn">World coordinates of TIP</param> /// <param name="size">Radius of base</param> /// <returns></returns> public static Marker CreateCone(Color color, Vector3 posn, Orientation orientation, float angle, float height) { Marker m = new Marker(color, posn, orientation, angle, height); list.Add(m); return m; }
/// <summary> /// TEMP: Create one or more creatures for testing /// </summary> private static void CreateSomeCreatures() { const int NUMCREATURES = 50; Creature = new Organism[NUMCREATURES]; string[] genotype = { "testTail", "testJawRed", }; // Creature 0 is guaranteed to be in front of the camera - use this alone when testing Creature[0] = new Organism(genotype[0], new Vector3(512.0f, 25.0f, 475.0f), new Orientation(0, 0, 0)); Creature[1] = new Organism(genotype[1], new Vector3(512.0f, 25.0f, 480.0f), new Orientation(0, 0, 0)); for (int c = 2; c < NUMCREATURES; c++) { float x, z; do { x = Rnd.Float(400,600); z = Rnd.Float(400,600); } while (Terrain.AltitudeAt(x, z) > Water.WATERLEVEL - 10); Vector3 loc = new Vector3( x, Rnd.Float(Terrain.AltitudeAt(x, z) + 5, Water.WATERLEVEL - 5), z ); Orientation or = new Orientation(Rnd.Float(3.14f), Rnd.Float(3.14f), Rnd.Float(3.14f)); int genome = Rnd.Int(genotype.Length - 1); Creature[c] = new Organism(genotype[genome], loc, or); } }