public static Vector3[] computeCorners(Auto auto) { TgcObb obbAuto = auto.obb; Vector3[] corners = new Vector3[8]; Vector3 extents; Vector3[] orientation = obbAuto.Orientation; Vector3 center = obbAuto.Center; extents = auto.mesh.BoundingBox.calculateAxisRadius(); extents = TgcVectorUtils.abs(extents); Vector3 eX = extents.X * orientation[0]; Vector3 eY = extents.Y * orientation[1]; Vector3 eZ = extents.Z * orientation[2]; corners[0] = center - eX - eY - eZ; corners[1] = center - eX - eY + eZ; corners[2] = center - eX + eY - eZ; corners[3] = center - eX + eY + eZ; corners[4] = center + eX - eY - eZ; corners[5] = center + eX - eY + eZ; corners[6] = center + eX + eY - eZ; corners[7] = center + eX + eY + eZ; return(corners); }
public void MoverHaciaObjetivo(float tiempoRenderizado, Vector3 posicionObjetivo) { if (this.Modelo.Enabled) { //Resto los dos vectores para hallar el vector distancia Vector3 Distancia = Vector3.Subtract(posicionObjetivo, this.Modelo.Position); //Otro vector, con valores absolutos para hallar la componente maxima Vector3 DistanciaAbs = TgcVectorUtils.abs(Distancia); //Calculo matriz de rotacion Vector3 DireccionObjetivo = Vector3.Normalize(posicionObjetivo - this.Modelo.Position); float angulo = FastMath.Acos(Vector3.Dot(RotacionOriginal, DireccionObjetivo)); Vector3 axisRotation = Vector3.Cross(this.Modelo.Rotation, DireccionObjetivo); MatrizRotacion = Matrix.RotationAxis(axisRotation, angulo); float cantidadDeMovimiento = this.VelocidadMovimiento * tiempoRenderizado; float giro = this.Modelo.Rotation.Y - angulo; if (giro < -0.1) { this.Modelo.rotateY(Geometry.DegreeToRadian(-giro * 100 * tiempoRenderizado)); return; } else if (giro > 0.1) { this.Modelo.rotateY(Geometry.DegreeToRadian(-giro * 100 * tiempoRenderizado)); return; } if (DistanciaAbs.X + DistanciaAbs.Y + DistanciaAbs.Z > 700f) { //Hallo la componente de mayor valor y me muevo en esa direccion. VER SENTIDO. if (DistanciaAbs.X >= DistanciaAbs.Y) { if (DistanciaAbs.X >= DistanciaAbs.Z) { // MOVER EN X if (Distancia.X > cantidadDeMovimiento) { this.Modelo.move(cantidadDeMovimiento, 0, 0); } else { this.Modelo.move(cantidadDeMovimiento * -1, 0, 0); } } else { // MOVER EN Z if (Distancia.Z > 0) { this.Modelo.move(0, 0, cantidadDeMovimiento); } else { this.Modelo.move(0, 0, cantidadDeMovimiento * -1); } } } else { if (DistanciaAbs.Y >= DistanciaAbs.Z) { // MOVER EN Y if (Distancia.Y > 0) { this.Modelo.move(0, cantidadDeMovimiento, 0); } else { this.Modelo.move(0, cantidadDeMovimiento * -1, 0); } } else { // MOVER EN Z if (Distancia.Z > 0) { this.Modelo.move(0, 0, cantidadDeMovimiento); } else { this.Modelo.move(0, 0, cantidadDeMovimiento * -1); } } } } else { //Disparar. Tambien deberia rotar para que el disparo vaya bien if (TiempoParado == 0 || TiempoParado >= TiempoRecarga) { Disparo disparo = new Disparo(this.Modelo, MatrizRotacion); Disparos.Add(disparo); TiempoParado = 0f; } TiempoParado = TiempoParado + tiempoRenderizado * 4; } } }
/// <summary> /// Calcular OBB a partir de un conjunto de puntos. /// Prueba todas las orientaciones entre initValues y endValues, saltando de angulo en cada intervalo segun step /// Continua recursivamente hasta llegar a un step menor a 0.01f /// </summary> /// <returns></returns> private static OBBStruct computeFromPointsRecursive(Vector3[] points, Vector3 initValues, Vector3 endValues, float step) { var minObb = new OBBStruct(); var minVolume = float.MaxValue; var minInitValues = Vector3.Empty; var minEndValues = Vector3.Empty; var transformedPoints = new Vector3[points.Length]; float x, y, z; x = initValues.X; while (x <= endValues.X) { y = initValues.Y; var rotX = FastMath.ToRad(x); while (y <= endValues.Y) { z = initValues.Z; var rotY = FastMath.ToRad(y); while (z <= endValues.Z) { //Matriz de rotacion var rotZ = FastMath.ToRad(z); var rotM = Matrix.RotationYawPitchRoll(rotY, rotX, rotZ); Vector3[] orientation = { new Vector3(rotM.M11, rotM.M12, rotM.M13), new Vector3(rotM.M21, rotM.M22, rotM.M23), new Vector3(rotM.M31, rotM.M32, rotM.M33) }; //Transformar todos los puntos a OBB-space for (var i = 0; i < transformedPoints.Length; i++) { transformedPoints[i].X = Vector3.Dot(points[i], orientation[0]); transformedPoints[i].Y = Vector3.Dot(points[i], orientation[1]); transformedPoints[i].Z = Vector3.Dot(points[i], orientation[2]); } //Obtener el AABB de todos los puntos transformados var aabb = TgcBoundingBox.computeFromPoints(transformedPoints); //Calcular volumen del AABB var extents = aabb.calculateAxisRadius(); extents = TgcVectorUtils.abs(extents); var volume = extents.X * 2 * extents.Y * 2 * extents.Z * 2; //Buscar menor volumen if (volume < minVolume) { minVolume = volume; minInitValues = new Vector3(x, y, z); minEndValues = new Vector3(x + step, y + step, z + step); //Volver centro del AABB a World-space var center = aabb.calculateBoxCenter(); center = center.X * orientation[0] + center.Y * orientation[1] + center.Z * orientation[2]; //Crear OBB minObb.center = center; minObb.extents = extents; minObb.orientation = orientation; } z += step; } y += step; } x += step; } //Recursividad en mejor intervalo encontrado if (step > 0.01f) { minObb = computeFromPointsRecursive(points, minInitValues, minEndValues, step / 10f); } return(minObb); }