bool CheckBoundingBoxes(HRigidBody a1, HRigidBody b1) { float tol = 0.1f; Vector3 a = a1.transform.position; float aRad = a1.radius; Vector3 b = b1.transform.position; float bRad = b1.radius; if (a.x + aRad + tol < b.x - bRad - tol) { return(false); // a is left of b } if (a.x - aRad - tol > b.x + bRad + tol) { return(false); // a is right of b } if (a.y + aRad + tol < b.y - bRad - tol) { return(false); // a is left of b } if (a.y - aRad - tol > b.y + bRad + tol) { return(false); // a is right of b } if (a.z + aRad + tol < b.z - bRad - tol) { return(false); // a is left of b } if (a.z - aRad - tol > b.z + bRad + tol) { return(false); // a is right of b } return(true); // boxes overlap }
void checkBounds(HRigidBody body) { if (body.transform.position.x > bounds - body.radius) { body.directions = -body.directions; } else if (body.transform.position.x < 0 + body.radius) { body.directions = -body.directions; } if (body.transform.position.y > bounds - body.radius) { body.directions = -body.directions; } else if (body.transform.position.y < 0 + body.radius) { body.directions = -body.directions; } if (body.transform.position.z > bounds - body.radius) { body.directions = -body.directions; } else if (body.transform.position.z < 0 + body.radius) { body.directions = -body.directions; } }
public void stepSimulation(HRigidBody body) { if ((gravity > 0) && !body.isStatic && body.transform.position.y < bounds - body.radius - 1) { body.AddForce(body.mass * gravity * Vector3.down); } else if ((gravity < 0) && !body.isStatic && body.transform.position.y > body.radius + 1) { body.AddForce(body.mass * gravity * Vector3.down); } body.applyGravity = true; body.SumForces(); body.velocityVector += (body.netForceVector / body.mass * Time.deltaTime); body.oldPosition = body.transform.position; if (!physics) { body.transform.position += body.directions * Time.deltaTime; } else { body.transform.position += body.velocityVector * Time.deltaTime; if (body.transform.position == body.oldPosition) { body.didMove = false; } else { body.didMove = true; } } }
bool overlapTest(int i, int k) { HRigidBody a = objects [i]; HRigidBody b = objects [k]; if (a.mins [0].value <b.mins [0].value && a.maxs [0].value> b.mins [0].value || b.mins [0].value <a.mins [0].value && b.maxs [0].value> a.mins [0].value || a.mins[0].value > b.mins[0].value && a.maxs[0].value <b.maxs[0].value || b.mins[0].value> a.mins[0].value && b.maxs[0].value < a.maxs[0].value) { if (a.mins [1].value <b.mins [1].value && a.maxs [1].value> b.mins [1].value || b.mins [1].value <a.mins [1].value && b.maxs [1].value> a.mins [1].value || a.mins[1].value > b.mins[1].value && a.maxs[1].value <b.maxs[1].value || b.mins[1].value> a.mins[1].value && b.maxs[1].value < a.maxs[1].value) { if (a.mins [2].value <b.mins [2].value && a.maxs [2].value> b.mins [2].value || b.mins [2].value <a.mins [2].value && b.maxs [2].value> a.mins [2].value || a.mins[2].value > b.mins[2].value && a.maxs[2].value <b.maxs[2].value || b.mins[2].value> a.mins[2].value && b.maxs[2].value < a.maxs[2].value) { pm.addPair(i, k); return(true); } } } return(false); }
//For particle/plane //public float bodyPlaneMultFactor = 1f; void ApplyImpulse(HRigidBody body) { //float randomization = 0.000f; //Vector3 randomizedVector = new Vector3 (Random.Range (-1, 1) * randomization, Random.Range (-1, 1) * randomization, Random.Range (-1, 1) * randomization); //planeCollisionNormal = planeCollisionNormal + randomizedVector; Vector3 N = planeCollisionNormal; Vector3 V = body.velocityVector; Vector3 Vn = Vector3.Dot(N, V) * N; Vector3 Vt = V - Vn; Vector3 newVelocityVector = Vt - coefficientOfRestitution * Vn; body.velocityVector = newVelocityVector; }
int distributeObject(HRigidBody h) { bool done = false; HRigidBody[] tmp = FindObjectsOfType <HRigidBody> (); int loop = 0; float buffer = bounds / 16f; float buffer2 = buffer * 2; while (!done) { h.transform.position = new Vector3((bounds - buffer2) * Random.value + buffer, (bounds - buffer2) * Random.value + buffer, (bounds - buffer2) * Random.value + buffer); if (tmp.Length == 1) { done = true; } else { for (int m = 0; m < tmp.Length; m++) { if (h.name != tmp [m].name) { bool overlap = CheckBoundingBoxes(h, tmp [m]); if (!overlap) { done = true; } } } } for (int l = 0; l < planeIndices.Length; l++) { int result = narrowPhase.CheckGroundPlaneContacts(new CollisionObject(h, planeIndices [l])); if (result == 2 | result == 1) { done = false; } } loop++; if (loop > 100) { return(1); } } h.oldPosition = h.transform.position; return(0); }
public void makeObjects() { narrowPhase = GetComponent <NarrowPhase> (); // narrowPhase = gameObject.AddComponent<NarrowPhase>(); // narrowPhase.sweepAndPrune = GetComponent<SweepAndPrune> (); // narrowPhase.octTree = GetComponent<OctTreeAlg> (); // narrowPhase.mask = GetComponent<SpatialMasking> (); // narrowPhase.simple = GetComponent<Simple> (); // narrowPhase.boundsThing = GetComponent<Bounds> (); //GameControl.gameControl.createObjects = this; simple = GetComponent <Simple>(); simple.narrowPhase = narrowPhase; mass = GameControl.gameControl.objectMass; speed = GameControl.gameControl.speed; drag = GameControl.gameControl.drag; bounds = GameControl.gameControl.bounds; //space = GameControl.gameControl.spacing; staticRadius = GameControl.gameControl.radius; radiusRange = GameControl.gameControl.radiusRange; //spacing = new Vector3 (space, space, space); dimension = GameControl.gameControl.numObjects; nextUpdate = Time.time; definePlanes(bounds); int count = 0; while (count < dimension) { GameObject particle = GameObject.CreatePrimitive(PrimitiveType.Sphere); float radius = GameControl.gameControl.radius; radius += Random.value * radiusRange; //float radius = radiusRandomizer (); if (radius > maxRadius) { maxRadius = radius; } if (radius < minRadius) { minRadius = radius; } particle.transform.localScale = new Vector3(radius * 2, radius * 2, radius * 2); particle.GetComponent <MeshRenderer> ().material.color = Color.red; particle.name = "Sphere (" + count + ")"; count++; HRigidBody h = particle.AddComponent <HRigidBody> (); if (GameControl.gameControl.massScales) { h.mass = (4f / 3f) * Mathf.PI * Mathf.Pow(radius, 3) * mass; } else { h.mass = mass; } h.velocityExponent = 2.0f; h.drag = drag; h.isStatic = false; h.radius = radius; averageRadius += radius; narrowPhase.bounds = GameControl.gameControl.bounds; int i = distributeObject(h); if (i == 1) { Text msg = GameObject.FindGameObjectWithTag("ErrorText").GetComponent <Text>(); msg.text = "Error: Too many objects for bounding volume: Use fewer objects, enlarge area size, or make radius smaller"; start = false; break; } int[] direction = { -1, 1 }; float speedRange = 0f; h.velocityVector = new Vector3(direction [Random.Range(0, 2)] * (Random.value * speedRange + speed), direction [Random.Range(0, 2)] * (Random.value * speedRange + speed), direction [Random.Range(0, 2)] * (Random.value * speedRange + speed)); } #region arrange objects in grid /* * //static objects in grid * for (int k = 0; k < dimension; k++) { * for (int j = 0; j < dimension; j++) { * for (int i = 0; i < dimension; i++) { * GameObject particle = GameObject.CreatePrimitive (PrimitiveType.Sphere); * float radius = Random.value * radiusRange + staticRadius; * //if (count > dimension * dimension * dimension - 100) { * // radius = 10.0f; * //} else * // radius = 0.05f; * particle.transform.localScale = new Vector3 (radius * 2, radius * 2, radius * 2); * //particle.transform.localScale = new Vector3 (rad * 2, rad * 2, rad * 2); * particle.transform.position = new Vector3 (i * spacing.x + offset, j * spacing.y + offset, k * spacing.z + offset); * particle.GetComponent<Renderer> ().material.color = Color.red; * particle.name = "Sphere (" + count + ")"; * count++; * HRigidBody h = particle.AddComponent<HRigidBody> (); * h.mass = mass; * h.velocityExponent = 2.0f; * h.drag = drag; * h.isStatic = false; * h.radius = radius; * averageRadius += radius; * if (!randomPlacement){ * //h.velocityVector = new Vector3 (-1, 2, -3); * } * if (randomPlacement) { * narrowPhase.bounds = GameControl.gameControl.bounds; * int[] direction = { -1, 1 }; * float speedRange = speed / 5f; * h.velocityVector = new Vector3 (direction [Random.Range (0, 2)] * (Random.value * speedRange + speed), direction [Random.Range (0, 2)] * (Random.value * speedRange + speed), direction [Random.Range (0, 2)] * (Random.value * speedRange + speed)); * bool done = false; * HRigidBody[] tmp = FindObjectsOfType<HRigidBody> (); * int loop = 0; * while (!done) { * particle.transform.position = new Vector3 ((bounds - 4f) * Random.value + 2f, (bounds - 4f) * Random.value + 2f, (bounds - 4f) * Random.value + 2f); * if (tmp.Length == 1) * done = true; * else { * for (int m = 0; m < tmp.Length; m++) { * if (h.name != tmp [m].name) { * bool overlap = CheckBoundingBoxes (h, tmp [m]); * if (!overlap) * done = true; * } * } * } * for (int l = 0; l < planeIndices.Length; l++) { * int result = narrowPhase.CheckGroundPlaneContacts (new CollisionObject (h, planeIndices [l])); * if (result == 2 | result == 1) { * done = false; * } * } * //loop++; * } * h.oldPosition = h.transform.position; * } * } * } * } */ #endregion averageRadius /= count; GameControl.gameControl.avgRadius = averageRadius; GameControl.gameControl.maxRadius = maxRadius; GameControl.gameControl.minRadius = minRadius; HRigidBody[] tmp = FindObjectsOfType <HRigidBody> (); float avgVol = (4f / 3f) * Mathf.PI * (Mathf.Pow(averageRadius, 3f)); #region variance test float percObjVol = (dimension * avgVol) / (bounds * bounds * bounds); GameControl.gameControl.percObjVol = percObjVol; /* * bounds = GameControl.gameControl.bounds = narrowPhase.bounds = (int)Mathf.Pow((avgVol * dimension) / 0.01f, 1f/3f); * definePlanes (bounds); * speed = (float)bounds / 25.6f; * GameControl.gameControl.speed = speed; * foreach (HRigidBody h in FindObjectsOfType<HRigidBody>()) { * distributeObject (h); * int[] direction = { -1, 1 }; * float speedRange = 0f; * h.velocityVector = new Vector3 (direction [Random.Range (0, 2)] * (Random.value * speedRange + speed), direction [Random.Range (0, 2)] * (Random.value * speedRange + speed), direction [Random.Range (0, 2)] * (Random.value * speedRange + speed)); * } * * if (GameControl.gameControl.whichBroad == 1) { * StreamWriter sr; * GameControl.gameControl.fileName = "j" + GameControl.gameControl.testNum + "radiusDist" + ".dat"; * if (!File.Exists ("j" + GameControl.gameControl.testNum + "radiusDist" + ".dat")) { * //sr = File.CreateText ("j" + GameControl.gameControl.testNum + "TimeTest" + whichBroad + ".dat"); * sr = File.CreateText ("j" + GameControl.gameControl.testNum + "radiusDist" + ".dat"); * sr.WriteLine ("# X Y Z"); * } else { * //sr = File.AppendText ("j" + GameControl.gameControl.testNum + "TimeTest" + whichBroad + ".dat"); * sr = File.AppendText ("j" + GameControl.gameControl.testNum + "radiusDist" + ".dat"); * } * sr.WriteLine (perc1); * sr.WriteLine (perc2); * sr.WriteLine (perc3); * sr.WriteLine (perc4); * sr.WriteLine (perc5); * sr.Close (); * } */ #endregion //StartCoroutine (timer ()); if (start) { narrowPhase.StartNarrowPhase(); } }
public EndPoint(HRigidBody i, float v, bool m) { body = i; value = v; isMin = m; }
public void addParticleCollision(HRigidBody h, HRigidBody i) { cols.Add(new CollisionObject(h, i)); }
public void addPlaneCollision(HRigidBody h, int i) { CollisionObject obj = new CollisionObject(h, planeIndices[i]); cols.Add(obj); }
public void Insert(HRigidBody body) { if (objects.Count <= 1 && activeChildren == 0) { curLifeSpan = -1; objects.Add(body); return; } Vector3 dimensions = region.Max - region.Min; if ((region.Max.y - region.Min.y) / 2 < minSize) { objects.Add(body); return; } #region octants Vector3 half = dimensions / 2.0f; Vector3 center = region.Min + half; //Find or create subdivided regions for each octant in the current region BoundingBox[] childOctant = new BoundingBox[8]; if (children == null) { children = new OctTree[8]; } childOctant[0] = (children[0] != null) ? children[0].region : new BoundingBox(region.Min, center); childOctant[1] = (children[1] != null) ? children[1].region : new BoundingBox(new Vector3(center.x, region.Min.y, region.Min.z), new Vector3(region.Max.x, center.y, center.z)); childOctant[2] = (children[2] != null) ? children[2].region : new BoundingBox(new Vector3(center.x, region.Min.y, center.z), new Vector3(region.Max.x, center.y, region.Max.z)); childOctant[3] = (children[3] != null) ? children[3].region : new BoundingBox(new Vector3(region.Min.x, region.Min.y, center.z), new Vector3(center.x, center.y, region.Max.z)); childOctant[4] = (children[4] != null) ? children[4].region : new BoundingBox(new Vector3(region.Min.x, center.y, region.Min.z), new Vector3(center.x, region.Max.y, center.z)); childOctant[5] = (children[5] != null) ? children[5].region : new BoundingBox(new Vector3(center.x, center.y, region.Min.z), new Vector3(region.Max.x, region.Max.y, center.z)); childOctant[6] = (children[6] != null) ? children[6].region : new BoundingBox(center, region.Max); childOctant[7] = (children[7] != null) ? children[7].region : new BoundingBox(new Vector3(region.Min.x, center.y, center.z), new Vector3(center.x, region.Max.y, region.Max.z)); if (drawOcts) { DrawOctTree.drawOctTree.list.Add(childOctant [0]); DrawOctTree.drawOctTree.list.Add(childOctant [1]); DrawOctTree.drawOctTree.list.Add(childOctant [2]); DrawOctTree.drawOctTree.list.Add(childOctant [3]); DrawOctTree.drawOctTree.list.Add(childOctant [4]); DrawOctTree.drawOctTree.list.Add(childOctant [5]); DrawOctTree.drawOctTree.list.Add(childOctant [6]); DrawOctTree.drawOctTree.list.Add(childOctant [7]); } #endregion //First, is the item completely contained within the root bounding box? //note2: I shouldn't actually have to compensate for this. If an object is out of our predefined bounds, then we have a problem/error. // Wrong. Our initial bounding box for the terrain is constricting its height to the highest peak. Flying units will be above that. // Fix: I resized the enclosing box to 256x256x256. This should be sufficient. if (region.Contains(body.transform, body.radius)) { bool found = false; //we will try to place the object into a child node. If we can't fit it in a child node, then we insert it into the current node object list. for (int a = 0; a < 8; a++) { //is the object contained within a child quadrant? if (childOctant [a].Contains(body.transform, body.radius)) { if (children [a] != null) { children [a].Insert(body); //Add the item into that tree and let the child tree figure out what to do with it } else { List <HRigidBody> newList = new List <HRigidBody> (); newList.Add(body); children [a] = new OctTree(childOctant [a], newList, narrowPhase, minSize); hasChildren = true; children [a].parent = this; children [a].name = name + a; children [a].isActive = true; activeChildren |= (byte)(1 << a); children [a].BuildTree(); } found = true; } } if (!found) { objects.Add(body); } } else { objects.Add(body); } }
public CollisionObject(HRigidBody b1, Plane p) { body1 = b1; plane = p; }
public CollisionObject(HRigidBody ba, HRigidBody bb) { body1 = ba; body2 = bb; }