Exemple #1
0
        /// <summary>
        ///     Picking con los planos XZ e YZ ubicados en el centro del objeto
        /// </summary>
        public TGCVector3 getPickingZ(TgcRay ray, TGCVector3 objCenter)
        {
            //Mover ambos planos hacia el centro del objeto
            pickingXZAabb.setExtremes(
                new TGCVector3(pickingXZAabb.PMin.X, objCenter.Y - SMALL_VAL, pickingXZAabb.PMin.Z),
                new TGCVector3(pickingXZAabb.PMax.X, objCenter.Y, pickingXZAabb.PMax.Z));
            pickingYZAabb.setExtremes(
                new TGCVector3(objCenter.X - SMALL_VAL, pickingYZAabb.PMin.Y, pickingYZAabb.PMin.Z),
                new TGCVector3(objCenter.X, pickingYZAabb.PMax.Y, pickingYZAabb.PMax.Z));

            TGCVector3 q1, q2;
            bool       r1, r2;

            r1 = TgcCollisionUtils.intersectRayAABB(ray, pickingXZAabb, out q1);
            r2 = TgcCollisionUtils.intersectRayAABB(ray, pickingYZAabb, out q2);

            if (r1 && r2)
            {
                var objPos = new TGCVector2(objCenter.X, objCenter.Y);
                var diff1  = TGCVector2.Length(new TGCVector2(q1.X, q1.Y) - objPos);
                var diff2  = TGCVector2.Length(new TGCVector2(q2.X, q2.Y) - objPos);
                return(diff1 < diff2 ? q1 : q2);
            }
            if (r1)
            {
                return(clampPickingResult(q1));
            }
            if (r2)
            {
                return(clampPickingResult(q2));
            }
            return(objCenter);
        }
        /// <summary>
        /// Hacer picking contra todos los ejes y devolver el eje seleccionado (si hay colision).
        /// Tambien se evaluan los ejes compuestos (XY, XZ, YZ)
        /// </summary>
        public Axis doPickAxis(TgcRay ray)
        {
            TGCVector3 collP;

            if (TgcCollisionUtils.intersectRayAABB(ray, boxX.BoundingBox, out collP))
            {
                return(Axis.X);
            }
            if (TgcCollisionUtils.intersectRayAABB(ray, boxY.BoundingBox, out collP))
            {
                return(Axis.Y);
            }
            if (TgcCollisionUtils.intersectRayAABB(ray, boxZ.BoundingBox, out collP))
            {
                return(Axis.Z);
            }
            if (TgcCollisionUtils.intersectRayAABB(ray, boxXZ.BoundingBox, out collP))
            {
                return(Axis.XZ);
            }
            if (TgcCollisionUtils.intersectRayAABB(ray, boxXY.BoundingBox, out collP))
            {
                return(Axis.XY);
            }
            if (TgcCollisionUtils.intersectRayAABB(ray, boxYZ.BoundingBox, out collP))
            {
                return(Axis.YZ);
            }
            return(Axis.None);
        }
        public override bool intersectRay(TgcRay ray, Matrix transform, out Vector3 q)
        {
            COLLISION_SPHERE.setCenter(Vector3.TransformCoordinate(position, transform));
            float t;

            return(TgcCollisionUtils.intersectRaySphere(ray, COLLISION_SPHERE, out t, out q));
        }
Exemple #4
0
        public static Vector3 getClosesPointBetween(TgcRay rayCast, BoundingBoxCollider boundingBox)
        {
            Vector3 vector = new Vector3();

            TgcCollisionUtils.intersectRayAABB(rayCast, boundingBox.Aabb, out vector);
            return(vector);
        }
 public Rayo(TGCVector3 origen, TGCVector3 direccion)
 {
     this.origen            = origen;
     this.direccion         = direccion;
     this.ray               = new TgcRay(origen, direccion);
     this.puntoInterseccion = TGCVector3.Empty;
 }
Exemple #6
0
        /// <summary>
        /// Picking con los planos XY e YZ ubicados en el centro del objeto
        /// </summary>
        public Vector3 getPickingY(TgcRay ray, Vector3 objCenter)
        {
            //Mover ambos planos hacia el centro del objeto
            pickingXYAabb.setExtremes(
                new Vector3(pickingXYAabb.PMin.X, pickingXYAabb.PMin.Y, objCenter.Z - SMALL_VAL),
                new Vector3(pickingXYAabb.PMax.X, pickingXYAabb.PMax.Y, objCenter.Z));
            pickingYZAabb.setExtremes(
                new Vector3(objCenter.X - SMALL_VAL, pickingYZAabb.PMin.Y, pickingYZAabb.PMin.Z),
                new Vector3(objCenter.X, pickingYZAabb.PMax.Y, pickingYZAabb.PMax.Z));

            Vector3 q1, q2;
            bool    r1, r2;

            r1 = TgcCollisionUtils.intersectRayAABB(ray, pickingXYAabb, out q1);
            r2 = TgcCollisionUtils.intersectRayAABB(ray, pickingYZAabb, out q2);

            if (r1 && r2)
            {
                Vector2 objPos = new Vector2(objCenter.X, objCenter.Z);
                float   diff1  = Vector2.Length(new Vector2(q1.X, q1.Z) - objPos);
                float   diff2  = Vector2.Length(new Vector2(q2.X, q2.Z) - objPos);
                return(diff1 < diff2 ? q1 : q2);
            }
            else if (r1)
            {
                return(clampPickingResult(q1));
            }
            else if (r2)
            {
                return(clampPickingResult(q2));
            }
            return(objCenter);
        }
        public Item Pick(TgcRay ray)
        {
            var item = _Items.FirstOrDefault(i => i.Intercepts(ray));

            if (item != null)
            {
                Remove(item);
            }
            return(item);
        }
Exemple #8
0
        public override bool intersectRay(TgcRay ray, Matrix transform, out Vector3 q)
        {
            Vector3[] v = new Vector3[vertices.Count];
            for (int i = 0; i < v.Length; i++)
            {
                v[i] = Vector3.TransformCoordinate(vertices[i].position, transform);
            }
            float t;

            return(TgcCollisionUtils.intersectRayConvexPolygon(ray, v, out t, out q));
        }
Exemple #9
0
        public override bool intersectRay(TgcRay ray, Matrix transform, out Vector3 q)
        {
            //Actualizar OBB con posiciones de la arista para utilizar en colision
            EditablePolyUtils.updateObbFromSegment(COLLISION_OBB,
                                                   Vector3.TransformCoordinate(a.position, transform),
                                                   Vector3.TransformCoordinate(b.position, transform),
                                                   0.4f);

            //ray-obb
            return(TgcCollisionUtils.intersectRayObb(ray, COLLISION_OBB, out q));
        }
        public bool isIntersectedBy(TgcRay r)
        {
            var   tMin = (this.PMin.X - r.Origin.X) / r.Direction.X;
            var   tMax = (this.PMax.X - r.Origin.X) / r.Direction.X;
            float aux;

            if (tMin > tMax)
            {
                aux  = tMin;
                tMin = tMax;
                tMax = aux;
            }
            ;

            var tyMin = (this.PMin.Y - r.Origin.Y) / r.Direction.Y;
            var tyMax = (this.PMax.Y - r.Origin.Y) / r.Direction.Y;

            if (tyMin > tyMax)
            {
                aux   = tyMin;
                tyMin = tyMax;
                tyMax = aux;
            }
            ;

            if ((tMin > tyMax) || (tyMin > tMax))
            {
                return(false);
            }

            if (tyMin > tMin)
            {
                tMin = tyMin;
            }

            if (tyMax < tMax)
            {
                tMax = tyMax;
            }

            var tzMin = (this.PMin.Z - r.Origin.Z) / r.Direction.Z;
            var tzMax = (this.PMax.Z - r.Origin.Z) / r.Direction.Z;

            if (tzMin > tzMax)
            {
                aux   = tzMin;
                tzMin = tzMax;
                tzMax = aux;
            }
            ;

            return(!(tMin > tzMax) && !(tzMin > tMax));
        }
Exemple #11
0
        public bool hasDirectSightWith(Checkpoint aCheckPoint)
        {
            TgcRay rayCast = new TgcRay();

            rayCast.Origin    = this.Position;
            rayCast.Direction = aCheckPoint.Position - this.Position;
            float distance = Vector3.Length(aCheckPoint.Position - this.Position);
            BoundingBoxCollider boundingBox = new BoundingBoxCollider();

            CollisionManager.getClosestBoundingBox(rayCast, out boundingBox, null);
            return(boundingBox == null || (Vector3.Length(CollisionManager.getClosesPointBetween(rayCast, boundingBox) - rayCast.Origin) > distance));
        }
 private bool IntersectRayAABB(TgcRay ray, TgcBoundingAxisAlignBox aabb)
 {
     TgcBoundingAxisAlignBox.Face[] faces = aabb.computeFaces();
     foreach (TgcBoundingAxisAlignBox.Face face in faces)
     {
         if (TgcCollisionUtils.intersectRayPlane(ray, face.Plane, out float t, out TGCVector3 intersection))
         {
             return(true);
         }
     }
     return(false);
 }
Exemple #13
0
        /// <summary>
        /// Picking con plano XY ubicado en el centro del objeto
        /// </summary>
        public Vector3 getPickingXY(TgcRay ray, Vector3 objCenter)
        {
            //Mover aabb en Y al centro del mesh
            pickingXYAabb.setExtremes(
                new Vector3(pickingXYAabb.PMin.X, pickingXYAabb.PMin.Y, objCenter.Z - SMALL_VAL),
                new Vector3(pickingXYAabb.PMax.X, pickingXYAabb.PMax.Y, objCenter.Z));
            Vector3 q;
            bool    r = TgcCollisionUtils.intersectRayAABB(ray, pickingXYAabb, out q);

            if (r)
            {
                return(clampPickingResult(q));
            }
            return(objCenter);
        }
Exemple #14
0
        /// <summary>
        ///     Constructor de la camara a partir de un TgcD3dInput el cual ya tiene por default el eyePosition (0,0,0), el mouseCenter a partir del centro del a pantalla, RotationSpeed 1.0f,
        ///     MovementSpeed y JumpSpeed 500f, el directionView (0,0,-1)
        /// </summary>
        public Camera()
        {
            cameraRotation = TGCMatrix.RotationX(updownRot) * TGCMatrix.RotationY(leftrightRot);

            down           = new TgcRay();
            horx           = new TgcRay();
            horz           = new TgcRay();
            down.Direction = new TGCVector3(0, -1, 0);
            horx.Direction = new TGCVector3(1, 0, 0);
            horz.Direction = new TGCVector3(0, 0, 1);


            g.camera = this;
            g.hands  = new Hands();
        }
Exemple #15
0
        /// <summary>
        ///     Picking con plano YZ ubicado en el centro del objeto
        /// </summary>
        public TGCVector3 getPickingYZ(TgcRay ray, TGCVector3 objCenter)
        {
            //Mover aabb en Y al centro del mesh
            pickingYZAabb.setExtremes(
                new TGCVector3(objCenter.X - SMALL_VAL, pickingYZAabb.PMin.Y, pickingYZAabb.PMin.Z),
                new TGCVector3(objCenter.X, pickingYZAabb.PMax.Y, pickingYZAabb.PMax.Z));
            TGCVector3 q;
            var        r = TgcCollisionUtils.intersectRayAABB(ray, pickingYZAabb, out q);

            if (r)
            {
                return(clampPickingResult(q));
            }
            return(objCenter);
        }
Exemple #16
0
        protected bool IsReallyTheFloor(Collidable element)
        {
            TGCVector3 directionOfCollision = new TGCVector3(0, -1f, 0);
            TgcRay     ray = new TgcRay();

            ray.Origin    = this.auto.GetLastPosition();
            ray.Direction = directionOfCollision;
            TGCPlane   plane  = element.GetPlaneOfCollision(ray, this.auto);
            TGCVector3 normal = new TGCVector3(0, 1, 0);

            if (normal != new TGCVector3(0, 1, 0))
            {
                return(false);
            }
            return(true);
        }
Exemple #17
0
        private TGCPlane CreatePlane(TgcRay ray, TgcBoundingAxisAlignBox.Face[] faces, TGCVector3 testPoint)
        {
            float           instante;
            TGCVector3      intersection;
            List <TGCPlane> candidatesPlanes = new List <TGCPlane>();

            foreach (TgcBoundingAxisAlignBox.Face face in faces)
            {
                if (TgcCollisionUtils.intersectRayPlane(ray, face.Plane, out instante, out intersection))
                {
                    candidatesPlanes.Add(face.Plane);
                }
            }

            return(this.SelectPlane(candidatesPlanes, testPoint));
        }
        private void Collide(Vehicle car)
        {
            TgcRay ray = new TgcRay();

            ray.Origin    = this.GetLastPosition();
            ray.Direction = this.GetDirectionOfCollision();
            if (this.IntersectRayAABB(ray, car.mesh.BoundingBox))
            {
                float distanceAI = car.GetDistanceOfCollision(this.vectorAdelante, this.velocidadActual);
                float distance   = this.GetDistanceOfCollision(car.GetVectorAdelante(), car.GetVelocidadActual());
                car.SetEstado(new Crashing(car, distanceAI, this.GetVectorAdelante()));
                this.SetEstado(new Crashing(this, distance, car.GetVectorAdelante()));
                car.TakeDamage(5f);
                TakeDamage(5f);
            }
        }
Exemple #19
0
        /// <summary>
        /// Retorna true si hubo interseccion con el plano del terreno y setea el collisionPoint con la altura en ese punto.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="collisionPoint"></param>
        /// <returns></returns>
        public bool intersectRayPlane(TgcRay ray, out Vector3 collisionPoint)
        {
            collisionPoint = Vector3.Empty;
            float minHeight = (minIntensity + traslation.Y) * ScaleY;


            float t;

            //Me fijo si intersecta con el BB del terreno.
            if (!TgcCollisionUtils.intersectRayPlane(ray, new Plane(0, 1, 0, -minHeight), out t, out collisionPoint))
            {
                return(false);
            }

            return(interpoledHeight(collisionPoint.X, collisionPoint.Z, out collisionPoint.Y));
        }
Exemple #20
0
        public static Boolean getClosestBoundingBox(TgcRay rayCast, out BoundingBoxCollider boundingBoxResult, BoundingBoxCollider boundingBox)
        {
            List <BoundingBoxCollider> boundingBoxes = getColisions(rayCast);

            boundingBoxes.Remove(boundingBox);
            if (boundingBoxes.Count == 0)
            {
                boundingBoxResult = null;
                return(false);
            }
            else
            {
                List <Vector3> vectors = boundingBoxes.ConvertAll(b => { Vector3 vector = new Vector3(); TgcCollisionUtils.intersectRayAABB(rayCast, b.Aabb, out vector); return(vector); });
                boundingBoxResult = boundingBoxes.Find(b => { Vector3 vector = new Vector3(); TgcCollisionUtils.intersectRayAABB(rayCast, b.Aabb, out vector); return(vectors.TrueForAll(v => Vector3.Length(vector - rayCast.Origin) <= Vector3.Length(v - rayCast.Origin))); });
                return(true);
            }
        }
Exemple #21
0
        public TGCPlane GetPlaneOfCollision(TgcRay ray, Vehicle car)
        {
            TgcMesh collide = null;

            foreach (TgcMesh element in this.elements)
            {
                if (IsColliding(element, car))
                {
                    collide = element;
                }
            }
            if (collide == null)
            {
                throw new Exception("Hubo un error no esperado");
            }
            TgcBoundingAxisAlignBox.Face[] faces = collide.BoundingBox.computeFaces();
            return(this.CreatePlane(ray, faces, car.GetLastPosition()));
        }
Exemple #22
0
        /// <summary>
        ///     Retorna true si hubo interseccion con el plano del terreno y setea el collisionPoint con la altura en ese punto.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="collisionPoint"></param>
        /// <returns></returns>
        public bool intersectRayTGCPlane(TgcRay ray, out TGCVector3 collisionPoint)
        {
            collisionPoint = TGCVector3.Empty;
            var minHeight = (minIntensity + traslation.Y) * ScaleY;

            float t;

            //Me fijo si intersecta con el BB del terreno.
            if (!TgcCollisionUtils.intersectRayPlane(ray, new TGCPlane(0, 1, 0, -minHeight), out t, out collisionPoint))
            {
                return(false);
            }

            var collisionPointY = collisionPoint.Y;
            var interseccion    = interpoledHeight(collisionPoint.X, collisionPoint.Z, out collisionPointY);

            collisionPoint.Y = collisionPointY;
            return(interseccion);
        }
Exemple #23
0
        public Vector3 fireLauncher()
        {
            //Disparamos el arma, nos fijamos si colisiona con un enemigo, y si hay obstaculos en el medio
            TgcRay         ray                = new TgcRay(CustomFpsCamera.Instance.Position, CustomFpsCamera.Instance.LookAt - CustomFpsCamera.Instance.Position);
            Vector3        newPosition        = new Vector3(0, 0, 0);
            List <Vector3> posicionObstaculos = new List <Vector3>();

            foreach (TgcMesh obstaculo in vegetation)
            {
                if (TgcCollisionUtils.intersectRayAABB(ray, obstaculo.BoundingBox, out newPosition))
                {
                    posicionObstaculos.Add(newPosition);
                }
            }

            for (int i = enemies.Count - 1; i >= 0; i--)
            {
                if (TgcCollisionUtils.intersectRayAABB(ray, enemies[i].mesh.BoundingBox, out newPosition))
                {
                    posicionObstaculos.Add(newPosition);
                }
            }
            //////////////////////////disparo a barriles////////////////////////////////////////
            for (int i = barriles.Count - 1; i >= 0; i--)
            {
                if (TgcCollisionUtils.intersectRayAABB(ray, barriles[i].mesh.BoundingBox, out newPosition))
                {
                    posicionObstaculos.Add(newPosition);
                }
            }

            posicionObstaculos.Add(intersectRayTerrain(ray));

            posicionObstaculos.Sort(delegate(Vector3 x, Vector3 y)
            {
                return(distanciaACamara(x).CompareTo(distanciaACamara(y)));
            });

            Vector3 min = posicionObstaculos[0];

            return(min);
        }
Exemple #24
0
        public bool pointParallelipedXZColission(Parallelepiped par, TGCVector3 pos, float colissionLen)
        {
            var ray = new TgcRay();

            ray.Direction = new TGCVector3(1, 0, 0);
            ray.Origin    = pos + new TGCVector3(-colissionLen, 0, 0);

            if (par.intersectRay(ray, out float t, out TGCVector3 q) && t < 2f * colissionLen)
            {
                return(true);
            }

            ray.Direction = new TGCVector3(0, 0, 1);
            ray.Origin    = pos + new TGCVector3(0, 0, -colissionLen);

            if (par.intersectRay(ray, out t, out q) && t < 2f * colissionLen)
            {
                return(true);
            }
            return(false);
        }
Exemple #25
0
        public Vector3 intersectRayTerrain(TgcRay ray)
        {
            int     iteraciones = heightmapResolution / cantidadFilasColumnas * (int)currentScaleXZ;
            Vector3 dir         = ray.Direction;

            dir.Normalize();
            Vector3 origin = ray.Origin;
            Vector3 pos    = origin;
            float   y      = 0;

            for (int i = 0; i < iteraciones; i++)
            {
                interpoledHeight(pos.X, pos.Z, out y);
                if (FastMath.Abs(pos.Y - y) < 1f)
                {
                    return(pos);
                }
                pos += dir;
            }
            return(pos);
        }
Exemple #26
0
        private void Collide(TgcMesh elemento, Vehicle car)
        {
            //direccion a la que estoy yendo antes de chocar
            TGCVector3 directionOfCollision = car.GetDirectionOfCollision();
            TgcRay     ray = new TgcRay();

            ray.Origin    = car.GetLastPosition();
            ray.Direction = directionOfCollision;
            //interseco el rayo con el aabb, para conocer un punto del plano con el que colisione
            TgcBoundingAxisAlignBox.Face[] faces;
            faces = elemento.BoundingBox.computeFaces();
            TGCPlane   plane  = this.CreatePlane(ray, faces, car.GetLastPosition());
            TGCVector3 normal = GlobalConcepts.GetInstance().GetNormalPlane(plane);
            TGCVector3 output = normal + directionOfCollision * 2;
            float      angle  = car.SetDirection(output, normal);

            car.Crash(angle);

            while (TgcCollisionUtils.testObbAABB(car.GetTGCBoundingOrientedBox(), elemento.BoundingBox))
            {
                car.Translate(TGCMatrix.Translation(normal));
                car.Transform();
            }
        }
        /// <summary>
        /// Detección de colisiones recursiva
        /// </summary>
        public void doCollideWithWorld(TgcBoundingSphere characterSphere, Vector3 movementVector, List <TgcBoundingBox> obstaculos, int recursionDepth)
        {
            //Limitar recursividad
            if (recursionDepth > 5)
            {
                return;
            }

            //Ver si la distancia a recorrer es para tener en cuenta
            float distanceToTravelSq = movementVector.LengthSq();

            if (distanceToTravelSq < EPSILON)
            {
                return;
            }

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

            //Buscar el punto de colision mas cercano de todos los objetos candidatos
            float   minCollisionDistSq = float.MaxValue;
            Vector3 realMovementVector = movementVector;

            TgcBoundingBox.Face collisionFace     = null;
            TgcBoundingBox      collisionObstacle = null;
            Vector3             nearestPolygonIntersectionPoint = Vector3.Empty;

            foreach (TgcBoundingBox obstaculoBB in obstaculos)
            {
                //Obtener los polígonos que conforman las 6 caras del BoundingBox
                TgcBoundingBox.Face[] bbFaces = obstaculoBB.computeFaces();

                foreach (TgcBoundingBox.Face bbFace in bbFaces)
                {
                    Vector3 pNormal = TgcCollisionUtils.getPlaneNormal(bbFace.Plane);

                    TgcRay  movementRay = new TgcRay(originalSphereCenter, movementVector);
                    float   brutePlaneDist;
                    Vector3 brutePlaneIntersectionPoint;
                    if (!TgcCollisionUtils.intersectRayPlane(movementRay, bbFace.Plane, out brutePlaneDist, out brutePlaneIntersectionPoint))
                    {
                        continue;
                    }

                    float movementRadiusLengthSq = Vector3.Multiply(movementVector, characterSphere.Radius).LengthSq();
                    if (brutePlaneDist * brutePlaneDist > movementRadiusLengthSq)
                    {
                        continue;
                    }


                    //Obtener punto de colisión en el plano, según la normal del plano
                    float   pDist;
                    Vector3 planeIntersectionPoint;
                    Vector3 sphereIntersectionPoint;
                    TgcRay  planeNormalRay = new TgcRay(originalSphereCenter, -pNormal);
                    bool    embebbed       = false;
                    bool    collisionFound = false;
                    if (TgcCollisionUtils.intersectRayPlane(planeNormalRay, bbFace.Plane, out pDist, out planeIntersectionPoint))
                    {
                        //Ver si el plano está embebido en la esfera
                        if (pDist <= characterSphere.Radius)
                        {
                            embebbed = true;

                            //TODO: REVISAR ESTO, caso embebido a analizar con más detalle
                            sphereIntersectionPoint = originalSphereCenter - pNormal * characterSphere.Radius;
                        }
                        //Esta fuera de la esfera
                        else
                        {
                            //Obtener punto de colisión del contorno de la esfera según la normal del plano
                            sphereIntersectionPoint = originalSphereCenter - Vector3.Multiply(pNormal, characterSphere.Radius);

                            //Disparar un rayo desde el contorno de la esfera hacia el plano, con el vector de movimiento
                            TgcRay sphereMovementRay = new TgcRay(sphereIntersectionPoint, movementVector);
                            if (!TgcCollisionUtils.intersectRayPlane(sphereMovementRay, bbFace.Plane, out pDist, out planeIntersectionPoint))
                            {
                                //no hay colisión
                                continue;
                            }
                        }

                        //Ver si planeIntersectionPoint pertenece al polígono
                        Vector3 newMovementVector;
                        float   newMoveDistSq;
                        Vector3 polygonIntersectionPoint;
                        if (pointInBounbingBoxFace(planeIntersectionPoint, bbFace))
                        {
                            if (embebbed)
                            {
                                //TODO: REVISAR ESTO, nunca debería pasar
                                //throw new Exception("El polígono está dentro de la esfera");
                            }

                            polygonIntersectionPoint = planeIntersectionPoint;
                            collisionFound           = true;
                        }
                        else
                        {
                            //Buscar el punto mas cercano planeIntersectionPoint que tiene el polígono real de esta cara
                            polygonIntersectionPoint = TgcCollisionUtils.closestPointRectangle3d(planeIntersectionPoint,
                                                                                                 bbFace.Extremes[0], bbFace.Extremes[1], bbFace.Extremes[2]);

                            //Revertir el vector de velocidad desde el nuevo polygonIntersectionPoint para ver donde colisiona la esfera, si es que llega
                            Vector3 reversePointSeg = polygonIntersectionPoint - movementVector;
                            if (TgcCollisionUtils.intersectSegmentSphere(polygonIntersectionPoint, reversePointSeg, characterSphere, out pDist, out sphereIntersectionPoint))
                            {
                                collisionFound = true;
                            }
                        }

                        if (collisionFound)
                        {
                            //Nuevo vector de movimiento acotado
                            newMovementVector = polygonIntersectionPoint - sphereIntersectionPoint;
                            newMoveDistSq     = newMovementVector.LengthSq();

                            if (newMoveDistSq <= distanceToTravelSq && newMoveDistSq < minCollisionDistSq)
                            {
                                minCollisionDistSq = newMoveDistSq;
                                realMovementVector = newMovementVector;
                                nearestPolygonIntersectionPoint = polygonIntersectionPoint;
                                collisionFace     = bbFace;
                                collisionObstacle = obstaculoBB;
                            }
                        }
                    }
                }
            }

            //Si nunca hubo colisión, avanzar todo lo requerido
            if (collisionFace == null)
            {
                //Avanzar hasta muy cerca
                float movementLength = movementVector.Length();
                movementVector.Multiply((movementLength - EPSILON) / movementLength);
                characterSphere.moveCenter(movementVector);
                return;
            }

            //Solo movernos si ya no estamos muy cerca
            if (minCollisionDistSq >= EPSILON)
            {
                //Mover el BoundingSphere hasta casi la nueva posición real
                float movementLength = realMovementVector.Length();
                realMovementVector.Multiply((movementLength - EPSILON) / movementLength);
                characterSphere.moveCenter(realMovementVector);
            }



            //Calcular plano de Sliding
            Vector3 slidePlaneOrigin = nearestPolygonIntersectionPoint;
            Vector3 slidePlaneNormal = characterSphere.Center - nearestPolygonIntersectionPoint;

            slidePlaneNormal.Normalize();

            Plane slidePlane = Plane.FromPointNormal(slidePlaneOrigin, slidePlaneNormal);

            //Proyectamos el punto original de destino en el plano de sliding
            TgcRay  slideRay = new TgcRay(nearestPolygonIntersectionPoint + Vector3.Multiply(movementVector, slideFactor), slidePlaneNormal);
            float   slideT;
            Vector3 slideDestinationPoint;

            if (TgcCollisionUtils.intersectRayPlane(slideRay, slidePlane, out slideT, out slideDestinationPoint))
            {
                //Nuevo vector de movimiento
                Vector3 slideMovementVector = slideDestinationPoint - nearestPolygonIntersectionPoint;

                if (slideMovementVector.LengthSq() < EPSILON)
                {
                    return;
                }

                //Recursividad para aplicar sliding
                doCollideWithWorld(characterSphere, slideMovementVector, obstaculos, recursionDepth + 1);
            }
        }
Exemple #28
0
        public void update()
        {
            dir = TGCVector3.Empty;
            if (mode == -1)//cambiar por un switch
            {
                if (g.map.candlesPlaced > 0)
                {
                    mode = 3;
                }
                return;
            }
            else if (mode == 0)
            {
                //va hacia el jugador, la aceleracion salta entre + y - cada tanto
                speedToPlayer();
            }
            else if (mode == 1)
            {
                //mientras se lo este mirando no ataca al jugador, se queda cerca
                //@todo chequeo especial, antes se usaba los triangulos de la camara
                if (true)
                {
                    if (setObj)
                    {
                        setObj = false;

                        if (speed > 3500f)
                        {
                            speed -= g.game.ElapsedTime * acceleration;
                        }


                        //aca estoy consiguiendo un valor en un radio del jugador, mas o menos en la direccion que mira
                        //seguro que hay una forma mejor de calcular esto
                        obj = g.camera.cameraRotatedTarget * 100f
                              + TGCVector3.Cross(g.camera.cameraRotatedTarget * 100f, TGCVector3.Up) * g.map.Random.Next(-10000, 10000);
                        obj.Normalize();
                        obj *= 2000f + 1000 * g.hands.state;
                        obj += g.camera.eyePosition;
                    }
                    dir = obj - pos;
                    if (dir.Length() < 500f)
                    {
                        setObj = true;
                    }
                }
                else
                {
                    setObj = true;
                    speedToPlayer();
                }
            }
            else if (mode == 3)
            {
                //@todo se puede optimizar guardando la direccion de movimiento y una cantidad de pasos en vez
                //de tener objobj y calcular cada frame
                var lightMove = lightObjObj - lightObj;
                if (lightMove.Length() < 1000f)
                {
                    lightObjObj = new TGCVector2();
                    var rnd = g.map.Random;


                    lightObjObj.X = (float)rnd.NextDouble();
                    lightObjObj.Y = (float)rnd.NextDouble();
                    lightObjObj.Normalize();
                    lightObjObj *= (float)rnd.NextDouble() * 150000f;
                    lightObjObj += new TGCVector2(g.camera.eyePosition.X, g.camera.eyePosition.Z);

                    lightMove = lightObjObj - lightObj;
                }
                lightMove.Normalize();
                lightMove *= 5000f;
                lightObj  += lightMove * g.game.ElapsedTime;

                flyHeight = g.camera.terrainHeight(pos) + 2500f;
                dir.X     = lightObj.X - pos.X;
                dir.Y     = flyHeight - pos.Y;
                dir.Z     = lightObj.Y - pos.Z;


                var sightLine  = new TGCVector2(dir.X, dir.Z);
                var playerLine = new TGCVector2(g.camera.eyePosition.X - pos.X, g.camera.eyePosition.Z - pos.Z);
                sightLine.Normalize(); playerLine.Normalize();
                if (TGCVector2.Dot(sightLine, playerLine) >= .96)
                {
                    var sight = g.camera.Position - pos;
                    //detectar colisiones
                    timeInView += g.game.ElapsedTime;
                    if (timeInView > 1)
                    {
                        mode = 0;
                    }
                }
                else
                {
                    timeInView = 0;
                }
            }

            Console.WriteLine(mode);

            dir.Normalize();
            dir.Multiply(speed * (g.cameraSprites.squeletonHalfSpeed ? .0f : 1f)
                         * (g.map.candlesPlaced == g.cameraSprites.candlesRequired ? .2f : 1f)
                         * g.game.ElapsedTime);      //11000f

            colDir = new TGCVector3(dir.X, 0, dir.Z);
            colDir.Normalize();
            colDir *= 1000;

            //colDir.X = Math.Max(colDir.X, dir.X);
            //colDir.Z = Math.Max(colDir.Z, dir.Z);//puede que sea demasiado precavido esto


            cPos = pos + TGCVector3.Up * height;


            var chunk = g.chunks.fromCoordinates(pos);

            float      len = colDir.Length();
            float      t;
            TGCVector3 q;//esta porque c# me obliga

            var ray = new TgcRay();

            ray.Direction = colDir;
            ray.Origin    = cPos;


            var intersecRay = new Func <bool>(() =>
            {
                foreach (var mesh in chunk.meshes)
                {
                    if (mesh.paralleliped.intersectRay(ray, out t, out q) && t < len)
                    {
                        return(true);
                    }
                }
                foreach (var multimesh in chunk.multimeshes)
                {
                    foreach (var par in multimesh.parallelipeds)
                    {
                        if (par.intersectRay(ray, out t, out q) && t < len)
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            });


            if (intersecRay())
            {
                swithSideTimer = 0f;
                setObj         = true;

                ray.Direction = TGCVector3.Cross(colDir, TGCVector3.Up) * sidePref;
                if (intersecRay())
                {
                    ray.Direction = -ray.Direction;
                    if (intersecRay())
                    {
                        dir = -dir;
                    }
                    else
                    {
                        dir = -TGCVector3.Cross(dir, TGCVector3.Up) * sidePref;
                    }
                    sidePref = -sidePref;
                }
                else
                {
                    dir = TGCVector3.Cross(dir, TGCVector3.Up) * sidePref;
                }
            }
            else
            {
                //si no hay nada enfrente mirar al jugador
                swithSideTimer += g.game.ElapsedTime;
                if (swithSideTimer > 3f)
                {
                    swithSideTimer = 0;
                    sidePref       = -sidePref;
                }


                lookAt = new TGCVector3(dir.X, 0, dir.Z);
                lookAt.Normalize();
                lookin = new TGCVector3(0, 0, -1);
            }


            pos += dir;
            //Logger.Log(rot);

            musica.Position = pos;
            g.game.DirectSound.Listener3d.Position = g.camera.eyePosition;
        }
        /// <summary>
        /// Detección de colisiones recursiva
        /// </summary>
        public void doCollideWithWorld(TgcBoundingSphere characterSphere, Vector3 movementVector, List<IColisionable> obstaculos, int recursionDepth, ColisionInfo colisionInfo)
        {
            //Limitar recursividad
            if (recursionDepth > 5)
            {
                return;
            }

            //Ver si la distancia a recorrer es para tener en cuenta
            float distanceToTravelSq = movementVector.LengthSq();

            if (distanceToTravelSq < EPSILON)
            {
                return;
            }

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

            //Buscar el punto de colision mas cercano de todos los objetos candidatos
            float minCollisionDistSq = float.MaxValue;
            Vector3 realMovementVector = movementVector;
            TgcBoundingAxisAlignBox.Face collisionFace = null;
            IColisionable collisionObstacle = null;
            Vector3 nearestPolygonIntersectionPoint = Vector3.Empty;
            foreach (IColisionable obstaculoBB in obstaculos)
            {
                //Obtener los polígonos que conforman las 6 caras del BoundingBox
                TgcBoundingAxisAlignBox.Face[] bbFaces = obstaculoBB.GetTgcBoundingBox().computeFaces();

                foreach (TgcBoundingAxisAlignBox.Face bbFace in bbFaces)
                {
                    Vector3 pNormal = TgcCollisionUtils.getPlaneNormal(bbFace.Plane);

                    TgcRay movementRay = new TgcRay(originalSphereCenter, movementVector);
                    float brutePlaneDist;
                    Vector3 brutePlaneIntersectionPoint;
                    if (!TgcCollisionUtils.intersectRayPlane(movementRay, bbFace.Plane, out brutePlaneDist, out brutePlaneIntersectionPoint))
                    {
                        continue;
                    }

                    float movementRadiusLengthSq = Vector3.Multiply(movementVector, characterSphere.Radius).LengthSq();
                    if (brutePlaneDist * brutePlaneDist > movementRadiusLengthSq)
                    {
                        continue;
                    }

                    //Obtener punto de colisión en el plano, según la normal del plano
                    float pDist;
                    Vector3 planeIntersectionPoint;
                    Vector3 sphereIntersectionPoint;
                    TgcRay planeNormalRay = new TgcRay(originalSphereCenter, -pNormal);
                    bool embebbed = false;
                    bool collisionFound = false;
                    if (TgcCollisionUtils.intersectRayPlane(planeNormalRay, bbFace.Plane, out pDist, out planeIntersectionPoint))
                    {
                        //Ver si el plano está embebido en la esfera
                        if (pDist <= characterSphere.Radius)
                        {
                            embebbed = true;

                            //TODO: REVISAR ESTO, caso embebido a analizar con más detalle
                            sphereIntersectionPoint = originalSphereCenter - pNormal * characterSphere.Radius;
                        }
                        //Esta fuera de la esfera
                        else
                        {
                            //Obtener punto de colisión del contorno de la esfera según la normal del plano
                            sphereIntersectionPoint = originalSphereCenter - Vector3.Multiply(pNormal, characterSphere.Radius);

                            //Disparar un rayo desde el contorno de la esfera hacia el plano, con el vector de movimiento
                            TgcRay sphereMovementRay = new TgcRay(sphereIntersectionPoint, movementVector);
                            if (!TgcCollisionUtils.intersectRayPlane(sphereMovementRay, bbFace.Plane, out pDist, out planeIntersectionPoint))
                            {
                                //no hay colisión
                                continue;
                            }
                        }

                        //Ver si planeIntersectionPoint pertenece al polígono
                        Vector3 newMovementVector;
                        float newMoveDistSq;
                        Vector3 polygonIntersectionPoint;
                        if (pointInBounbingBoxFace(planeIntersectionPoint, bbFace))
                        {
                            if (embebbed)
                            {
                                //TODO: REVISAR ESTO, nunca debería pasar
                                //throw new Exception("El polígono está dentro de la esfera");
                            }

                            polygonIntersectionPoint = planeIntersectionPoint;
                            collisionFound = true;
                        }
                        else
                        {
                            //Buscar el punto mas cercano planeIntersectionPoint que tiene el polígono real de esta cara
                            polygonIntersectionPoint = TgcCollisionUtils.closestPointRectangle3d(planeIntersectionPoint,
                                bbFace.Extremes[0], bbFace.Extremes[1], bbFace.Extremes[2]);

                            //Revertir el vector de velocidad desde el nuevo polygonIntersectionPoint para ver donde colisiona la esfera, si es que llega
                            Vector3 reversePointSeg = polygonIntersectionPoint - movementVector;
                            if (TgcCollisionUtils.intersectSegmentSphere(polygonIntersectionPoint, reversePointSeg, characterSphere, out pDist, out sphereIntersectionPoint))
                            {
                                collisionFound = true;
                            }
                        }

                        if (collisionFound)
                        {
                            //Nuevo vector de movimiento acotado
                            newMovementVector = polygonIntersectionPoint - sphereIntersectionPoint;
                            newMoveDistSq = newMovementVector.LengthSq();

                            //se colisiono con algo, lo agrego a la lista
                            colisionInfo.Add(obstaculoBB);

                            if (newMoveDistSq <= distanceToTravelSq && newMoveDistSq < minCollisionDistSq)
                            {
                                minCollisionDistSq = newMoveDistSq;
                                realMovementVector = newMovementVector;
                                nearestPolygonIntersectionPoint = polygonIntersectionPoint;
                                collisionFace = bbFace;
                                collisionObstacle = obstaculoBB;

                            }
                        }
                    }
                }
            }

            //Si nunca hubo colisión, avanzar todo lo requerido
            if (collisionFace == null)
            {
                //Avanzar hasta muy cerca
                float movementLength = movementVector.Length();
                movementVector.Multiply((movementLength - EPSILON) / movementLength);
                characterSphere.moveCenter(movementVector);
                return;
            }

            //Solo movernos si ya no estamos muy cerca
            if (minCollisionDistSq >= EPSILON)
            {
                //Mover el BoundingSphere hasta casi la nueva posición real
                float movementLength = realMovementVector.Length();
                realMovementVector.Multiply((movementLength - EPSILON) / movementLength);
                characterSphere.moveCenter(realMovementVector);
            }

            //Calcular plano de Sliding
            Vector3 slidePlaneOrigin = nearestPolygonIntersectionPoint;
            Vector3 slidePlaneNormal = characterSphere.Center - nearestPolygonIntersectionPoint;
            slidePlaneNormal.Normalize();

            Plane slidePlane = Plane.FromPointNormal(slidePlaneOrigin, slidePlaneNormal);

            //Proyectamos el punto original de destino en el plano de sliding
            TgcRay slideRay = new TgcRay(nearestPolygonIntersectionPoint + Vector3.Multiply(movementVector, slideFactor), slidePlaneNormal);
            float slideT;
            Vector3 slideDestinationPoint;

            if (TgcCollisionUtils.intersectRayPlane(slideRay, slidePlane, out slideT, out slideDestinationPoint))
            {
                //Nuevo vector de movimiento
                Vector3 slideMovementVector = slideDestinationPoint - nearestPolygonIntersectionPoint;

                if (slideMovementVector.LengthSq() < EPSILON)
                {
                    return;
                }

                //Recursividad para aplicar sliding
                doCollideWithWorld(characterSphere, slideMovementVector, obstaculos, recursionDepth + 1, colisionInfo);
            }

            return;
        }
Exemple #30
0
        public bool ColisionDisparo(TgcRay disparo)
        {
            Vector3 interseccion;
            float   distancia;

            foreach (Enemigo enemigo in enemigos.ListaDeEnemigosOrdenadaPorDistancia())
            {
                if (TgcCollisionUtils.intersectRayAABB(disparo, enemigo.BoundingBoxEnemigo(), out interseccion))
                {
                    enemigo.Herir(damage_Body, interseccion);

                    if (enemigo.Murio())
                    {
                        enemigo.Muriendo     = true;
                        this.jugador.puntos += 10;
                    }

                    this.jugador.puntos += 1;
                    return(true);
                }

                if (TgcCollisionUtils.intersectRaySphere(disparo, enemigo.BoundingBoxCabeza(), out distancia, out interseccion))
                {
                    enemigo.Herir(damage_Head, interseccion);

                    if (enemigo.Murio())
                    {
                        enemigo.Muriendo     = true;
                        this.jugador.puntos += 10;
                    }

                    this.jugador.puntos += 2;
                    return(true);
                }
            }

            foreach (TgcMesh barril in escenario.BarrilesExplosivos())
            {
                if (TgcCollisionUtils.intersectRayAABB(disparo, barril.BoundingBox, out interseccion))
                {
                    //Se podria hacer un objeto barril, por ahora meto el código acá. -Alex
                    //Hasta aca ya sabemos que el disparo le dio al barril.
                    float d, xc, zc;
                    xc = barril.Position.X;
                    zc = barril.Position.Z;

                    var listaDeEnemigos = enemigos.ListaDeEnemigos();

                    foreach (var enemigo in listaDeEnemigos)
                    {
                        //Calculo la distancia hasta el barril
                        d = FastMath.Sqrt(FastMath.Pow2(enemigo.Position().X - xc) + FastMath.Pow2(enemigo.Position().Z - zc));

                        //Me fijo si cumple con el radio (si tenemos el objeto barril, cada barril puede tener su radio)
                        if (d <= 300) //Radio hardcodeado
                        {
                            enemigo.Herir(300 / (0.05F * d), interseccion);

                            if (enemigo.Murio())
                            {
                                enemigo.Muriendo     = true;
                                this.jugador.puntos += 10;
                            }
                        }
                    }

                    //Aparte, el barril exploto...
                    sound_Explosion.play();

                    escenario.BorrarObjeto(barril.Name);
                    return(true);
                }
            }

            return(false);
        }
Exemple #31
0
        public void Update(float elapsedTime)
        {
            // correr
            if (GuiController.Instance.D3dInput.keyPressed(Microsoft.DirectX.DirectInput.Key.LeftShift))
            {
                camera.MovementSpeed = RUNNING_SPEED;
            }
            else if (GuiController.Instance.D3dInput.keyUp(Microsoft.DirectX.DirectInput.Key.LeftShift))
            {
                camera.MovementSpeed = WALKING_SPEED;
            }


            /*Si se movio, chequeo colisiones con objetos... Esto no funciona como debería, aparte no podemos atajar el movimiento antes de renderearlo y queda medio feo.
             * para solucionarlo tendríamos que hacer que la camara sigua al mesh (es decir, que el mesh sea el que se mueve con WASD) y ahí podemos atajar la colision antes
             * El otro problema es como se genera el bounding box del mesh, deje seteado para que se renderize el mesh del sniper así lo ven, solucionar esto CREO que es facil
             */

            if (!posicionSegura.Equals(camera.getPosition()))
            {
                if (moviendo == false)
                {
                    elapsedMOVE = 0.0f;
                    moviendo    = true;
                }
                else
                {
                    elapsedMOVE += elapsedTime;
                }

                if (ColisionesAdmin.Instance.ColisionConObjetos())
                {
                    camera.move(posicionSegura - camera.getPosition());
                }
                else
                {
                    posicionSegura = camera.getPosition();
                }
            }
            else
            {
                moviendo = false;
            }

            if (ColisionesAdmin.Instance.ColisionConEnemigos())
            {
                this.vidas -= 1;
                sound_Die.play();
                camera.move(posicionInicial - camera.getPosition());
            }

            // Disparo

            if (!puedeDisparar)
            {
                elapsedROF += elapsedTime;
            }
            if (elapsedROF >= ROF)
            {
                puedeDisparar = true;
            }

            if (GuiController.Instance.D3dInput.buttonPressed(TgcViewer.Utils.Input.TgcD3dInput.MouseButtons.BUTTON_LEFT))
            {
                if (ammo != 0)
                {
                    if (puedeDisparar)
                    {
                        TgcRay disparo = new TgcRay(camera.getPosition(), Vector3.Subtract(camera.getLookAt(), camera.getPosition()));

                        if (ColisionesAdmin.Instance.ColisionDisparo(disparo))
                        {
                            sound_Hit.play();
                        }


                        sound_Disparo.play();
                        puedeDisparar = false;
                        elapsedROF    = 0;
                        ammo--;
                    }
                }
                else
                {
                    sound_DryFire.play();
                }
            }


            // Activa el scope
            if (GuiController.Instance.D3dInput.buttonPressed(TgcViewer.Utils.Input.TgcD3dInput.MouseButtons.BUTTON_RIGHT))
            {
                // Me fijo el estado del scope, cambio la matriz de proyeccion y la velocidad de rotación del mouse
                // (para disminuir la sens y que el mouse no vuele con el zoom)

                //Reproduzco el sonido del zoom
                sound_Zoom.play();

                scope = !scope;

                if (scope)
                {
                    zoom = zoomBase;
                    camera.RotationSpeed = ROTATION_SPEED_SCOPE;
                }
                else
                {
                    zoom = 1;
                    camera.RotationSpeed = ROTATION_SPEED_NO_SCOPE;
                }
            }

            // Zoom con la rueda del mouse, SOLO si el scope esta activado
            if (scope)
            {
                if (GuiController.Instance.D3dInput.WheelPos > 0)
                {
                    zoom += zoomWheel;
                }
                if (GuiController.Instance.D3dInput.WheelPos < 0)
                {
                    zoom -= zoomWheel;
                }

                if (GuiController.Instance.D3dInput.WheelPos != 0 && zoom <= (zoomBase + zoomMaximo * zoomWheel) && zoom >= 1)
                {
                    sound_Zoom.play();
                }


                if (zoom > zoomBase + (zoomWheel * zoomMaximo))
                {
                    zoom = zoomBase + (zoomWheel * zoomMaximo);
                }
                if (zoom < zoomBase)
                {
                    zoom = zoomBase;
                }
            }
            else
            {
                UpdateRifle();
            }

            matrizConZoom.M11 = matrizSinZoom.M11 * zoom;
            matrizConZoom.M22 = matrizSinZoom.M22 * zoom;

            GuiController.Instance.D3dDevice.Transform.Projection = matrizConZoom;
        }