//parametr direction jest odpowiedzialny za kierunek w którym dosuwamy zaznaczony objekt, //może przyjmować 6 wartości: xyl, xyr, zxf, zxb, yzu, yzd. Będzie podawany odpowiednio na podstawie //wybranej opcji w menu kontekstowym oraz widoku, w którym dana opcja została wybrana private static void SetSpaceRequiredBox(Scene s, String direction) { if(direction.Equals("xyl")) //rzutowanie na płaszczyznę x y przesunięcie do lewej { Vector3D tmp = new Vector3D(sceneBB.minBB.x, selectedObjectBB.minBB.y, selectedObjectBB.minBB.z); Vector3D tmp2 = new Vector3D(selectedObjectBB.minBB.x, selectedObjectBB.maxBB.y, selectedObjectBB.maxBB.z); requiredSpaceBB = new BoundingBox(tmp, tmp2); } else if(direction.Equals("xyr")) //rzutowanie na płaszczyznę x y przesunięcie do prawej { Vector3D tmp = new Vector3D(sceneBB.maxBB.x, selectedObjectBB.maxBB.y, selectedObjectBB.maxBB.z); Vector3D tmp2 = new Vector3D(selectedObjectBB.maxBB.x, selectedObjectBB.minBB.y, selectedObjectBB.minBB.z); requiredSpaceBB = new BoundingBox(tmp2, tmp); } else if(direction.Equals("yzu")) //rzutowanie na płaszczyznę y z przesunięcie do góry { Vector3D tmp = new Vector3D(selectedObjectBB.maxBB.x, sceneBB.maxBB.y, selectedObjectBB.maxBB.z); Vector3D tmp2 = new Vector3D(selectedObjectBB.minBB.x, selectedObjectBB.maxBB.y, selectedObjectBB.minBB.z); requiredSpaceBB = new BoundingBox(tmp2, tmp); } else if(direction.Equals("yzd")) //rzutowanie na płaszczyznę y z przesunięcie do dołu { Vector3D tmp = new Vector3D(selectedObjectBB.minBB.x, sceneBB.minBB.y, selectedObjectBB.minBB.z); Vector3D tmp2 = new Vector3D(selectedObjectBB.maxBB.x, selectedObjectBB.minBB.y, selectedObjectBB.maxBB.z); requiredSpaceBB = new BoundingBox(tmp, tmp2); } else if(direction.Equals("zxb")) //rzutowanie na płaszczyznę z x przesunięcie do tyłu { Vector3D tmp = new Vector3D(selectedObjectBB.minBB.x, selectedObjectBB.minBB.y, sceneBB.minBB.z); Vector3D tmp2 = new Vector3D(selectedObjectBB.maxBB.x, selectedObjectBB.maxBB.y, selectedObjectBB.minBB.z); requiredSpaceBB = new BoundingBox(tmp, tmp2); } else //if(direction.Equals("zxf")) //rzutowanie na płaszczyznę z x przesunięcie do przodu { Vector3D tmp = new Vector3D(selectedObjectBB.maxBB.x, selectedObjectBB.maxBB.y, sceneBB.maxBB.z); Vector3D tmp2 = new Vector3D(selectedObjectBB.minBB.x, selectedObjectBB.minBB.y, selectedObjectBB.maxBB.z); requiredSpaceBB = new BoundingBox(tmp2, tmp); } }
//działa na razie tylko na meshach które nie są zagnieżdżone w hierarchii, dodaje tylko te które nie są zaznaczone, ustawia bb sceny private static void SetBBoxes(Scene s) { float minx = float.MaxValue; float miny = float.MaxValue; float minz = float.MaxValue; float maxx = float.MinValue; float maxy = float.MinValue; float maxz = float.MinValue; float tmpx, tmpy, tmpz; BoundingBox tmpbb; foreach (HierarchyMesh mesh in s.hierarchy.objects) { tmpbb = new BoundingBox(s, mesh); if (!s.IsTriangleSelected(mesh.triangles[0])) { //sprawdzamy, czy obiekt jest zaznaczony - jest kiedy jakikolwiek jego trójkąt jest na liście trójkatów zaznaczonych //jeśli nie jest dodajemy jego bb do listy otherSceneObjBB.Add(tmpbb); } //wyznaczamy skrajne punkty do wyznaczenia bb sceny tmpx = tmpbb.minBB.x; tmpy = tmpbb.minBB.y; tmpz = tmpbb.minBB.z; if (tmpx < minx) minx = tmpx; if (tmpy < miny) miny = tmpy; if (tmpz < minz) minz = tmpz; tmpx = tmpbb.maxBB.x; tmpy = tmpbb.maxBB.y; tmpz = tmpbb.maxBB.z; if (tmpx > maxx) maxx = tmpx; if (tmpy > maxy) maxy = tmpy; if (tmpz > maxz) maxz = tmpz; } Vector3D tmpmin = new Vector3D(minx, miny, minz); Vector3D tmpmax = new Vector3D(maxx, maxy, maxz); sceneBB = new BoundingBox(tmpmin, tmpmax); }
private static void SetSlidingObjectBBox(Scene s) { List<Triangle> selected = new List<Triangle>(); foreach (HierarchyMesh selMesh in s.selTriangles) { foreach (uint triangleIdx in selMesh.triangles) { if(s.IsTriangleSelected(triangleIdx)) selected.Add(s.triangles[(int)triangleIdx]); } } selectedObjectBB = new BoundingBox(s, selected); }
private static void Clear() { selectedObjectBB=null; otherSceneObjBB.Clear(); sceneBB=null; requiredSpaceBB=null; }
private static float CalculateDistanceEZ(BoundingBox otherObj, BoundingBox selObj, String direction) { if (direction.Equals("xyl")) //rzutowanie na płaszczyznę x y przesunięcie do lewej { return Math.Abs(selObj.minBB.x - otherObj.maxBB.x); } else if (direction.Equals("xyr")) //rzutowanie na płaszczyznę x y przesunięcie do prawej { return Math.Abs(selObj.maxBB.x - otherObj.minBB.x); } else if (direction.Equals("yzu")) //rzutowanie na płaszczyznę y z przesunięcie do góry { return Math.Abs(selObj.maxBB.y - otherObj.minBB.y); } else if (direction.Equals("yzd")) //rzutowanie na płaszczyznę y z przesunięcie do dołu { return Math.Abs(selObj.minBB.y - otherObj.maxBB.y); } else if (direction.Equals("zxb")) //rzutowanie na płaszczyznę z x przesunięcie do tyłu { return Math.Abs(selObj.minBB.z - otherObj.maxBB.z); } else //if(direction.Equals("zxf")) //rzutowanie na płaszczyznę z x przesunięcie do przodu { return Math.Abs(selObj.maxBB.z - otherObj.minBB.z); } }
//, String direction) private static bool BBoxCollisionDetection(BoundingBox b1, BoundingBox b2) { //if (direction.Equals("xyl")) //{ if ((b1.maxBB.x <= b2.minBB.x || b2.maxBB.x <= b1.minBB.x) || (b1.maxBB.y <= b2.minBB.y || b2.maxBB.y <= b1.minBB.y) || (b1.maxBB.z <= b2.minBB.z || b2.maxBB.z <= b1.minBB.z)) return false; return true; //} //else if (direction.Equals("xyr")) //rzutowanie na płaszczyznę x y przesunięcie do prawej //{ // if ((b1.maxBB.y < b2.minBB.y || b2.maxBB.y < b1.minBB.y) || // (b1.maxBB.z < b2.minBB.z || b2.maxBB.z < b1.minBB.z)) // return false; // return true; //} //else if (direction.Equals("yzu")) //rzutowanie na płaszczyznę y z przesunięcie do góry //{ // if ((b1.maxBB.x < b2.minBB.x || b2.maxBB.x < b1.minBB.x) || // (b1.maxBB.z < b2.minBB.z || b2.maxBB.z < b1.minBB.z)) // return false; // return true; //} //else if (direction.Equals("yzd")) //rzutowanie na płaszczyznę y z przesunięcie do dołu //{ // if ((b1.maxBB.x < b2.minBB.x || b2.maxBB.x < b1.minBB.x) || // (b1.maxBB.z < b2.minBB.z || b2.maxBB.z < b1.minBB.z)) // return false; // return true; //} //else if (direction.Equals("zxb")) //rzutowanie na płaszczyznę z x przesunięcie do tyłu //{ // if ((b1.maxBB.x < b2.minBB.x || b2.maxBB.x < b1.minBB.x) || // (b1.maxBB.y < b2.minBB.y || b2.maxBB.y < b1.minBB.y)) // return false; // return true; //} //else //if(direction.Equals("zxf")) //rzutowanie na płaszczyznę z x przesunięcie do przodu //{ // if ((b1.maxBB.x < b2.minBB.x || b2.maxBB.x < b1.minBB.x) || // (b1.maxBB.y < b2.minBB.y || b2.maxBB.y < b1.maxBB.y)) // return false; // return true; //} }
public static void Slide(Scene scene, String direction) { BoundingBox tmpbb; float tmpDistance = float.MaxValue, minDistance = float.MaxValue, minDistanceGlobal = float.MaxValue; bool colisionFound = false; bool canTranslate = true; SetBBoxes(scene); //tworzy strukture bboxów nie zaznaczonych obiektów na dole hierarchii, oraz bboxx sceny if (otherSceneObjBB.Count > 0) { if (direction.Equals("xyl")) //rzutowanie na płaszczyznę x y przesunięcie do lewej { foreach (HierarchyMesh mesh in scene.hierarchy.objects) { if (scene.IsTriangleSelected(mesh.triangles[0])) { tmpbb = new BoundingBox(scene, mesh); Vector3D tmp = new Vector3D(sceneBB.minBB.x, tmpbb.minBB.y, tmpbb.minBB.z); Vector3D tmp2 = new Vector3D(tmpbb.minBB.x, tmpbb.maxBB.y, tmpbb.maxBB.z); requiredSpaceBB = new BoundingBox(tmp, tmp2); foreach (BoundingBox otherbb in otherSceneObjBB) { if (BBoxCollisionDetection(otherbb, requiredSpaceBB))//, slideDir)) { colisionFound = true; tmpDistance = CalculateDistanceEZ(otherbb, tmpbb, direction); if (tmpDistance < minDistance) minDistance = tmpDistance; if (minDistance < minDistanceGlobal) minDistanceGlobal = minDistance; if (BBoxCollisionDetection(otherbb, tmpbb)) //jeśli jakiś obiekt przecina się z dosuwanym na początku operacji- nie można dosuwać canTranslate = false; Console.WriteLine("Kolizja wykryta z obiektem " + otherbb.minBB.x + " " + otherbb.minBB.y + " " + otherbb.minBB.z + " : " + otherbb.maxBB.x + " " + otherbb.maxBB.y + " " + otherbb.maxBB.z); } } } } if (colisionFound && canTranslate) Transformations.Translate(scene, -minDistanceGlobal, 0, 0); else if(colisionFound && !canTranslate) Console.WriteLine("Płaszczyzna BBoxa którą chcemy dosuwać jest wewnątrz BBoxa innego obiektu. Nie można wykonać operacji."); else Console.WriteLine("Brak kolizji"); } else if (direction.Equals("xyr")) //rzutowanie na płaszczyznę x y przesunięcie do prawej { foreach (HierarchyMesh mesh in scene.hierarchy.objects) { if (scene.IsTriangleSelected(mesh.triangles[0])) { tmpbb = new BoundingBox(scene, mesh); Vector3D tmp = new Vector3D(sceneBB.maxBB.x, tmpbb.maxBB.y, tmpbb.maxBB.z); requiredSpaceBB = new BoundingBox(tmpbb.minBB, tmp); foreach (BoundingBox otherbb in otherSceneObjBB) { if (BBoxCollisionDetection(otherbb, requiredSpaceBB))//, slideDir)) { colisionFound = true; tmpDistance = CalculateDistanceEZ(otherbb, tmpbb, direction); if (tmpDistance < minDistance) minDistance = tmpDistance; if (minDistance < minDistanceGlobal) minDistanceGlobal = minDistance; if (BBoxCollisionDetection(otherbb, tmpbb)) //jeśli jakiś obiekt przecina się z dosuwanym na początku operacji- nie można dosuwać canTranslate = false; Console.WriteLine("Kolizja wykryta z obiektem " + otherbb.minBB.x + " " + otherbb.minBB.y + " " + otherbb.minBB.z + " : " + otherbb.maxBB.x + " " + otherbb.maxBB.y + " " + otherbb.maxBB.z); } } } } if (colisionFound) Transformations.Translate(scene, minDistanceGlobal, 0, 0); else if (colisionFound && !canTranslate) Console.WriteLine("Płaszczyzna BBoxa którą chcemy dosuwać jest wewnątrz BBoxa innego obiektu. Nie można wykonać operacji."); else Console.WriteLine("Brak kolizji"); } else if (direction.Equals("yzu")) //rzutowanie na płaszczyznę y z przesunięcie do góry { foreach (HierarchyMesh mesh in scene.hierarchy.objects) { if (scene.IsTriangleSelected(mesh.triangles[0])) { tmpbb = new BoundingBox(scene, mesh); Vector3D tmp = new Vector3D(tmpbb.maxBB.x, sceneBB.maxBB.y, tmpbb.maxBB.z); requiredSpaceBB = new BoundingBox(tmpbb.minBB, tmp); foreach (BoundingBox otherbb in otherSceneObjBB) { if (BBoxCollisionDetection(otherbb, requiredSpaceBB))//, slideDir)) { colisionFound = true; tmpDistance = CalculateDistanceEZ(otherbb, tmpbb, direction); if (tmpDistance < minDistance) minDistance = tmpDistance; if (minDistance < minDistanceGlobal) minDistanceGlobal = minDistance; if (BBoxCollisionDetection(otherbb, tmpbb)) //jeśli jakiś obiekt przecina się z dosuwanym na początku operacji- nie można dosuwać canTranslate = false; Console.WriteLine("Kolizja wykryta z obiektem " + otherbb.minBB.x + " " + otherbb.minBB.y + " " + otherbb.minBB.z + " : " + otherbb.maxBB.x + " " + otherbb.maxBB.y + " " + otherbb.maxBB.z); } } } } if (colisionFound) Transformations.Translate(scene, 0, minDistanceGlobal, 0); else if (colisionFound && !canTranslate) Console.WriteLine("Płaszczyzna BBoxa którą chcemy dosuwać jest wewnątrz BBoxa innego obiektu. Nie można wykonać operacji."); else Console.WriteLine("Brak kolizji"); } else if (direction.Equals("yzd")) //rzutowanie na płaszczyznę y z przesunięcie do dołu { foreach (HierarchyMesh mesh in scene.hierarchy.objects) { if (scene.IsTriangleSelected(mesh.triangles[0])) { tmpbb = new BoundingBox(scene, mesh); Vector3D tmp = new Vector3D(tmpbb.minBB.x, sceneBB.minBB.y, tmpbb.minBB.z); requiredSpaceBB = new BoundingBox(tmp, tmpbb.maxBB); foreach (BoundingBox otherbb in otherSceneObjBB) { if (BBoxCollisionDetection(otherbb, requiredSpaceBB))//, slideDir)) { colisionFound = true; tmpDistance = CalculateDistanceEZ(otherbb, tmpbb, direction); if (tmpDistance < minDistance) minDistance = tmpDistance; if (minDistance < minDistanceGlobal) minDistanceGlobal = minDistance; if (BBoxCollisionDetection(otherbb, tmpbb)) //jeśli jakiś obiekt przecina się z dosuwanym na początku operacji- nie można dosuwać canTranslate = false; Console.WriteLine("Kolizja wykryta z obiektem " + otherbb.minBB.x + " " + otherbb.minBB.y + " " + otherbb.minBB.z + " : " + otherbb.maxBB.x + " " + otherbb.maxBB.y + " " + otherbb.maxBB.z); } } } } if (colisionFound) Transformations.Translate(scene, 0, -minDistanceGlobal, 0); else if (colisionFound && !canTranslate) Console.WriteLine("Płaszczyzna BBoxa którą chcemy dosuwać jest wewnątrz BBoxa innego obiektu. Nie można wykonać operacji."); else Console.WriteLine("Brak kolizji"); } else if (direction.Equals("zxb")) //rzutowanie na płaszczyznę z x przesunięcie do tyłu { foreach (HierarchyMesh mesh in scene.hierarchy.objects) { if (scene.IsTriangleSelected(mesh.triangles[0])) { tmpbb = new BoundingBox(scene, mesh); Vector3D tmp = new Vector3D(tmpbb.minBB.x, tmpbb.minBB.y, sceneBB.minBB.z); requiredSpaceBB = new BoundingBox(tmp, tmpbb.maxBB); foreach (BoundingBox otherbb in otherSceneObjBB) { if (BBoxCollisionDetection(otherbb, requiredSpaceBB))//, slideDir)) { colisionFound = true; tmpDistance = CalculateDistanceEZ(otherbb, tmpbb, direction); if (tmpDistance < minDistance) minDistance = tmpDistance; if (minDistance < minDistanceGlobal) minDistanceGlobal = minDistance; if (BBoxCollisionDetection(otherbb, tmpbb)) //jeśli jakiś obiekt przecina się z dosuwanym na początku operacji- nie można dosuwać canTranslate = false; Console.WriteLine("Kolizja wykryta z obiektem " + otherbb.minBB.x + " " + otherbb.minBB.y + " " + otherbb.minBB.z + " : " + otherbb.maxBB.x + " " + otherbb.maxBB.y + " " + otherbb.maxBB.z); } } } } if (colisionFound) Transformations.Translate(scene, 0, 0, -minDistanceGlobal); else if (colisionFound && !canTranslate) Console.WriteLine("Płaszczyzna BBoxa którą chcemy dosuwać jest wewnątrz BBoxa innego obiektu. Nie można wykonać operacji."); else Console.WriteLine("Brak kolizji"); } else //if(direction.Equals("zxf")) //rzutowanie na płaszczyznę z x przesunięcie do przodu { foreach (HierarchyMesh mesh in scene.hierarchy.objects) { if (scene.IsTriangleSelected(mesh.triangles[0])) { tmpbb = new BoundingBox(scene, mesh); Vector3D tmp = new Vector3D(tmpbb.maxBB.x, tmpbb.maxBB.y, sceneBB.maxBB.z); requiredSpaceBB = new BoundingBox(tmpbb.minBB, tmp); foreach (BoundingBox otherbb in otherSceneObjBB) { if (BBoxCollisionDetection(otherbb, requiredSpaceBB))//, slideDir)) { colisionFound = true; tmpDistance = CalculateDistanceEZ(otherbb, tmpbb, direction); if (tmpDistance < minDistance) minDistance = tmpDistance; if (minDistance < minDistanceGlobal) minDistanceGlobal = minDistance; if (BBoxCollisionDetection(otherbb, tmpbb)) //jeśli jakiś obiekt przecina się z dosuwanym na początku operacji- nie można dosuwać canTranslate = false; Console.WriteLine("Kolizja wykryta z obiektem " + otherbb.minBB.x + " " + otherbb.minBB.y + " " + otherbb.minBB.z + " : " + otherbb.maxBB.x + " " + otherbb.maxBB.y + " " + otherbb.maxBB.z); } } } } if (colisionFound) Transformations.Translate(scene, 0, 0, minDistanceGlobal); else if (colisionFound && !canTranslate) Console.WriteLine("Płaszczyzna BBoxa którą chcemy dosuwać jest wewnątrz BBoxa innego obiektu. Nie można wykonać operacji."); else Console.WriteLine("Brak kolizji"); } } else Console.WriteLine("Brak innych objektów sceny"); Clear(); }
//, String direction) private static bool BBoxCollisionDetection(BoundingBox b1, BoundingBox b2) { if ((b1.maxBB.x < b2.minBB.x || b2.maxBB.x < b1.minBB.x) || (b1.maxBB.y < b2.minBB.y || b2.maxBB.y < b1.minBB.y) || (b1.maxBB.z < b2.minBB.z || b2.maxBB.z < b1.minBB.z)) return false; return true; }