public void init()
        {
            Device device = GuiController.Instance.D3dDevice;
                sphere = new TgcBoundingSphere(posicion, EXPLOSION_RADIUS);

                sound = new TgcStaticSound();
                time = 0;

                int width = GuiController.Instance.Panel3d.Width;
                int height = GuiController.Instance.Panel3d.Height;

                int cantExplosion = 20;
                float particleTime = 1f, sizeMax = 2000f, expSpeed = 1f, expSizeSpeed = 20f; ;
                float expUpdateTime = 0;

                //Creo el emisor de explosion
                emisorExplosion = new ExplosionEmitter(cantExplosion, posicion, new Vector3(expSpeed, expSpeed, expSpeed), new Vector3(0.00f, 0.00f, 0.00f), 500f, sizeMax, particleTime, Color.White, 150, 0f, expUpdateTime, GameManager.Instance.random.Next(0, 1000), expSizeSpeed, 2);
                emisorExplosion.Init();

                int cantidad = 20;
                Vector3 origen1 = posicion;
                float speed = 5f;
                float divergence = 7f;
                Vector3 velocidad = new Vector3(divergence, speed, divergence);
                Vector3 aceleracion = new Vector3(0, 0, 0);
                float min = 500f, max = 1000f, tiempoVida_Particula = 1f;
                int alpha = 150;
                float spawn = 0.01f;
                float sizeSpeed = 1000f;
                float updateTime = 0.02f;

                //Creo los emisores de humo
                emisorHumo = new SmokeEmitter(cantidad, origen1, velocidad, aceleracion, min, max, tiempoVida_Particula, Color.DarkGray, alpha, spawn, updateTime, sizeSpeed);
                emisorHumo.Init();
        }
        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);
        }
示例#3
0
        public Enemigo(Vector3 posicionInicial, EscenarioManager escenarioManager)
        {
            this.huellas = new HuellasManager(10);
            this.teMataron = false;

            this.escenarioManager = escenarioManager;

            this.enemigoAmigacion = Enemigo.getAnimacion();

            this.mesh = Enemigo.getMesh();

            sangre = new TgcCylinder(posicionInicial, 0, 20, 0);
            sangre.Color = Color.Red;

            sangre.updateValues();

            enemigoEsfera = new TgcBoundingSphere(new Vector3(posicionInicial.X, 30, posicionInicial.Z), 10);

            Random rnd = new Random();
            mesh.Position = posicionInicial;

            mesh.Scale = new Vector3(1f, 1f, 1f);
            mesh.AutoTransformEnable = true;

            this.cabezaBounding = new TgcBoundingSphere(new Vector3(posicionInicial.X, posicionInicial.Y + 20, posicionInicial.Z), 20);

            this.setEstado(new EnemigoQuieto(this));
        }
示例#4
0
 public bool isAnyCollidingWith(TgcBoundingSphere tankSphere)
 {
     foreach (var tree in trees) {
         if (TgcCollisionUtils.testSphereSphere(tree.boundingSphere, tankSphere))
             return true;
     }
     return false;
 }
        public override void init()
        {
            collider = new TgcFixedYBoundingCylinder(new Vector3(0, 0, 0), 3, 3);
            collisionableSphere = new TgcBoundingSphere(new Vector3(-6, 0, 0), 3);
            collisionableAABB = new TgcBoundingBox(new Vector3(4, 0, -1), new Vector3(6, 2, 1));
            collisionableCylinder = new TgcFixedYBoundingCylinder(new Vector3(0, 0, -6), 2, 2);

            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));

            collider.setRenderColor(Color.LimeGreen);
        }
        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 SphereTriangleCollisionManager()
 {
     gravityEnabled = true;
     gravityForce = new Vector3(0, -10, 0);
     slideFactor = 1.3f;
     lastCollisionNormal = Vector3.Empty;
     movementSphere = new TgcBoundingSphere();
     objetosCandidatos = new List<Collider>();
     lastCollider = null;
     onGroundMinDotValue = 0.8f;
     collision = false;
     lastMovementVector = Vector3.Empty;
 }
        /// <summary>
        /// Mover BoundingSphere con detección de colisiones, sliding y gravedad.
        /// Se actualiza la posición del centrodel BoundingSphere.
        /// </summary>
        /// <param name="characterSphere">BoundingSphere del cuerpo a mover</param>
        /// <param name="movementVector">Movimiento a realizar</param>
        /// <param name="obstaculos">BoundingBox de obstáculos contra los cuales se puede colisionar</param>
        /// <returns>Desplazamiento relativo final efecutado al BoundingSphere</returns> 
        public Vector3 moveCharacter(TgcBoundingSphere characterSphere, Vector3 movementVector, List<TgcBoundingBox> obstaculos)
        {
            Vector3 originalSphereCenter = characterSphere.Center;

            //Realizar movimiento
            collideWithWorld(characterSphere, movementVector, obstaculos);

            //Aplicar gravedad
            if (gravityEnabled)
            {
                collideWithWorld(characterSphere, gravityForce, obstaculos);
            }

            return characterSphere.Center - originalSphereCenter;
        }
        /// <summary>
        /// Crear inicializado
        /// </summary>
        public ElipsoidCollisionManager()
        {
            gravityEnabled = true;
            gravityForce = new Vector3(0, -10, 0);
            slideFactor = 1.3f;
            movementSphere = new TgcBoundingSphere();
            eSphere = new TgcBoundingSphere();
            objetosCandidatos = new List<Collider>();
            onGroundMinDotValue = 0.72f;

            result = new CollisionResult();
            result.collisionFound = false;
            result.collisionNormal = Vector3.Empty;
            result.collisionPoint = Vector3.Empty;
            result.realMovmentVector = Vector3.Empty;
        }
        public override void init()
        {
            cylinder = new Cylinder(new Vector3(0, 0, 0), 2, 4);
            sphere = new TgcBoundingSphere(new Vector3(0, 0, 0), 3);

            //cylinder.Transform = Matrix.Scaling(2, 1, 1);
            //cylinder.AutoTransformEnable = false;
            //cylinder.updateValues();

            GuiController.Instance.Modifiers.addBoolean("boundingCylinder", "boundingCylinder", false);
            GuiController.Instance.Modifiers.addColor("color", Color.DarkGoldenrod);

            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));
        }
示例#11
0
        public Enemigo(Vector3 posicion)
        {
            //Cargar enemigo
            TgcSkeletalLoader skeletalLoader = new TgcSkeletalLoader();

            meshEnemigos.Add("BasicHuman-TgcSkeletalMesh.xml");
            meshEnemigos.Add("CombineSoldier-TgcSkeletalMesh.xml");
            meshEnemigos.Add("CS_Gign-TgcSkeletalMesh.xml");
            meshEnemigos.Add("CS_Arctic-TgcSkeletalMesh.xml");
            meshEnemigos.Add("Pilot-TgcSkeletalMesh.xml");
            meshEnemigos.Add("Quake2Scout-TgcSkeletalMesh.xml");
            meshEnemigos.Add("WomanJeans-TgcSkeletalMesh.xml");

            enemigo = skeletalLoader.loadMeshAndAnimationsFromFile(
                GuiController.Instance.ExamplesMediaDir + "SkeletalAnimations\\BasicHuman\\" + meshEnemigos[randomEnemigo.Next(0, 6)],
                new string[] {
                    GuiController.Instance.ExamplesMediaDir + "SkeletalAnimations\\BasicHuman\\Animations\\" + "Walk-TgcSkeletalAnim.xml",
                    GuiController.Instance.ExamplesMediaDir + "SkeletalAnimations\\BasicHuman\\Animations\\" + "StandBy-TgcSkeletalAnim.xml",
                    GuiController.Instance.ExamplesMediaDir + "SkeletalAnimations\\BasicHuman\\Animations\\" + "Run-TgcSkeletalAnim.xml",
                    GuiController.Instance.AlumnoEjemplosMediaDir + "CEGA\\Animations\\" + "Death-TgcSkeletalAnim.xml",
                });

            enemigo.playAnimation("Run", true);
            enemigo.Position = posicion;
            enemigo.Scale = new Vector3(0.12f, 0.12f, 0.12f);
            this.colisionado = false;

            //Inicializo HP
            hp = 100;

            //Creo el BB para la cabeza
            cabeza = new TgcBoundingSphere(new Vector3(enemigo.Position.X, enemigo.Position.Y + 5.2F, enemigo.Position.Z), 0.5F); //Debe haber alguna forma de sacar esta info del hueso directamente
            cabeza.setRenderColor(System.Drawing.Color.Red);

            //Modifico el BB del cuerpo
            enemigo.AutoUpdateBoundingBox = false;
            enemigo.BoundingBox.scaleTranslate(enemigo.Position, new Vector3(0.07f, 0.095f, 0.07f));

            //Inicializo el emisor
            emisorDeParticulas = new ParticleEmitter(GuiController.Instance.AlumnoEjemplosMediaDir + "CEGA\\Textures\\blood.jpg", 500);
            emisorDeParticulas.Playing = false;
        }
示例#12
0
文件: Tank.cs 项目: faloi/tegece
        public Tank(Vector3 initialPosition, Terrain.Terrain terrain, string scenePath)
        {
            var loader = new TgcSceneLoader { MeshFactory = new MeshShaderFactory() };
            var scene = loader.loadSceneFromFile(scenePath);
            this.mesh = (MeshShader) scene.Meshes[0];
            this.loadShader();

            this.terrain = terrain;
            missilesShooted = new List<Missile>();

            this.boundingSphere = new TgcBoundingSphere(this.mesh.BoundingBox.calculateBoxCenter(), this.mesh.BoundingBox.calculateBoxRadius()*3);

            this.mesh.AutoTransformEnable =  this.mesh.AutoUpdateBoundingBox = false;
            this.translationMatrix = Matrix.Identity;
            this.Position = initialPosition;

            this.setTranslationMatrix(initialPosition);
            this.totalSpeed = 0f;
            this.totalRotationSpeed = 100f;
            this.forwardVector = new Vector3(0, 0, -1);
        }
        public override void init()
        {
            Device d3dDevice = GuiController.Instance.D3dDevice;

            CommandosUI.Instance.Camera = new TgcCameraAdapter(new StandardCamera());

            //this.lastPos = new Vector3(0, 0, 0);
            //GuiController.Instance.Modifiers.addVertex3f("posicion", new Vector3(-200, 0, -200), new Vector3(200, 0, 200), this.lastPos);

            this.userCylinder = new CommandosCylinder(CommandosUI.Instance.Camera.getLookAt(), 40, 20, Color.Yellow);

            this.staticSphere = new TgcBoundingSphere(new Vector3(200, 0, -200), 40);
            this.staticCylinder = new CommandosCylinder(new Vector3(-100, 0, 0), 40, 40, Color.Yellow);
            this.staticAABB = new TgcBoundingBox(new Vector3(0, -40, -200), new Vector3(80, 40, -120));

            //GuiController.Instance.Modifiers.addBoolean("closestPoint", "closestPoint", false);

            this.colisionNormal = new TgcArrow();
            this.colisionNormal.Thickness = 2f;
            this.colisionNormal.HeadSize = new Vector2(4f, 4f);
            this.colisionNormal.Enabled = true;
        }
        /// <summary>
        /// Detección de colisiones recursiva
        /// </summary>
        public void doCollideWithWorld(TgcBoundingSphere characterSphere, Vector3 movementVector, List<Collider> colliders, int recursionDepth, TgcBoundingSphere movementSphere, bool sliding, float slidingMinY)
        {
            //Limitar recursividad
            if (recursionDepth > 5)
            {
                return;
            }

            //Posicion deseada
            Vector3 originalSphereCenter = characterSphere.Center;
            Vector3 nextSphereCenter = originalSphereCenter + movementVector;

            //Buscar el punto de colision mas cercano de todos los objetos candidatos
            collision = false;
            Vector3 q;
            float t;
            Vector3 n;
            float minT = float.MaxValue;
            foreach (Collider collider in colliders)
            {
                //Colisionar Sphere en movimiento contra Collider (cada Collider resuelve la colision)
                if (collider.intersectMovingSphere(characterSphere, movementVector, movementSphere, out t, out q, out n))
                {
                    //Quedarse con el menor instante de colision
                    if(t < minT)
                    {
                        minT = t;
                        collision = true;
                        lastCollisionPoint = q;
                        lastCollisionNormal = n;
                        lastCollider = collider;
                    }
                }
            }

            //Si nunca hubo colisión, avanzar todo lo requerido
            if (!collision)
            {
                //Avanzar todo lo pedido
                //lastCollisionDistance = movementVector.Length();
                characterSphere.moveCenter(movementVector);
                return;
            }

            //Solo movernos si ya no estamos muy cerca
            if (minT >= EPSILON)
            {
                //Restar un poco al instante de colision, para movernos hasta casi esa distancia
                minT -= EPSILON;
                Vector3 realMovementVector = movementVector * minT;

                //Mover el BoundingSphere
                characterSphere.moveCenter(realMovementVector);

                //Quitarle al punto de colision el EPSILON restado al movimiento, para no afectar al plano de sliding
                Vector3 v = Vector3.Normalize(realMovementVector);
                lastCollisionPoint -= v * EPSILON;
            }

            if (sliding)
            {
                //Calcular plano de Sliding, como un plano tangete al punto de colision con la esfera, apuntando hacia el centro de la esfera
                Vector3 slidePlaneOrigin = lastCollisionPoint;
                Vector3 slidePlaneNormal = characterSphere.Center - lastCollisionPoint;
                slidePlaneNormal.Normalize();
                Plane slidePlane = Plane.FromPointNormal(slidePlaneOrigin, slidePlaneNormal);

                //Calcular vector de movimiento para sliding, proyectando el punto de destino original sobre el plano de sliding
                float distance = TgcCollisionUtils.distPointPlane(nextSphereCenter, slidePlane);
                Vector3 newDestinationPoint = nextSphereCenter - distance * slidePlaneNormal;
                Vector3 slideMovementVector = newDestinationPoint - lastCollisionPoint;

                //No hacer recursividad si es muy pequeño
                slideMovementVector.Scale(slideFactor);
                if (slideMovementVector.Length() < EPSILON)
                {
                    return;
                }

                if (lastCollisionNormal.Y <= slidingMinY)
                {
                    //Recursividad para aplicar sliding
                    doCollideWithWorld(characterSphere, slideMovementVector, colliders, recursionDepth + 1, movementSphere, sliding, slidingMinY);
                }

            }
        }
示例#15
0
 /// <summary>
 /// Detecta colision entre una esfera que se esta moviendo contra un plano.
 /// Si hay colision devuelve el instante t de la colision y el punto q de colision.
 /// </summary>
 /// <param name="sphere">BoundingSphere</param>
 /// <param name="velocity">Vector de movimiento de la esfera</param>
 /// <param name="plane">Plano</param>
 /// <param name="t">Instante de colision en el intervalo [0, 1]</param>
 /// <param name="q">Punto de colision</param>
 /// <returns>True si hay colision</returns>
 public static bool intersectMovingSpherePlane(TgcBoundingSphere sphere, Vector3 velocity, Plane plane, out float t, out Vector3 q)
 {
     // Compute distance of sphere center to plane
     float dist = plane.Dot(sphere.Center);
     if (FastMath.Abs(dist) <= sphere.Radius) {
         // The sphere is already overlapping the plane. Set time of
         // intersection to zero and q to sphere center
         t = 0.0f;
         q = sphere.Center;
         return true;
     } else {
         Vector3 p_n = getPlaneNormal(plane);
         float denom = Vector3.Dot(p_n, velocity);
         if (denom * dist >= 0.0f) {
             // No intersection as sphere moving parallel to or away from plane
             t = -1;
             q = Vector3.Empty;
             return false;
         } else {
             // Sphere is moving towards the plane
             // Use +r in computations if sphere in front of plane, else -r
             float r = dist > 0.0f ? sphere.Radius : -sphere.Radius;
             t = (r - dist) / denom;
             q = sphere.Center + t * velocity - r * p_n;
             if (t > 1) return false;
             return true;
         }
     }
 }
示例#16
0
 /// <summary>
 /// Colisiona un Elipsoide en movimiento contra el objeto colisionador.
 /// Si hay colision devuelve el instante t de colision, el punto q de colision y el vector normal n de la superficie contra la que
 /// se colisiona.
 /// Todo se devuelve en Elipsoid space.
 /// </summary>
 /// <param name="eSphere">BoundingSphere de radio 1 en Elipsoid space</param>
 /// <param name="eMovementVector">movimiento en Elipsoid space</param>
 /// <param name="eRadius">radio del Elipsoide</param>
 /// <param name="movementSphere">BoundingSphere que abarca el sphere en su punto de origen mas el sphere en su punto final deseado</param>
 /// <param name="t">Menor instante de colision, en Elipsoid space</param>
 /// <param name="q">Punto mas cercano de colision, en Elipsoid space</param>
 /// <param name="n">Vector normal de la superficie contra la que se colisiona</param>
 /// <returns>True si hay colision</returns>
 public abstract bool intersectMovingElipsoid(TgcBoundingSphere eSphere, Vector3 eMovementVector, Vector3 eRadius, TgcBoundingSphere movementSphere, out float t, out Vector3 q, out Vector3 n);
示例#17
0
        protected void configure(float radius, Color color, TgcTexture texture, Vector3 center)
        {

            this.autoTransformEnable = true;
            this.transform = Matrix.Identity;
            this.translation = center;
            this.rotation = new Vector3(0, 0, 0);
            this.enabled = true;
            this.scale = new Vector3(1, 1, 1);
            this.alphaBlendEnable = false;
            this.uvOffset = new Vector2(0, 0);

            //BoundingSphere
            boundingSphere = new TgcBoundingSphere();

            //Shader
            this.effect = GuiController.Instance.Shaders.VariosShader;

            //Tipo de vertice y technique
            if (texture != null) this.setTexture(texture);
            else this.setColor(color);

            basePoly = eBasePoly.ICOSAHEDRON;
            levelOfDetail = 2;
            inflate = true;
            ForceUpdate = false;
            uvTiling = new Vector2(1, 1);
        }
        /// <summary>
        /// Mover BoundingSphere con detección de colisiones, sliding y gravedad.
        /// Se actualiza la posición del centrodel BoundingSphere.
        /// </summary>
        /// <param name="characterSphere">BoundingSphere del cuerpo a mover</param>
        /// <param name="movementVector">Movimiento a realizar</param>
        /// <param name="colliders">Obstáculos contra los cuales se puede colisionar</param>
        /// <returns>Desplazamiento relativo final efecutado al BoundingSphere</returns> 
        public Vector3 moveCharacter(TgcBoundingSphere characterSphere, Vector3 movementVector, List<Collider> colliders)
        {
            Vector3 originalSphereCenter = characterSphere.Center;

            //Mover
            collideWithWorld(characterSphere, movementVector, colliders, true, 1);

            //Aplicar gravedad
            if (gravityEnabled)
            {
                collideWithWorld(characterSphere, gravityForce, colliders, true, onGroundMinDotValue);
            }

            //Calcular el desplazamiento real que hubo
            lastMovementVector = characterSphere.Center - originalSphereCenter;
            return lastMovementVector;
        }
        /// <summary>
        /// Detección de colisiones, filtrando los obstaculos que se encuentran dentro del radio de movimiento
        /// </summary>
        private void collideWithWorld(TgcBoundingSphere characterSphere, Vector3 movementVector, List<Collider> colliders, bool sliding, float slidingMinY)
        {
            //Ver si la distancia a recorrer es para tener en cuenta
            float distanceToTravelSq = movementVector.LengthSq();
            if (distanceToTravelSq < EPSILON)
            {
                return;
            }

            //Dejar solo los obstáculos que están dentro del radio de movimiento de la esfera
            Vector3 halfMovementVec = Vector3.Multiply(movementVector, 0.5f);
            movementSphere.setValues(
                characterSphere.Center + halfMovementVec,
                halfMovementVec.Length() + characterSphere.Radius
                );
            objetosCandidatos.Clear();
            foreach (Collider collider in colliders)
            {
                if (collider.Enable && TgcCollisionUtils.testSphereSphere(movementSphere, collider.BoundingSphere))
                {
                    objetosCandidatos.Add(collider);
                }
            }

            //Detectar colisiones y deplazar con sliding
            doCollideWithWorld(characterSphere, movementVector, objetosCandidatos, 0, movementSphere, sliding, slidingMinY);
        }
示例#20
0
 /// <summary>
 /// Crear triangulo.
 /// Calcula su plano y BoundingSphere
 /// </summary>
 public Triangle(Vector3 a, Vector3 b, Vector3 c)
 {
     this.a = a;
     this.b = b;
     this.c = c;
     this.plane = Plane.FromPoints(a, b, c);
     this.boundingSphere = TgcBoundingSphere.computeFromPoints(new Vector3[] { a, b, c }).toClass();
 }
示例#21
0
        public override void init()
        {
            Microsoft.DirectX.Direct3D.Device d3dDevice = GuiController.Instance.D3dDevice;

            //Cargar escenario específico para este ejemplo
            TgcSceneLoader loader = new TgcSceneLoader();
            escenario = loader.loadSceneFromFile(GuiController.Instance.ExamplesDir + "\\Collision\\SphereCollision\\PatioDeJuegos\\PatioDeJuegos-TgcScene.xml");

            //Cargar personaje con animaciones
            TgcSkeletalLoader skeletalLoader = new TgcSkeletalLoader();
            personaje = skeletalLoader.loadMeshAndAnimationsFromFile(
                GuiController.Instance.ExamplesMediaDir + "SkeletalAnimations\\Robot\\" + "Robot-TgcSkeletalMesh.xml",
                GuiController.Instance.ExamplesMediaDir + "SkeletalAnimations\\Robot\\",
                new string[] {
                    GuiController.Instance.ExamplesMediaDir + "SkeletalAnimations\\Robot\\" + "Caminando-TgcSkeletalAnim.xml",
                    GuiController.Instance.ExamplesMediaDir + "SkeletalAnimations\\Robot\\" + "Parado-TgcSkeletalAnim.xml",
                });

            //Le cambiamos la textura para diferenciarlo un poco
            personaje.changeDiffuseMaps(new TgcTexture[] { TgcTexture.createTexture(d3dDevice, GuiController.Instance.ExamplesMediaDir + "SkeletalAnimations\\Robot\\Textures\\" + "uvwGreen.jpg") });

            //Configurar animacion inicial
            personaje.playAnimation("Parado", true);
            //Escalarlo porque es muy grande
            personaje.Position = new Vector3(0,500,-100);
            //Rotarlo 180° porque esta mirando para el otro lado
            personaje.rotateY(Geometry.DegreeToRadian(180f));

            //BoundingSphere que va a usar el personaje
            personaje.AutoUpdateBoundingBox = false;
            characterSphere = new TgcBoundingSphere(personaje.BoundingBox.calculateBoxCenter(), personaje.BoundingBox.calculateBoxRadius());

            //Almacenar volumenes de colision del escenario
            objetosColisionables.Clear();
            foreach (TgcMesh mesh in escenario.Meshes)
            {
                objetosColisionables.Add(mesh.BoundingBox);
            }

            //Crear linea para mostrar la direccion del movimiento del personaje
            directionArrow = new TgcArrow();
            directionArrow.BodyColor = Color.Red;
            directionArrow.HeadColor = Color.Green;
            directionArrow.Thickness = 1;
            directionArrow.HeadSize = new Vector2(10, 20);

            //Crear manejador de colisiones
            collisionManager = new SphereCollisionManager();
            collisionManager.GravityEnabled = true;

            //Configurar camara en Tercer Persona
            GuiController.Instance.ThirdPersonCamera.Enable = true;
            GuiController.Instance.ThirdPersonCamera.setCamera(personaje.Position, 100, -400);
            GuiController.Instance.ThirdPersonCamera.TargetDisplacement = new Vector3(0, 100, 0);

            //Crear SkyBox
            skyBox = new TgcSkyBox();
            skyBox.Center = new Vector3(0, 0, 0);
            skyBox.Size = new Vector3(10000, 10000, 10000);
            string texturesPath = GuiController.Instance.ExamplesMediaDir + "Texturas\\Quake\\SkyBox3\\";
            skyBox.setFaceTexture(TgcSkyBox.SkyFaces.Up, texturesPath + "Up.jpg");
            skyBox.setFaceTexture(TgcSkyBox.SkyFaces.Down, texturesPath + "Down.jpg");
            skyBox.setFaceTexture(TgcSkyBox.SkyFaces.Left, texturesPath + "Left.jpg");
            skyBox.setFaceTexture(TgcSkyBox.SkyFaces.Right, texturesPath + "Right.jpg");
            skyBox.setFaceTexture(TgcSkyBox.SkyFaces.Front, texturesPath + "Back.jpg");
            skyBox.setFaceTexture(TgcSkyBox.SkyFaces.Back, texturesPath + "Front.jpg");
            skyBox.updateValues();

            //Modifier para ver BoundingBox
            GuiController.Instance.Modifiers.addBoolean("showBoundingBox", "Bouding Box", true);

            //Modifiers para desplazamiento del personaje
            GuiController.Instance.Modifiers.addFloat("VelocidadCaminar", 0, 100, 16);
            GuiController.Instance.Modifiers.addFloat("VelocidadRotacion", 1f, 360f, 150f);
            GuiController.Instance.Modifiers.addBoolean("HabilitarGravedad", "Habilitar Gravedad", true);
            GuiController.Instance.Modifiers.addVertex3f("Gravedad", new Vector3(-50, -50, -50), new Vector3(50, 50, 50), new Vector3(0, -10, 0));
            GuiController.Instance.Modifiers.addFloat("SlideFactor", 1f, 2f, 1.3f);

            GuiController.Instance.UserVars.addVar("Movement");
        }
示例#22
0
        /// <summary>
        /// Colisiona un Elipsoide en movimiento contra un conjunto de triangulos.
        /// Si hay colision devuelve el instante t de colision, el punto q de colision y el vector normal n de la superficie contra la que
        /// se colisiona.
        /// Todo se devuelve en Elipsoid space.
        /// Pasa cada triangulo a Elipsoid space para hacer el testeo.
        /// </summary>
        /// <param name="eSphere">BoundingSphere de radio 1 en Elipsoid space</param>
        /// <param name="eMovementVector">movimiento en Elipsoid space</param>
        /// <param name="eRadius">radio del Elipsoide</param>
        /// <param name="movementSphere">BoundingSphere que abarca el sphere en su punto de origen mas el sphere en su punto final deseado</param>
        /// <param name="minT">Menor instante de colision, en Elipsoid space</param>
        /// <param name="minQ">Punto mas cercano de colision, en Elipsoid space</param>
        /// <param name="n">Vector normal de la superficie contra la que se colisiona</param>
        /// <returns>True si hay colision</returns>
        public override bool intersectMovingElipsoid(TgcBoundingSphere eSphere, Vector3 eMovementVector, Vector3 eRadius, TgcBoundingSphere movementSphere, out float minT, out Vector3 minQ, out Vector3 n)
        {
            minQ = Vector3.Empty;
            minT = float.MaxValue;
            n = Vector3.Empty;
            Plane collisionPlane = Plane.Empty;
            
            //Colision contra cada triangulo del collider, quedarse con el menor
            Vector3 q;
            float t;
            for (int i = 0; i < triangles.Length; i++)
            {
                Triangle triangle = triangles[i];

                //Primero hacer un Sphere-Sphere test
                if (TgcCollisionUtils.testSphereSphere(movementSphere, triangle.BoundingSphere))
                {
                    //Pasar triangle a Elipsoid Space
                    Triangle eTriangle = new Triangle(
                        TgcVectorUtils.div(triangle.A, eRadius),
                        TgcVectorUtils.div(triangle.B, eRadius),
                        TgcVectorUtils.div(triangle.C, eRadius),
                        null
                        );

                    //Interseccion Moving Sphere-Triangle
                    if (intersectMovingSphereTriangle(eSphere, eMovementVector, eTriangle, out t, out q))
                    {
                        if (t < minT)
                        {
                            minT = t;
                            minQ = q;
                            collisionPlane = triangle.Plane;
                        }
                    }
                } 
            }

            if (minT != float.MaxValue)
            {
                n = TgcCollisionUtils.getPlaneNormal(collisionPlane);
                return true;
            }

            return false;
        }
示例#23
0
 /// <summary>
 /// Crear triangulo.
 /// Calcula su plano
 /// </summary>
 public Triangle(Vector3 a, Vector3 b, Vector3 c, TgcBoundingSphere sphere)
 {
     this.a = a;
     this.b = b;
     this.c = c;
     this.plane = Plane.FromPoints(a, b, c);
     this.boundingSphere = sphere;
 }
示例#24
0
 /// <summary>
 /// Indica si un BoundingSphere colisiona con otro.
 /// </summary>
 /// <returns>True si hay colisión</returns>
 public static bool testSphereSphere(TgcBoundingSphere a, TgcBoundingSphere b)
 {
     // Calculate squared distance between centers
     Vector3 d = a.Center - b.Center;
     float dist2 = Vector3.Dot(d, d);
     // Spheres intersect if squared distance is less than squared sum of radii
     float radiusSum = a.Radius + b.Radius;
     return dist2 <= radiusSum * radiusSum;
 }
示例#25
0
        /// <summary>
        /// Detectar colision entre una esfera que se mueve y un triangulo
        /// </summary>
        /// <param name="sphere">BoundingSphere</param>
        /// <param name="movementVector">Vector de movimiento de la esferfa</param>
        /// <param name="triangle">Triangulo</param>
        /// <param name="collisionPoint">Menor punto de colision encontrado</param>
        /// <returns>True si hay colision</returns>
        private bool intersectMovingSphereTriangle(TgcBoundingSphere sphere, Vector3 movementVector, Triangle triangle, out float minT, out Vector3 collisionPoint)
        {
            float t;
            Vector3 q;
            collisionPoint = Vector3.Empty;
            minT = float.MaxValue;

            //Ver si la esfera en movimiento colisiona con el plano del triangulo
            if (!TgcCollisionUtils.intersectMovingSpherePlane(sphere, movementVector, triangle.Plane, out t, out q))
            {
                return false;
            }


            //Ver si la esfera ya esta dentro del Plano, hacer un chequeo Sphere-Triangle
            if (t == 0.0f)
            {
                if (TgcCollisionUtils.testSphereTriangle(sphere, triangle.A, triangle.B, triangle.C, out q))
                {
                    minT = 0.0f;
                    collisionPoint = q;
                    return true;
                }
            }
            else
            {
                //Si el punto de colision contra el plano pertenece al triangulo, entonces ya encontramos el punto de colision
                if (TgcCollisionUtils.testPointInTriangle(q, triangle.A, triangle.B, triangle.C))
                {
                    minT = t;
                    collisionPoint = q;
                    return true;
                }
            }



            //Ver de que lado del plano del triangulo esta la esfera
            float distPlane = triangle.Plane.Dot(sphere.Center);
            float sphereRad = distPlane >= 0.0f ? sphere.Radius : -sphere.Radius;
            Vector3 planeNormal = TgcCollisionUtils.getPlaneNormal(triangle.Plane);


            //Chequear colision entre la esfera en movimiento y los tres Edge y obtener el menor punto de colision
            //Es como un Ray del centro de la esfera contra un edge que se convierte en cilindro sin endcap
            Vector3 segmentEnd = sphere.Center + movementVector;
            if (intersectSegmentCylinderNoEndcap(sphere.Center, segmentEnd, triangle.A, triangle.B, sphere.Radius, out t))
            {
                minT = TgcCollisionUtils.min(t, minT);
            }
            if (intersectSegmentCylinderNoEndcap(sphere.Center, segmentEnd, triangle.B, triangle.C, sphere.Radius, out t))
            {
                minT = TgcCollisionUtils.min(t, minT);
            }
            if (intersectSegmentCylinderNoEndcap(sphere.Center, segmentEnd, triangle.C, triangle.A, sphere.Radius, out t))
            {
                minT = TgcCollisionUtils.min(t, minT);
            }
            //Si hubo colision, retornar la menor encontrada
            if (minT != float.MaxValue)
            {
                collisionPoint = sphere.Center + minT * movementVector - sphereRad * planeNormal;
                return true;
            }

            //Sino, chequear colision entra la esfera y los tres vertices del triangulo y obtener la menor
            //Es como un Ray del centro de la esfera contra un vertice que se convierte en esfera
            TgcBoundingSphere vertSphere = new TgcBoundingSphere();
            minT = float.MaxValue;
            vertSphere.setValues(triangle.A, sphere.Radius);
            if (TgcCollisionUtils.intersectSegmentSphere(sphere.Center, segmentEnd, vertSphere, out t, out q))
            {
                minT = TgcCollisionUtils.min(t, minT);
            }
            vertSphere.setValues(triangle.B, sphere.Radius);
            if (TgcCollisionUtils.intersectSegmentSphere(sphere.Center, segmentEnd, vertSphere, out t, out q))
            {
                minT = TgcCollisionUtils.min(t, minT);
            }
            vertSphere.setValues(triangle.C, sphere.Radius);
            if (TgcCollisionUtils.intersectSegmentSphere(sphere.Center, segmentEnd, vertSphere, out t, out q))
            {
                minT = TgcCollisionUtils.min(t, minT);
            }
            //Si hubo colision, retornar la menor encontrada
            if (minT != float.MaxValue)
            {
                collisionPoint = sphere.Center + minT * movementVector - sphereRad * planeNormal;
                return true;
            }


            //No hay colision
            return false;
        }
示例#26
0
 /// <summary>
 /// Indica si un BoundingSphere colisiona con un triangulo (a, b, c).
 /// Si hay colision devuelve el punto p mas cercano de la colision
 /// </summary>
 /// <param name="sphere">BoundingSphere</param>
 /// <param name="a">Vertice A del triangulo</param>
 /// <param name="b">Vertice B del triangulo</param>
 /// <param name="c">Vertice C del triangulo</param>
 /// <param name="p">Punto mas cercano de colision</param>
 /// <returns>True si hay colision</returns>
 public static bool testSphereTriangle(TgcBoundingSphere sphere, Vector3 a, Vector3 b, Vector3 c, out Vector3 p)
 {
     // Find point P on triangle ABC closest to sphere center
     p = TgcCollisionUtils.closestPointTriangle(sphere.Center, a, b, c);
     // Sphere and triangle intersect if the (squared) distance from sphere
     // center to point p is less than the (squared) sphere radius
     Vector3 v = p - sphere.Center;
     return Vector3.Dot(v, v) <= sphere.Radius * sphere.Radius;
 }
        /// <summary>
        /// Colisiona un Elipsoide en movimiento contra el BoundingBox.
        /// Si hay colision devuelve el instante t de colision, el punto q de colision y el vector normal n de la superficie contra la que
        /// se colisiona.
        /// Todo se devuelve en Elipsoid space.
        /// El BoundingBox se pasa a Elipsoid space para comparar.
        /// </summary>
        /// <param name="eSphere">BoundingSphere de radio 1 en Elipsoid space</param>
        /// <param name="eMovementVector">movimiento en Elipsoid space</param>
        /// <param name="eRadius">radio del Elipsoide</param>
        /// <param name="movementSphere">BoundingSphere que abarca el sphere en su punto de origen mas el sphere en su punto final deseado</param>
        /// <param name="t">Menor instante de colision, en Elipsoid space</param>
        /// <param name="q">Punto mas cercano de colision, en Elipsoid space</param>
        /// <param name="n">Vector normal de la superficie contra la que se colisiona</param>
        /// <returns>True si hay colision</returns>
        public override bool intersectMovingElipsoid(TgcBoundingSphere eSphere, Vector3 eMovementVector, Vector3 eRadius, TgcBoundingSphere movementSphere, out float t, out Vector3 q, out Vector3 n)
        {
            //Pasar AABB a Elipsoid Space
            eAABB.setExtremes(
                TgcVectorUtils.div(aabb.PMin, eRadius),
                TgcVectorUtils.div(aabb.PMax, eRadius)
                );

            t = -1f;
            q = Vector3.Empty;
            n = Vector3.Empty;

            // Compute the AABB resulting from expanding b by sphere radius r
            TgcBoundingBox.AABBStruct e = eAABB.toStruct();
            e.min.X -= eSphere.Radius; e.min.Y -= eSphere.Radius; e.min.Z -= eSphere.Radius;
            e.max.X += eSphere.Radius; e.max.Y += eSphere.Radius; e.max.Z += eSphere.Radius;

            // Intersect ray against expanded AABB e. Exit with no intersection if ray
            // misses e, else get intersection point p and time t as result
            Vector3 p;
            TgcRay.RayStruct ray = new TgcRay.RayStruct();
            ray.origin = eSphere.Center;
            ray.direction = eMovementVector;
            if (!intersectRayAABB(ray, e, out t, out p) || t > 1.0f)
                return false;

            // Compute which min and max faces of b the intersection point p lies
            // outside of. Note, u and v cannot have the same bits set and
            // they must have at least one bit set among them
            int i = 0;
            int[] sign = new int[3];
            if (p.X < eAABB.PMin.X)
            {
                sign[0] = -1;
                i++;
            }
            if (p.X > eAABB.PMax.X)
            {
                sign[0] = 1;
                i++;
            }
            if (p.Y < eAABB.PMin.Y)
            {
                sign[1] = -1;
                i++;
            }
            if (p.Y > eAABB.PMax.Y)
            {
                sign[1] = 1;
                i++;
            }
            if (p.Z < eAABB.PMin.Z)
            {
                sign[2] = -1;
                i++;
            }
            if (p.Z > eAABB.PMax.Z)
            {
                sign[2] = 1;
                i++;
            }

            //Face
            if (i == 1)
            {
                n = new Vector3(sign[0], sign[1], sign[2]);
                q = eSphere.Center + t * eMovementVector - eSphere.Radius * n;
                return true;
            }

            // Define line segment [c, c+d] specified by the sphere movement
            Segment seg = new Segment(eSphere.Center, eSphere.Center + eMovementVector);

            //Box extent and center
            Vector3 extent = eAABB.calculateAxisRadius();
            Vector3 center = eAABB.PMin + extent;

            //Edge
            if (i == 2)
            {
                //Generar los dos puntos extremos del Edge
                float[] extentDir = new float[]{sign[0], sign[1], sign[2]};
                int zeroIndex = sign[0] == 0 ? 0 : (sign[1] == 0 ? 1 : 2);
                extentDir[zeroIndex] = 1;
                Vector3 capsuleA = center + new Vector3(extent.X * extentDir[0], extent.Y * extentDir[1], extent.Z * extentDir[2]);
                extentDir[zeroIndex] = -1;
                Vector3 capsuleB = center + new Vector3(extent.X * extentDir[0], extent.Y * extentDir[1], extent.Z * extentDir[2]);

                //Colision contra el Edge hecho Capsula
                if (intersectSegmentCapsule(seg, new Capsule(capsuleA, capsuleB, eSphere.Radius), out t))
                {
                    n = new Vector3(sign[0], sign[1], sign[2]);
                    n.Normalize();
                    q = eSphere.Center + t * eMovementVector - eSphere.Radius * n;
                    return true;
                }
            }

            //Vertex
            if (i == 3)
            {
                float tmin = float.MaxValue;
                Vector3 capsuleA = center + new Vector3(extent.X * sign[0], extent.Y * sign[1], extent.Z * sign[2]);
                Vector3 capsuleB;

                capsuleB = center + new Vector3(extent.X * -sign[0], extent.Y * sign[1], extent.Z * sign[2]);
                if (intersectSegmentCapsule(seg, new Capsule(capsuleA, capsuleB, eSphere.Radius), out t))
                    tmin = TgcCollisionUtils.min(t, tmin);

                capsuleB = center + new Vector3(extent.X * sign[0], extent.Y * -sign[1], extent.Z * sign[2]);
                if (intersectSegmentCapsule(seg, new Capsule(capsuleA, capsuleB, eSphere.Radius), out t))
                    tmin = TgcCollisionUtils.min(t, tmin);

                capsuleB = center + new Vector3(extent.X * sign[0], extent.Y * sign[1], extent.Z * -sign[2]);
                if (intersectSegmentCapsule(seg, new Capsule(capsuleA, capsuleB, eSphere.Radius), out t))
                    tmin = TgcCollisionUtils.min(t, tmin);

                if (tmin == float.MaxValue) return false; // No intersection

                t = tmin;
                n = new Vector3(sign[0], sign[1], sign[2]);
                n.Normalize();
                q = eSphere.Center + t * eMovementVector - eSphere.Radius * n;
                return true; // Intersection at time t == tmin
            }

            return false;
        }
示例#28
0
        /// <summary>
        /// Indica si un BoundingSphere colisiona con el Frustum
        /// </summary>
        /// <param name="frustum">Frustum</param>
        /// <param name="sphere">BoundingSphere</param>
        /// <returns>Resultado de la colisión</returns>
        public static FrustumResult classifyFrustumSphere(TgcFrustum frustum, TgcBoundingSphere sphere)
        {
            float distance;
            FrustumResult result = FrustumResult.INSIDE;
            Plane[] frustumPlanes = frustum.FrustumPlanes;

            for (int i = 0; i < 6; i++)
            {
                distance = distPointPlane(sphere.Center, frustumPlanes[i]);

                if (distance < - sphere.Radius)
                {
                    return FrustumResult.OUTSIDE;
                }
                else if (distance < sphere.Radius)
                {
                    result = FrustumResult.INTERSECT;
                }

            }
            return result;
        }
        /// <summary>
        /// Detección de colisiones recursiva
        /// </summary>
        /// <param name="eSphere">Sphere de radio 1 pasada a Elipsoid space</param>
        /// <param name="eMovementVector">Movimiento pasado a Elipsoid space</param>
        /// <param name="eRadius">Radio de la elipsoide</param>
        /// <param name="colliders">Objetos contra los cuales colisionar</param>
        /// <param name="recursionDepth">Nivel de recursividad</param>
        /// <param name="movementSphere">Esfera real que representa el movimiento abarcado</param>
        /// <param name="slidingMinY">Minimo valor de normal Y de colision para hacer sliding</param>
        /// <returns>Resultado de colision</returns>
        public CollisionResult doCollideWithWorld(TgcBoundingSphere eSphere, Vector3 eMovementVector, Vector3 eRadius, List<Collider> colliders, int recursionDepth, TgcBoundingSphere movementSphere, float slidingMinY)
        {
            CollisionResult result = new CollisionResult();
            result.collisionFound = false;

            //Limitar recursividad
            if (recursionDepth > 5)
            {
                return result;
            }

            //Posicion deseada
            Vector3 nextSphereCenter = eSphere.Center + eMovementVector;

            //Buscar el punto de colision mas cercano de todos los objetos candidatos
            Vector3 q;
            float t;
            Vector3 n;
            float minT = float.MaxValue;
            foreach (Collider collider in colliders)
            {
                //Colisionar Sphere en movimiento contra Collider (cada Collider resuelve la colision)
                if (collider.intersectMovingElipsoid(eSphere, eMovementVector, eRadius, movementSphere, out t, out q, out n))
                {
                    //Quedarse con el menor instante de colision
                    if(t < minT)
                    {
                        minT = t;
                        result.collisionFound = true;
                        result.collisionPoint = q;
                        result.collisionNormal = n;
                        result.collider = collider;
                    }
                }
            }

            //Si nunca hubo colisión, avanzar todo lo requerido
            if (!result.collisionFound)
            {
                //Avanzar todo lo pedido
                eSphere.moveCenter(eMovementVector);
                result.realMovmentVector = eMovementVector;
                result.collisionNormal = Vector3.Empty;
                result.collisionPoint = Vector3.Empty;
                result.collider = null;
                return result;
            }


            //Solo movernos si ya no estamos muy cerca
            if (minT >= EPSILON)
            {
                //Restar un poco al instante de colision, para movernos hasta casi esa distancia
                minT -= EPSILON;
                result.realMovmentVector = eMovementVector * minT;
                eSphere.moveCenter(result.realMovmentVector);

                //Quitarle al punto de colision el EPSILON restado al movimiento, para no afectar al plano de sliding
                Vector3 v = Vector3.Normalize(result.realMovmentVector);
                result.collisionPoint -= v * EPSILON;
            }


            //Calcular plano de Sliding, como un plano tangete al punto de colision con la esfera, apuntando hacia el centro de la esfera
            Vector3 slidePlaneOrigin = result.collisionPoint;
            Vector3 slidePlaneNormal = eSphere.Center - result.collisionPoint;
            slidePlaneNormal.Normalize();
            Plane slidePlane = Plane.FromPointNormal(slidePlaneOrigin, slidePlaneNormal);

            //Calcular vector de movimiento para sliding, proyectando el punto de destino original sobre el plano de sliding
            float distance = TgcCollisionUtils.distPointPlane(nextSphereCenter, slidePlane);
            Vector3 newDestinationPoint = nextSphereCenter - distance * slidePlaneNormal;
            Vector3 slideMovementVector = newDestinationPoint - result.collisionPoint;

            //No hacer recursividad si es muy pequeño
            slideMovementVector.Scale(slideFactor);
            if (slideMovementVector.Length() < EPSILON)
            {
                return result;
            }

            //Ver si posee la suficiente pendiente en Y para hacer sliding
            if (result.collisionNormal.Y <= slidingMinY)
            {
                //Recursividad para aplicar sliding
                doCollideWithWorld(eSphere, slideMovementVector, eRadius, colliders, recursionDepth + 1, movementSphere, slidingMinY);
            }

            
            return result;
        }
示例#30
0
        //
        /// <summary>
        /// Indica si un BoundingSphere se encuentra completamente en el lado negativo del plano
        /// </summary>
        /// <returns>True si se encuentra completamente en el lado negativo del plano</returns>
        public static bool insideSpherePlane(TgcBoundingSphere s, Plane plane)
        {
            Vector3 p = toVector3(plane);

            float dist = Vector3.Dot(s.Center, p) - plane.D;
            return dist < -s.Radius;
        }