public override void init() { collider = new TgcBoundingCylinder(new Vector3(0, 0, 0), 2, 4); collisionableSphere = new TgcBoundingSphere(new Vector3(0, 0, -6), 3); GuiController.Instance.Modifiers.addVertex2f("size", new Vector2(1, 1), new Vector2(5, 10), new Vector2(2, 5)); GuiController.Instance.Modifiers.addVertex3f("position", new Vector3(-20, -20, -20), new Vector3(20, 20, 20), new Vector3(0, 0, 0)); float angle = FastMath.TWO_PI; GuiController.Instance.Modifiers.addVertex3f("rotation", new Vector3(-angle, -angle, -angle), new Vector3(angle, angle, angle), new Vector3(0, 0, 0)); collider.setRenderColor(Color.LimeGreen); }
public TgcCylinder(Vector3 _center, float _topRadius, float _bottomRadius, float _halfLength) { this.topRadius = _topRadius; this.bottomRadius = _bottomRadius; this.boundingCylinder = new TgcBoundingCylinder(_center, 1, _halfLength); this.color = Color.Red.ToArgb(); this.manualTransformation = Matrix.Identity; this.AutoTransformEnable = true; this.initialize(); }
public Barril(Vector3 position) { this.mesh = Barril.getMesh(); this.mesh.Position = position; this.mesh.Scale = new Vector3(0.6f, 0.7f, 0.6f); this.mesh.AlphaBlendEnable = true; cilindro = new TgcBoundingCylinder(position, 10, 150); this.mesh.updateBoundingBox(); BoundigBox = this.mesh.BoundingBox; explosion = new Explosion(position); humo = new Humo(this.mesh.Position); }
/* Se le pasa una lista de cilindros colisionables, y devuelve el mas cercano */ /* Usado para ver por donde esquivar al arbol y barril */ public TgcBoundingCylinder detectarMasCercano(List<TgcBoundingCylinder> cilindros) { float distMinimo = 0; TgcBoundingCylinder cilindroMasCercano = new TgcBoundingCylinder(new Vector3(0, 0, 0), 0, 0); foreach (TgcBoundingCylinder cilindro in cilindros) { Vector3 puntoCilindro = TgcCollisionUtils.closestPointCylinder(enemigo.enemigoEsfera.Center, cilindro); Vector3 distV = puntoCilindro - enemigo.enemigoEsfera.Center; if (distMinimo > Math.Abs(distV.Length())) { distMinimo = distV.Length(); cilindroMasCercano = cilindro; } } return cilindroMasCercano; }
private void generarArboles(int cantidadArboles) { scene = loader.loadSceneFromFile(GuiController.Instance.ExamplesMediaDir + "MeshCreator\\Meshes\\Vegetacion\\" + tipoArboles[0] + "-TgcScene.xml"); arbol = scene.Meshes[0]; for (int i = 0; i < cantidadArboles; i++) { TgcMesh instancia = arbol.createMeshInstance("arbol"); TgcBoundingCylinder instanciaCilindro = new TgcBoundingCylinder(this.divisionesPiso[i], 15, 100); instancia.Scale = new Vector3(3f, 3f, 3f); instancia.Position = this.divisionesPiso[i]; instancia.AlphaBlendEnable = true; //Agrego efecto y tecnica instancia.Effect = efecto; instancia.Technique = "VientoArbol"; arboles.Add(instancia); colisionables.Add(instanciaCilindro); } }
/// <summary> /// Determina el punto del cilindro mas cercano al punto p. /// </summary> /// <param name="p">Punto</param> /// <param name="cylinder">Cilindro orientable</param> /// <returns>Punto del cilindro que esta mas cerca de p</returns> public static Vector3 closestPointCylinder(Vector3 p, TgcBoundingCylinder cylinder) { //transformamos el punto a coordenadas uvw del cilindro Matrix transformation = cylinder.AntiRotationMatrix; Vector3 uvwPoint = Vector3.TransformCoordinate(p, transformation); //buscamos el punto mas cercano en uvw Vector3 uvwResult = TgcCollisionUtils.closestPointCylinder(uvwPoint, cylinder.Center, cylinder.HalfLength, cylinder.Radius); //transformamos ese resultado a xyz transformation.Invert(); return Vector3.TransformCoordinate(uvwResult, transformation); }
/// <summary> /// Indica si un Cilindro colisiona con una Esfera. /// Solo indica si hay colision o no. No va mas en detalle. /// </summary> /// <param name="sphere">Esfera</param> /// <param name="cylinder">Cilindro orientable</param> /// <returns>True si hay colision</returns> public static bool testSphereCylinder(TgcBoundingSphere sphere, TgcBoundingCylinder cylinder) { //transformamos la posicion de la esfera a coordenadas uvw Vector3 uvwSphereCenter = Vector3.TransformCoordinate(sphere.Center, cylinder.AntiRotationMatrix); //nos fijamos si hay colision en el espacio uvw return TgcCollisionUtils.testSphereCylinder( uvwSphereCenter, sphere.Radius, cylinder.Center, cylinder.HalfLength, cylinder.Radius); }
/// <summary> /// Indica si un rayo colisiona con un cilindro. /// </summary> /// <param name="ray">Rayo</param> /// <param name="cylinder">Cilindro orientado</param> /// <returns>True si el rayo colisiona con el cilindro</returns> public static bool testRayCylinder(TgcRay ray, TgcBoundingCylinder cylinder) { Matrix transformation = cylinder.AntiTransformationMatrix; Vector3 origin = Vector3.TransformCoordinate(ray.Origin, transformation); Vector3 direction = Vector3.TransformNormal(ray.Direction, transformation); return TgcCollisionUtils.testRayCylinder(origin, direction); }
/// <summary> /// Indica si un Punto colisiona con un Cilindro. /// </summary> /// <param name="p">Punto</param> /// <param name="cylinder">Cilindro</param> /// <returns>True si el Punto esta adentro del Cilindro</returns> public static bool testPointCylinder(Vector3 p, TgcBoundingCylinder cylinder) { Vector3 uvwPoint = Vector3.TransformCoordinate(p, cylinder.AntiRotationMatrix); return TgcCollisionUtils.testPointCylinder(uvwPoint, cylinder.Center, cylinder.HalfLength, cylinder.Radius); }
/// <summary> /// Indica si un cilindro colisiona con un segmento. /// El cilindro se especifica con dos puntos centrales "cylinderInit" y "cylinderEnd" que forman una recta y con un radio "radius". /// Si hay colision se devuelve el instante de colision "t" y el punto de colision "q" /// </summary> /// <param name="segmentInit">Punto de inicio del segmento</param> /// <param name="segmentEnd">Punto de fin del segmento</param> /// <param name="cylinderInit">Punto inicial del cilindro</param> /// <param name="cylinderEnd">Punto final del cilindro</param> /// <param name="radius">Radio del cilindro</param> /// <param name="t">Instante de colision</param> /// <param name="q">Punto de colision</param> /// <returns>True si hay colision</returns> public static bool intersectSegmentCylinder(Vector3 segmentInit, Vector3 segmentEnd, TgcBoundingCylinder cylinder, out float t, out Vector3 q) { Vector3 hh = cylinder.HalfHeight; Vector3 cylinderInit = cylinder.Center - hh; Vector3 cylinderEnd = cylinder.Center + hh; float radius = cylinder.Radius; t = -1; q = Vector3.Empty; Vector3 d = cylinderEnd - cylinderInit, m = segmentInit - cylinderInit, n = segmentEnd - segmentInit; float md = Vector3.Dot(m, d); float nd = Vector3.Dot(n, d); float dd = Vector3.Dot(d, d); // Test if segment fully outside either endcap of cylinder if (md < 0.0f && md + nd < 0.0f) return false; // Segment outside ’p’ side of cylinder if (md > dd && md + nd > dd) return false; // Segment outside ’q’ side of cylinder float nn = Vector3.Dot(n, n); float mn = Vector3.Dot(m, n); float a = dd * nn - nd * nd; float k = Vector3.Dot(m, m) - radius * radius; float c = dd * k - md * md; if (FastMath.Abs(a) < float.Epsilon) { // Segment runs parallel to cylinder axis if (c > 0.0f) return false; // 'a' and thus the segment lie outside cylinder // Now known that segment intersects cylinder; figure out how it intersects if (md < 0.0f) t = -mn / nn; // Intersect segment against 'p' endcap else if (md > dd) t = (nd - mn) / nn; // Intersect segment against ’q’ endcap else t = 0.0f; // ’a’ lies inside cylinder q = segmentInit + t * n; return true; } float b = dd * mn - nd * md; float discr = b * b - a * c; if (discr < 0.0f) return false; // No real roots; no intersection t = (-b - FastMath.Sqrt(discr)) / a; if (t < 0.0f || t > 1.0f) return false; // Intersection lies outside segment if (md + t * nd < 0.0f) { // Intersection outside cylinder on 'p' side if (nd <= 0.0f) return false; // Segment pointing away from endcap t = -md / nd; // Keep intersection if Dot(S(t) - p, S(t) - p) <= r^2 return k + t * (2.0f * mn + t * nn) <= 0.0f; } else if (md + t * nd > dd) { // Intersection outside cylinder on 'q' side if (nd >= 0.0f) return false; // Segment pointing away from endcap t = (dd - md) / nd; // Keep intersection if Dot(S(t) - q, S(t) - q) <= r^2 return k + dd - 2.0f * md + t * (2.0f * (mn - nd) + t * nn) <= 0.0f; } // Segment intersects cylinder between the endcaps; t is correct q = segmentInit + t * n; return true; }