public override void init() { Device d3dDevice = GuiController.Instance.D3dDevice; //Cargar modelo TgcSceneLoader loader = new TgcSceneLoader(); TgcScene scene = loader.loadSceneFromFile( GuiController.Instance.ExamplesMediaDir + "MeshCreator\\Meshes\\Vehiculos\\StarWars-ATST\\StarWars-ATST-TgcScene.xml"); mesh = scene.Meshes[0]; //Computar OBB a partir del AABB del mesh. Inicialmente genera el mismo volumen que el AABB, pero luego te permite rotarlo (cosa que el AABB no puede) obb = TgcObb.computeFromAABB(mesh.BoundingBox); //Otra alternativa es computar OBB a partir de sus vertices. Esto genera un OBB lo mas apretado posible pero es una operacion costosa //obb = TgcObb.computeFromPoints(mesh.getVertexPositions()); //Alejar camara rotacional segun tamaño del BoundingBox del objeto GuiController.Instance.RotCamera.targetObject(mesh.BoundingBox); //Modifier para poder rotar y mover el mesh GuiController.Instance.Modifiers.addFloat("rotation", 0, 360, 0); GuiController.Instance.Modifiers.addVertex3f("position", new Vector3(0, 0, 0), new Vector3(50, 50, 50), new Vector3(0, 0, 0)); }
public ObstaculoRigido(string _pathMesh, Vector3 _posicion, Vector3 _escala ) { this.mesh = MeshUtils.loadMesh(_pathMesh); this.mesh.Position = _posicion; this.mesh.Scale = _escala; this.obb = TgcObb.computeFromAABB(this.mesh.BoundingBox); }
public Checkpoint(float x, float z, float y, TgcMesh _modelo) { _modelo.Position = new Vector3(x, y, z); this.modelo = _modelo; this.modelo.Scale = new Vector3(5, 5, 5); this.obb = TgcObb.computeFromAABB(this.modelo.BoundingBox); }
public override void init() { Microsoft.DirectX.Direct3D.Device d3dDevice = GuiController.Instance.D3dDevice; //Cuerpo principal que se controla con el teclado box = TgcBox.fromSize(new Vector3(0, 10, 0), new Vector3(10, 10, 10), Color.Blue); //triangulo triangle = new CustomVertex.PositionColored[3]; triangle[0] = new CustomVertex.PositionColored(-100, 0, 0, Color.Red.ToArgb()); triangle[1] = new CustomVertex.PositionColored(0, 0, 50, Color.Green.ToArgb()); triangle[2] = new CustomVertex.PositionColored(0, 100, 0, Color.Blue.ToArgb()); triagleAABB = TgcBoundingBox.computeFromPoints(new Vector3[] { triangle[0].Position, triangle[1].Position, triangle[2].Position }); //box2 box2 = TgcBox.fromSize(new Vector3(-50, 10, -20), new Vector3(15, 15, 15), Color.Violet); //sphere sphere = new TgcBoundingSphere(new Vector3(30, 20, -20), 15); //OBB: computar OBB a partir del AABB del mesh. TgcSceneLoader loader = new TgcSceneLoader(); TgcMesh meshObb = loader.loadSceneFromFile(GuiController.Instance.ExamplesMediaDir + "MeshCreator\\Meshes\\Vehiculos\\StarWars-ATST\\StarWars-ATST-TgcScene.xml").Meshes[0]; obb = TgcObb.computeFromAABB(meshObb.BoundingBox); meshObb.dispose(); obb.move(new Vector3(100, 0, 30)); obb.setRotation(new Vector3(0, FastMath.PI / 4, 0)); //Configurar camara en Tercer Persona GuiController.Instance.ThirdPersonCamera.Enable = true; GuiController.Instance.ThirdPersonCamera.setCamera(box.Position, 30, -75); }
/// <summary> /// Convertir a clase /// </summary> public TgcObb toClass() { TgcObb obb = new TgcObb(); obb.center = center; obb.orientation = orientation; obb.extents = extents; return(obb); }
public override void init() { Device d3dDevice = GuiController.Instance.D3dDevice; obb = new TgcObb(); generateObb(); generate = false; GuiController.Instance.Modifiers.addButton("generate", "generate", new EventHandler(this.random_clic)); }
// Constructor public ObstaculoRigido(float _x, float _z, float _y, float ancho, float alto, float largo, string textura) { TgcBox box = TgcBox.fromSize( new Vector3(_x, _z, _y), //posicion new Vector3(ancho, alto, largo), //tamaño TgcTexture.createTexture(textura)); //Computar OBB a partir del AABB del mesh. Inicialmente genera el mismo volumen que el AABB, pero luego te permite rotarlo (cosa que el AABB no puede) this.obb = TgcObb.computeFromAABB(box.BoundingBox); this.mesh = box.toMesh("caja"); }
private void _HollowObbCollider(TgcObb obb, Vector3 translation, Vector3 minCornerScale, Vector3 maxCornerScale) { var e = obb.Extents; var o = obb.Orientation; var min = e.MemberwiseMult(minCornerScale); if (min.X > 0) _AddCollider(o, new Vector3(min.X, e.Y, e.Z), (e.X - min.X) * Vector3Extension.Left + translation); if (min.Y > 0) _AddCollider(o, new Vector3(e.X, min.Y, e.Z), (e.Y - min.Y) * Vector3Extension.Bottom + translation); if (min.Z > 0) _AddCollider(o, new Vector3(e.X, e.Y, min.Z), (e.Z - min.Z) * Vector3Extension.Back + translation); var max = e.MemberwiseMult(maxCornerScale); if (max.X > 0) _AddCollider(o, new Vector3(max.X, e.Y, e.Z), (e.X - max.X) * Vector3Extension.Right + translation); if (max.Y > 0) _AddCollider(o, new Vector3(e.X, max.Y, e.Z), (e.Y - max.Y) * Vector3Extension.Top + translation); if (max.Z > 0) _AddCollider(o, new Vector3(e.X, e.Y, max.Z), (e.Z - max.Z) * Vector3Extension.Front + translation); }
public Auto(string pathMeshAuto, string _nombre, Vector3 _posicionInicial, float _velocidadMaxima, float _velocidadRotacion, float _aceleracion, float _masa, Vector3 _escala, Vector3 _rotacionInicial) { this.nombre = _nombre; this.posicionInicial = _posicionInicial; this.mesh = MeshUtils.loadMesh(pathMeshAuto); // sceneAuto = loadMesh(pathMeshAuto); //this.mesh = sceneAuto.Meshes[0]; this.mesh.Scale = _escala; this.rotacionInicial = _rotacionInicial; this.backupVertices(); this.velocidadActual = 0; this.velocidadMaxima = _velocidadMaxima; this.velocidadMaximaInicial = _velocidadMaxima; this.velocidadRotacion = _velocidadRotacion; this.velocidadRotacionOriginal = _velocidadRotacion; this.masa = _masa; this.aceleracion = _aceleracion; //Computar OBB a partir del AABB del mesh. Inicialmente genera el mismo volumen que el AABB, pero luego te permite rotarlo (cosa que el AABB no puede) this.obb = TgcObb.computeFromAABB(this.mesh.BoundingBox); this.puntoChoque = this.obb.Center; this.direccion = new TgcArrow(); direccion.PStart = this.obb.Center; Vector3 rotacion = this.mesh.Rotation; direccion.PEnd = this.obb.Center + Vector3.Multiply(new Vector3(rotacion.X, rotacion.Y, rotacion.Z), 500f); //// acá defino un mesh auxiliar para probar con el Debug mode string sphere = GuiController.Instance.ExamplesMediaDir + "ModelosTgc\\Sphere\\Sphere-TgcScene.xml"; TgcSceneLoader loader = new TgcSceneLoader(); moon = loader.loadSceneFromFile(sphere).Meshes[0]; moon.Scale = new Vector3(0.6f, 0.6f, 0.6f); //le asignamos una cantidad de chispas cada vez que choca for (int i = 0; i < cantidadDeChispas; i++) { chispas.Add(new Chispa()); } //... y un poco de sonido a los choques this.sonidoChoque = new Sonido(Shared.mediaPath + "\\sonidos\\choque.wav"); }
public static void updateObbFromSegment(TgcObb obb, Vector3 a, Vector3 b, float thickness) { Vector3 lineDiff = b - a; float lineLength = lineDiff.Length(); Vector3 lineVec = Vector3.Normalize(lineDiff); //Obtener angulo y vector de rotacion Vector3 upVec = new Vector3(0, 1, 0); float angle = FastMath.Acos(Vector3.Dot(upVec, lineVec)); Vector3 axisRotation = Vector3.Cross(upVec, lineVec); axisRotation.Normalize(); //Obtener matriz de rotacion para este eje y angulo Matrix rotM = Matrix.RotationAxis(axisRotation, angle); //Actualizar orientacion de OBB en base a matriz de rotacion obb.Orientation[0] = new Vector3(rotM.M11, rotM.M12, rotM.M13); obb.Orientation[1] = new Vector3(rotM.M21, rotM.M22, rotM.M23); obb.Orientation[2] = new Vector3(rotM.M31, rotM.M32, rotM.M33); //Actualizar extent de OBB segun el thickness del segmento obb.Extents = new Vector3(thickness, lineLength / 2, thickness); //Actualizar centro del OBB segun centro del segmento obb.Center = a + Vector3.Scale(lineDiff, 0.5f); //Regenerar OBB obb.updateValues(); }
public HollowObbCollider(TgcObb obb, Vector3 translation, Vector3 minCornerScale, Vector3 maxCornerScale) { _HollowObbCollider(obb, translation, minCornerScale, maxCornerScale); }
/// <summary> /// Crear nube de puntos aleatorios y luego computar el mejor OBB que los ajusta /// </summary> private void generateObb() { obb.dispose(); obb = null; //Crear nube ed puntos int COUNT = 10; float MIN_RAND = -20f; float MAX_RAND = 20f; points = new Vector3[COUNT]; for (int i = 0; i < points.Length; i++) { float x = MIN_RAND + (float)rand.NextDouble() * (MAX_RAND - MIN_RAND); float y = MIN_RAND + (float)rand.NextDouble() * (MAX_RAND - MIN_RAND); float z = MIN_RAND + (float)rand.NextDouble() * (MAX_RAND - MIN_RAND); points[i] = new Vector3(x, y, z); } //Computar mejor OBB obb = TgcObb.computeFromPoints(points); if (vertices != null) { for (int i = 0; i < vertices.Length; i++) { vertices[i].dispose(); } } vertices = new TgcBox[points.Length]; for (int i = 0; i < vertices.Length; i++) { vertices[i] = TgcBox.fromSize(points[i], new Vector3(1, 1, 1), Color.White); } }
/// <summary> /// Testear si hay olision entre dos OBB /// </summary> /// <param name="a">Primer OBB</param> /// <param name="b">Segundo OBB</param> /// <returns>True si hay colision</returns> public static bool testObbObb2(TgcObb.OBBStruct a, TgcObb.OBBStruct b) { float ra, rb; float[,] R = new float[3, 3]; float[,] AbsR = new float[3, 3]; float[] ae = toArray(a.extents); float[] be = toArray(b.extents); // Compute rotation matrix expressing b in a’s coordinate frame for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) R[i, j] = Vector3.Dot(a.orientation[i], b.orientation[j]); // Compute translation vector t Vector3 tVec = b.center - a.center; // Bring translation into a’s coordinate frame float[] t = new float[3]; t[0] = Vector3.Dot(tVec, a.orientation[0]); t[1] = Vector3.Dot(tVec, a.orientation[1]); t[2] = Vector3.Dot(tVec, a.orientation[2]); // Compute common subexpressions. Add in an epsilon term to // counteract arithmetic errors when two edges are parallel and // their cross product is (near) null (see text for details) for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) AbsR[i, j] = FastMath.Abs(R[i, j]) + float.Epsilon; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { ae[i] = FastMath.Abs(ae[i]); be[i] = FastMath.Abs(be[i]); } } // Test axes L = A0, L = A1, L = A2 for (int i = 0; i < 3; i++) { ra = ae[i]; rb = be[0] * AbsR[i, 0] + be[1] * AbsR[i, 1] + be[2] * AbsR[i, 2]; if (FastMath.Abs(t[i]) > FastMath.Abs(ra + rb)) return false; } // Test axes L = B0, L = B1, L = B2 for (int i = 0; i < 3; i++) { ra = ae[0] * AbsR[0, i] + ae[1] * AbsR[1, i] + ae[2] * AbsR[2, i]; rb = be[i]; if (FastMath.Abs(t[0] * R[0, i] + t[1] * R[1, i] + t[2] * R[2, i]) > FastMath.Abs(ra + rb)) return false; } // Test axis L = A0 x B0 ra = ae[1] * AbsR[2, 0] + ae[2] * AbsR[1, 0]; rb = be[1] * AbsR[0, 2] + be[2] * AbsR[0, 1]; if (FastMath.Abs(t[2] * R[1, 0] - t[1] * R[2, 0]) > FastMath.Abs(ra + rb)) return false; // Test axis L = A0 x B1 ra = ae[1] * AbsR[2, 1] + ae[2] * AbsR[1, 1]; rb = be[0] * AbsR[0, 2] + be[2] * AbsR[0, 0]; if (FastMath.Abs(t[2] * R[1, 1] - t[1] * R[2, 1]) > FastMath.Abs(ra + rb)) return false; // Test axis L = A0 x B2 ra = ae[1] * AbsR[2, 2] + ae[2] * AbsR[1, 2]; rb = be[0] * AbsR[0, 1] + be[1] * AbsR[0, 0]; if (FastMath.Abs(t[2] * R[1, 2] - t[1] * R[2, 2]) > FastMath.Abs(ra + rb)) return false; // Test axis L = A1 x B0 ra = ae[0] * AbsR[2, 0] + ae[2] * AbsR[0, 0]; rb = be[1] * AbsR[1, 2] + be[2] * AbsR[1, 1]; if (FastMath.Abs(t[0] * R[2, 0] - t[2] * R[0, 0]) > FastMath.Abs(ra + rb)) return false; // Test axis L = A1 x B1 ra = ae[0] * AbsR[2, 1] + ae[2] * AbsR[0, 1]; rb = be[0] * AbsR[1, 2] + be[2] * AbsR[1, 0]; if (FastMath.Abs(t[0] * R[2, 1] - t[2] * R[0, 1]) > FastMath.Abs(ra + rb)) return false; // Test axis L = A1 x B2 ra = ae[0] * AbsR[2, 2] + ae[2] * AbsR[0, 2]; rb = be[0] * AbsR[1, 1] + be[1] * AbsR[1, 0]; if (FastMath.Abs(t[0] * R[2, 2] - t[2] * R[0, 2]) > FastMath.Abs(ra + rb)) return false; // Test axis L = A2 x B0 ra = ae[0] * AbsR[1, 0] + ae[1] * AbsR[0, 0]; rb = be[1] * AbsR[2, 2] + be[2] * AbsR[2, 1]; if (FastMath.Abs(t[1] * R[0, 0] - t[0] * R[1, 0]) > FastMath.Abs(ra + rb)) return false; // Test axis L = A2 x B1 ra = ae[0] * AbsR[1, 1] + ae[1] * AbsR[0, 1]; rb = be[0] * AbsR[2, 2] + be[2] * AbsR[2, 0]; if (FastMath.Abs(t[1] * R[0, 1] - t[0] * R[1, 1]) > FastMath.Abs(ra + rb)) return false; // Test axis L = A2 x B2 ra = ae[0] * AbsR[1, 2] + ae[1] * AbsR[0, 2]; rb = be[0] * AbsR[2, 1] + be[1] * AbsR[2, 0]; if (FastMath.Abs(t[1] * R[0, 2] - t[0] * R[1, 2]) > FastMath.Abs(ra + rb)) return false; // Since no separating axis is found, the OBBs must be intersecting return true; }
public ObbTranslatedCollider(TgcObb obb, Vector3 translation) : base(obb) { _TranslationCurrent = _Translation = translation; }
/// <summary> /// Crea un array con los 8 vertices del OBB /// </summary> private Vector3[] computeCorners(TgcObb obb) { Vector3[] corners = new Vector3[8]; Vector3 eX = obb.Extents.X * obb.Orientation[0]; Vector3 eY = obb.Extents.Y * obb.Orientation[1]; Vector3 eZ = obb.Extents.Z * obb.Orientation[2]; corners[0] = obb.Center - eX - eY - eZ; corners[1] = obb.Center - eX - eY + eZ; corners[2] = obb.Center - eX + eY - eZ; corners[3] = obb.Center - eX + eY + eZ; corners[4] = obb.Center + eX - eY - eZ; corners[5] = obb.Center + eX - eY + eZ; corners[6] = obb.Center + eX + eY - eZ; corners[7] = obb.Center + eX + eY + eZ; return corners; }
/// <summary> /// Calcular OBB a partir de un conjunto de puntos. /// Busca por fuerza bruta el mejor OBB en la mejor orientación que se ajusta a esos puntos. /// Es un calculo costoso. /// </summary> /// <param name="points">puntos</param> /// <returns>OBB calculado</returns> public static TgcObb computeFromPoints(Vector3[] points) { return(TgcObb.computeFromPointsRecursive(points, new Vector3(0, 0, 0), new Vector3(360, 360, 360), 10f).toClass()); }
public static Vector3 ToObbSpace(this Vector3 p, TgcObb obb) { var t = p - obb.Center; var o = obb.Orientation; return new Vector3(Vector3.Dot(t, o[0]), Vector3.Dot(t, o[1]), Vector3.Dot(t, o[2])); }
public static Vector3 FromObbSpace(this Vector3 p, TgcObb obb) { var o = obb.Orientation; return obb.Center + p.X * o[0] + p.Y * o[1] + p.Z * o[2]; }
public HollowObbCollider(TgcObb obb, Vector3 cornerScale) : this(obb, Vector3.Empty, cornerScale, cornerScale) { }
public ObstaculoRigido(TgcMesh _mesh) { this.obb = TgcObb.computeFromAABB(_mesh.BoundingBox); this.mesh = _mesh; }
public ObbTranslatedUnRotatedCollider(TgcObb obb, Vector3 translation) : base(obb, translation) { }
/// <summary> /// Convertir a clase /// </summary> public TgcObb toClass() { TgcObb obb = new TgcObb(); obb.center = center; obb.orientation = orientation; obb.extents = extents; return obb; }
/// <summary> /// Interseccion Ray-OBB. /// Devuelve true y el punto q de colision si hay interseccion. /// </summary> public static bool intersectRayObb(TgcRay ray, TgcObb obb, out Vector3 q) { //Transformar Ray a OBB-space Vector3 a = ray.Origin; Vector3 b = ray.Origin + ray.Direction; a = obb.toObbSpace(a); b = obb.toObbSpace(b); TgcRay.RayStruct ray2 = new TgcRay.RayStruct(); ray2.origin = a; ray2.direction = Vector3.Normalize(b - a); //Crear AABB que representa al OBB Vector3 min = -obb.Extents; Vector3 max = obb.Extents; TgcBoundingBox.AABBStruct aabb = new TgcBoundingBox.AABBStruct(); aabb.min = min; aabb.max = max; //Hacer interseccion Ray-AABB if (TgcCollisionUtils.intersectRayAABB(ray2, aabb, out q)) { //Pasar q a World-Space q = obb.toWorldSpace(q); return true; } return false; }
/// <summary> /// Generar OBB a partir de AABB /// </summary> /// <param name="aabb">BoundingBox</param> /// <returns>OBB generado</returns> public static TgcObb computeFromAABB(TgcBoundingBox aabb) { return(TgcObb.computeFromAABB(aabb.toStruct()).toClass()); }
/// <summary> /// Testear si hay olision entre un OBB y un AABB /// </summary> /// <param name="a">OBB</param> /// <param name="b">AABB</param> /// <returns>True si hay colision</returns> public static bool testObbAABB(TgcObb obb, TgcBoundingBox aabb) { return TgcCollisionUtils.testObbAABB(obb.toStruct(), aabb.toStruct()); }
public ObbCollider(TgcObb obb) { Obb = obb; _Extents = obb.Extents; obb.setRenderColor(DefaultColiderColor); }
/// <summary> /// Testear si hay olision entre dos OBB /// </summary> /// <param name="a">Primer OBB</param> /// <param name="b">Segundo OBB</param> /// <returns>True si hay colision</returns> public static bool testObbObb(TgcObb a, TgcObb b) { return TgcCollisionUtils.testObbObb(a.toStruct(), b.toStruct()); }
/// <summary> /// Testear si hay olision entre dos OBB /// </summary> /// <param name="a">Primer OBB</param> /// <param name="b">Segundo OBB</param> /// <returns>True si hay colision</returns> public static bool testObbObb2(TgcObb a, TgcObb b) { return Colisiones.testObbObb2(a.toStruct(), b.toStruct()); }
/// <summary> /// Indica si un BoundingSphere colisiona con un BoundingBox. /// </summary> /// <param name="sphere">BoundingSphere</param> /// <param name="aabb">BoundingBox</param> /// <returns>True si hay colisión</returns> public static bool testSphereOBB(TgcBoundingSphere sphere, TgcObb obb) { return TgcCollisionUtils.testSphereOBB(sphere.toStruct(), obb.toStruct()); }
public void reiniciar() { Vector3 posicionInicio = posicionInicial; this.velocidadActual = 0; this.velocidadRotacion = velocidadRotacionOriginal; restaurarVertices(); this.velocidadMaxima = this.velocidadMaximaInicial; this.mesh.Rotation = rotacionInicial; this.mesh.Position = posicionInicio; this.obb = TgcObb.computeFromAABB(this.mesh.BoundingBox); }
/// <summary> /// Indica si un BoundingSphere colisiona con un BoundingBox. /// </summary> /// <param name="sphere">BoundingSphere</param> /// <param name="aabb">BoundingBox</param> /// <returns>True si hay colisión</returns> public static bool testSphereOBB(TgcBoundingSphere.SphereStruct sphere, TgcObb.OBBStruct obb) { //Transformar esfera a OBB-Space TgcBoundingSphere.SphereStruct sphere2 = new TgcBoundingSphere.SphereStruct(); sphere2.center = obb.toObbSpace(sphere.center); sphere2.radius = sphere.radius; //Crear AABB que representa al OBB Vector3 min = -obb.extents; Vector3 max = obb.extents; TgcBoundingBox.AABBStruct aabb = new TgcBoundingBox.AABBStruct(); aabb.min = min; aabb.max = max; return TgcCollisionUtils.testSphereAABB(sphere2, aabb); }
/// <summary> /// Testear si hay olision entre un OBB y un AABB /// </summary> /// <param name="a">OBB</param> /// <param name="b">AABB</param> /// <returns>True si hay colision</returns> public static bool testObbAABB(TgcObb.OBBStruct obb, TgcBoundingBox.AABBStruct aabb) { //Crear un OBB que represente al AABB TgcObb.OBBStruct obb2 = TgcObb.computeFromAABB(aabb); //Hacer colision obb-obb return TgcCollisionUtils.testObbObb(obb, obb2); }
public HollowObbCollider(TgcObb obb, Vector3 translation, Vector3 cornerScale) : this(obb, translation, cornerScale, cornerScale) { }