Ejemplo n.º 1
0
        public OctreeNode crearOctree(List<TgcMesh> modelos, TgcBoundingBox sceneBounds)
        {
            OctreeNode rootNode = new OctreeNode();

            Vector3 pMax = sceneBounds.PMax;
            Vector3 pMin = sceneBounds.PMin;

            //Calcular punto medio y centro
            Vector3 midSize = sceneBounds.calculateAxisRadius();
            Vector3 center = sceneBounds.calculateBoxCenter();

            //iniciar generacion recursiva de octree
            doSectorOctreeX(rootNode, center, midSize, 0, modelos);

            //podar nodos innecesarios
            deleteEmptyNodes(rootNode.children);

            //eliminar hijos que subdividen sin necesidad
            //deleteSameMeshCountChilds(rootNode);

            //imprimir por consola el octree
            //printDebugOctree(rootNode);

            //imprimir estadisticas de debug
            //printEstadisticasOctree(rootNode);

            return rootNode;
        }
        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);
        }
Ejemplo n.º 3
0
        public Grid(MeshCreatorControl control)
        {
            this.control = control;

            //El bounding box del piso es bien grande para hacer colisiones
            boundingBox = new TgcBoundingBox(new Vector3(-BIG_VAL, -SMALL_VAL, -BIG_VAL), new Vector3(BIG_VAL, 0, BIG_VAL));

            //Planos para colision de picking
            pickingXZAabb = new TgcBoundingBox(new Vector3(-BIG_VAL, -SMALL_VAL, -BIG_VAL), new Vector3(BIG_VAL, 0, BIG_VAL));
            pickingXYAabb = new TgcBoundingBox(new Vector3(-BIG_VAL, -BIG_VAL, -SMALL_VAL), new Vector3(BIG_VAL, BIG_VAL, 0));
            pickingYZAabb = new TgcBoundingBox(new Vector3(-SMALL_VAL, -BIG_VAL, -BIG_VAL), new Vector3(0, BIG_VAL, BIG_VAL));

            vertices = new CustomVertex.PositionColored[12 * 2 * 2];
            int color = Color.FromArgb(76, 76, 76).ToArgb();

            //10 lineas horizontales en X
            for (int i = 0; i < 11; i++)
            {
                vertices[i * 2] = new CustomVertex.PositionColored(-GRID_RADIUS, 0, -GRID_RADIUS + LINE_SEPARATION * i, color);
                vertices[i * 2 + 1] = new CustomVertex.PositionColored(GRID_RADIUS, 0, -GRID_RADIUS + LINE_SEPARATION * i, color);
            }

            //10 lineas horizontales en Z
            for (int i = 11; i < 22; i++)
            {
                vertices[i * 2] = new CustomVertex.PositionColored(-GRID_RADIUS * 3 + LINE_SEPARATION * i - LINE_SEPARATION, 0, -GRID_RADIUS, color);
                vertices[i * 2 + 1] = new CustomVertex.PositionColored(-GRID_RADIUS * 3 + LINE_SEPARATION * i - LINE_SEPARATION, 0, GRID_RADIUS, color);
            }
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Crear Collider a partir de BoundingBox.
 /// Crea el BoundingSphere del Collider.
 /// </summary>
 /// <param name="mesh">BoundingBox</param>
 /// <returns>Collider creado</returns>
 public static BoundingBoxCollider fromBoundingBox(TgcBoundingBox aabb)
 {
     BoundingBoxCollider collider = new BoundingBoxCollider();
     collider.aabb = aabb;
     collider.BoundingSphere = TgcBoundingSphere.computeFromPoints(aabb.computeCorners()).toClass();
     return collider;
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Crea una caja vacia
        /// </summary>
        public TgcBox()
        {
            Device d3dDevice = GuiController.Instance.D3dDevice;

            vertices     = new CustomVertex.PositionColoredTextured[36];
            vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionColoredTextured), vertices.Length, d3dDevice,
                                            Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColoredTextured.Format, Pool.Default);

            this.autoTransformEnable = true;
            this.transform           = Matrix.Identity;
            this.translation         = new Vector3(0, 0, 0);
            this.rotation            = new Vector3(0, 0, 0);
            this.enabled             = true;
            this.color            = Color.White;
            this.alphaBlendEnable = false;
            this.uvOffset         = new Vector2(0, 0);
            this.uvTiling         = new Vector2(1, 1);

            //BoundingBox
            boundingBox = new TgcBoundingBox();

            //Shader
            this.effect    = GuiController.Instance.Shaders.VariosShader;
            this.technique = TgcShaders.T_POSITION_COLORED;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Crea una caja vacia
        /// </summary>
        public TgcBox()
        {
            Device d3dDevice = GuiController.Instance.D3dDevice;

            vertices = new CustomVertex.PositionColoredTextured[36];
            vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionColoredTextured), vertices.Length, d3dDevice,
                Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColoredTextured.Format, Pool.Default);

            this.autoTransformEnable = true;
            this.transform = Matrix.Identity;
            this.translation = new Vector3(0,0,0);
            this.rotation = new Vector3(0,0,0);
            this.enabled = true;
            this.color = Color.White;
            this.alphaBlendEnable = false;
            this.uvOffset = new Vector2(0, 0);
            this.uvTiling = new Vector2(1, 1);

            //BoundingBox
            boundingBox = new TgcBoundingBox();

            //Shader
            this.effect = GuiController.Instance.Shaders.VariosShader;
            this.technique = TgcShaders.T_POSITION_COLORED;
        }
Ejemplo n.º 7
0
        public EscenarioManager()
        {
            EscenarioManager.Instance = this;

            sonido = SoundManager.getInstance();
            arboles = new List<TgcMesh>();
            pasto = new List<TgcMesh>();
            barriles = new List<Barril>();
            loader = new TgcSceneLoader();

            casillasPorEje = 50;
            divisionesPiso = new Vector3[2500];
            _random = new Random();

            piso = new TgcBox();
            piso.UVTiling = new Vector2(300, 300);
            pisoSize = (int) tamanio;
            piso.setPositionSize(new Vector3(0, 0, 0), new Vector3(pisoSize*2, 0, pisoSize*2));
            piso.updateValues();

            piso.setTexture(TgcTexture.createTexture(GuiController.Instance.D3dDevice, GuiController.Instance.AlumnoEjemplosMediaDir + "\\RenderMan\\texturas\\nieve.png"));

            generarSkyBox();

            colisionables = new List<TgcBoundingCylinder>();

            limites = new TgcBoundingBox(new Vector3(-tamanio, 0, -tamanio), new Vector3(tamanio, 5000, tamanio));

            GuiController.Instance.Modifiers.addInt("Viento en X", 0, 30, 5);
            GuiController.Instance.Modifiers.addInt("Viento en Z", 0, 30, 5);
        }
Ejemplo n.º 8
0
 public TgcSkeletalAnimation(string name, int frameRate, int framesCount, List<TgcSkeletalAnimationFrame>[] boneFrames, TgcBoundingBox boundingBox)
 {
     this.name = name;
     this.frameRate = frameRate;
     this.framesCount = framesCount;
     this.boneFrames = boneFrames;
     this.boundingBox = boundingBox;
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Clasifica un BoundingBox respecto de un Plano.
        /// </summary>
        /// <param name="plane">Plano</param>
        /// <param name="aabb">BoundingBox</param>
        /// <returns>
        /// Resultado de la clasificación.
        /// </returns>
        ///
        public static PlaneBoxResult classifyPlaneAABB(Plane plane, TgcBoundingBox aabb)
        {
            Vector3 vmin = Vector3.Empty;
            Vector3 vmax = Vector3.Empty;

            //Obtener puntos minimos y maximos en base a la dirección de la normal del plano
            if (plane.A >= 0f)
            {
                vmin.X = aabb.PMin.X;
                vmax.X = aabb.PMax.X;
            }
            else
            {
                vmin.X = aabb.PMax.X;
                vmax.X = aabb.PMin.X;
            }

            if (plane.B >= 0f)
            {
                vmin.Y = aabb.PMin.Y;
                vmax.Y = aabb.PMax.Y;
            }
            else
            {
                vmin.Y = aabb.PMax.Y;
                vmax.Y = aabb.PMin.Y;
            }

            if (plane.C >= 0f)
            {
                vmin.Z = aabb.PMin.Z;
                vmax.Z = aabb.PMax.Z;
            }
            else
            {
                vmin.Z = aabb.PMax.Z;
                vmax.Z = aabb.PMin.Z;
            }

            //Analizar punto minimo y maximo contra el plano
            PlaneBoxResult result;

            if (plane.Dot(vmin) > 0f)
            {
                result = PlaneBoxResult.IN_FRONT_OF;
            }
            else if (plane.Dot(vmax) > 0f)
            {
                result = PlaneBoxResult.INTERSECT;
            }
            else
            {
                result = PlaneBoxResult.BEHIND;
            }

            return(result);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Indica si un BoundingSphere colisiona con un BoundingBox.
        /// </summary>
        /// <param name="sphere">BoundingSphere</param>
        /// <param name="aabb">BoundingBox</param>
        /// <returns>True si hay colisión</returns>
        public static bool testSphereAABB(TgcBoundingSphere sphere, TgcBoundingBox aabb)
        {
            //Compute squared distance between sphere center and AABB
            float sqDist = TgcCollisionUtils.sqDistPointAABB(sphere.Center, aabb);

            //Sphere and AABB intersect if the (squared) distance
            //between them is less than the (squared) sphere radius
            return(sqDist <= sphere.Radius * sphere.Radius);
        }
Ejemplo n.º 11
0
        public SmartTerrain()
        {
            enabled = true;
            alphaBlendEnable = false;

            //Shader
            Effect = TgcShaders.loadEffect(GuiController.Instance.ExamplesDir + "TerrainEditor\\Shaders\\EditableTerrain.fx");
            Technique = "PositionColoredTextured";

            aabb = new TgcBoundingBox();
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Crear un BoundingBox igual a este
        /// </summary>
        /// <returns>BoundingBox clonado</returns>
        public TgcBoundingBox clone()
        {
            TgcBoundingBox cloneBbox = new TgcBoundingBox();

            cloneBbox.pMin         = this.pMin;
            cloneBbox.pMax         = this.pMax;
            cloneBbox.pMinOriginal = this.pMinOriginal;
            cloneBbox.pMaxOriginal = this.pMaxOriginal;

            return(cloneBbox);
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Crea una pared vacia.
 /// </summary>
 public TgcPlaneWall()
 {
     this.vertices         = new CustomVertex.PositionTextured[6];
     this.autoAdjustUv     = false;
     this.enabled          = true;
     this.boundingBox      = new TgcBoundingBox();
     this.uTile            = 1;
     this.vTile            = 1;
     this.alphaBlendEnable = false;
     this.uvOffset         = new Vector2(0, 0);
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Crea una pared vacia.
 /// </summary>
 public TgcPlaneWall()
 {
     this.vertices = new CustomVertex.PositionTextured[6];
     this.autoAdjustUv = false;
     this.enabled = true;
     this.boundingBox = new TgcBoundingBox();
     this.uTile = 1;
     this.vTile = 1;
     this.alphaBlendEnable = false;
     this.uvOffset = new Vector2(0, 0);
 }
Ejemplo n.º 15
0
        /// <summary>
        /// Dibujar meshes que representan los sectores del Quadtree
        /// </summary>
        public List<TgcDebugBox> createDebugQuadtreeMeshes(QuadtreeNode rootNode, TgcBoundingBox sceneBounds)
        {
            Vector3 pMax = sceneBounds.PMax;
            Vector3 pMin = sceneBounds.PMin;

            List<TgcDebugBox> debugBoxes = new List<TgcDebugBox>();
            doCreateQuadtreeDebugBox(rootNode, debugBoxes,
                pMin.X, pMin.Y, pMin.Z,
                pMax.X, pMax.Y, pMax.Z, 0);

            return debugBoxes;
        }
Ejemplo n.º 16
0
        public SimpleTerrain()
        {
            enabled = true;
            alphaBlendEnable = false;

            //BoundingBox
            boundingBox = new TgcBoundingBox();

            //Shader
            this.effect = GuiController.Instance.Shaders.VariosShader;
            this.technique = TgcShaders.T_POSITION_TEXTURED;
        }
Ejemplo n.º 17
0
        public SmartTerrain()
        {
            enabled = true;
            alphaBlendEnable = false;

            //Shader
            //Effect = TgcShaders.loadEffect(GuiController.Instance.ExamplesDir + "TerrainEditor\\Shaders\\EditableTerrain.fx");
            //Effect = TgcShaders.loadEffect(GuiController.Instance.AlumnoEjemplosMediaDir + "shader_agua.fx");
            //Technique = "RenderAgua";//"PositionColoredTextured";

            aabb = new TgcBoundingBox();
        }
Ejemplo n.º 18
0
 public LightData(TgcMeshData meshData)
 {
     this.color = parserColor(meshData.userProperties["color"]);
             this.aabb = new TgcBoundingBox(TgcParserUtils.float3ArrayToVector3(meshData.pMin), TgcParserUtils.float3ArrayToVector3(meshData.pMax));
             this.pos = this.aabb.calculateBoxCenter();
             this.spot = meshData.userProperties["esSpot"].Equals("SI");
             this.direccion = convertirDireccion(meshData.userProperties["dir"]);
             this.intencidad = float.Parse(meshData.userProperties["inten"]);
             this.atenuacion = float.Parse(meshData.userProperties["atenua"])/10;
             this.angleCos = float.Parse(meshData.userProperties["angleCos"]);
             this.exp = float.Parse(meshData.userProperties["exp"]);
 }
        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 Tree(Vector3 position, Vector3 scale, Vector3 rotation)
     : base(MESH_PATH, position, scale, rotation)
 {
                 
     //Hago que el bounding box sólo cubra el tronco
     this.boundingBox = mesh.BoundingBox.clone();
     Vector3 bBScale = new Vector3(0.09f * scale.X, 1f * scale.Y, 0.09f * scale.Z);
     this.boundingBox.scaleTranslate(position, bBScale);
     center = this.boundingBox.calculateBoxCenter();
     radius = this.boundingBox.calculateBoxRadius();
   
 }
Ejemplo n.º 21
0
        /// <summary>
        /// Crear una nueva grilla
        /// </summary>
        /// <param name="modelos">Modelos a contemplar</param>
        /// <param name="sceneBounds">Límites del escenario</param>
        public void create(List<TgcMesh> modelos, TgcBoundingBox sceneBounds)
        {
            this.modelos = modelos;
            this.sceneBounds = sceneBounds;

            //build
            grid = buildGrid(modelos, sceneBounds, new Vector3(CELL_WIDTH, CELL_HEIGHT, CELL_LENGTH));

            foreach (TgcMesh mesh in modelos)
            {
                mesh.Enabled = false;
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Indica si un Plano colisiona con un BoundingBox
        /// </summary>
        /// <param name="plane">Plano</param>
        /// <param name="aabb">BoundingBox</param>
        /// <returns>True si hay colisión.</returns>
        public static bool testPlaneAABB(Plane plane, TgcBoundingBox aabb)
        {
            Vector3 c = (aabb.PMax + aabb.PMin) * 0.5f; // Compute AABB center
            Vector3 e = aabb.PMax - c;                  // Compute positive extents

            // Compute the projection interval radius of b onto L(t) = b.c + t * p.n
            float r = e.X * FastMath.Abs(plane.A) + e.Y * FastMath.Abs(plane.B) + e.Z * FastMath.Abs(plane.C);
            // Compute distance of box center from plane
            float s = plane.Dot(c);

            // Intersection occurs when distance s falls within [-r,+r] interval
            return(FastMath.Abs(s) <= r);
        }
Ejemplo n.º 23
0
        public Barril(Vector3 position)
        {
            this.mesh = Barril.getMesh();
            this.mesh.Position = position;
            this.mesh.Scale = new Vector3(0.6f, 0.7f, 0.6f);
            this.mesh.AlphaBlendEnable = true;
            cilindro = new TgcBoundingCylinder(position, 10, 150);
            this.mesh.updateBoundingBox();
            BoundigBox = this.mesh.BoundingBox;

            explosion = new Explosion(position);
            humo = new Humo(this.mesh.Position);
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Crear nuevo Quadtree
        /// </summary>
        /// <param name="modelos">Modelos a optimizar</param>
        /// <param name="sceneBounds">Límites del escenario</param>
        public void create(List<TgcMesh> modelos, TgcBoundingBox sceneBounds)
        {
            this.modelos = modelos;
            this.sceneBounds = sceneBounds;

            //Crear Quadtree
            this.quadtreeRootNode = builder.crearQuadtree(modelos, sceneBounds);

            //Deshabilitar todos los mesh inicialmente
            foreach (TgcMesh mesh in modelos)
            {
                mesh.Enabled = false;
            }
        }
        public TerrainPatch(DivisibleTerrain father, CustomVertex.PositionTextured[] data, TgcBoundingBox bb)
        {
            this.father = father;
            totalVertices = data.Length;
            this.BoundingBox = bb;
            this.vbTerrainPatch  = new VertexBuffer(typeof(CustomVertex.PositionTextured), data.Length, GuiController.Instance.D3dDevice, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionTextured.Format, Pool.Default);
            this.Effect = father.Effect;
            this.Technique = father.Technique;
            this.Enabled = father.Enabled;
            this.RenderBB = false;
            vbTerrainPatch.SetData(data, 0, LockFlags.None);

            
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Crea una pared vacia.
        /// </summary>
        public TgcPlaneWall()
        {
            this.vertices         = new CustomVertex.PositionTextured[6];
            this.autoAdjustUv     = false;
            this.enabled          = true;
            this.boundingBox      = new TgcBoundingBox();
            this.uTile            = 1;
            this.vTile            = 1;
            this.alphaBlendEnable = false;
            this.uvOffset         = new Vector2(0, 0);

            //Shader
            this.effect    = GuiController.Instance.Shaders.VariosShader;
            this.technique = TgcShaders.T_POSITION_TEXTURED;
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Crea una pared vacia.
        /// </summary>
        public TgcPlaneWall()
        {
            this.vertices = new CustomVertex.PositionTextured[6];
            this.autoAdjustUv = false;
            this.enabled = true;
            this.boundingBox = new TgcBoundingBox();
            this.uTile = 1;
            this.vTile = 1;
            this.alphaBlendEnable = false;
            this.uvOffset = new Vector2(0, 0);

            //Shader
            this.effect = GuiController.Instance.Shaders.VariosShader;
            this.technique = TgcShaders.T_POSITION_TEXTURED;
        }
        public ManejadorColisiones(Camara camara, List<TgcBoundingBox> obstEscenario)
        {
            this.fpsCamara = camara;

            velSalto = 80.0f;
            gravedad = 80.0f;

            velocidad = new Vector3();
            antCamPos = Vector3.Empty;
            time = 0;
            firstTime = true;
            jugadorPriPers = new TgcBoundingBox(new Vector3(-20, -60, -20), new Vector3(20, 20, 20));

            obstaculos = obstEscenario;
        }
Ejemplo n.º 29
0
        public override void Init()
        {
            //seteamos atributos particulares de las naves
            health = 50;
            score = 2;
            tiempoMuerte = 5f;
            Device d3dDevice = GuiController.Instance.D3dDevice;
            MESH_SCALE = 0.5f;
            attackDamage = 50;
            MOVEMENT_SPEED = 225f;
            //cargamos el mesh
            //las naves no tienen skeletalMesh
            this.mesh = GameManager.Instance.ModeloNave.clone("Nave");

            SPAWN_HEIGHT = 1000f;
            giroInicial = Matrix.RotationY(0);

            //realizamos el init() comun a todos los enemigos
            base.Init();

            mesh.Effect = GameManager.Instance.envMap;
            mesh.Technique = "SimpleEnvironmentMapTechnique";
            mesh.Effect.SetValue("lightColor", ColorValue.FromColor(Color.White));
            mesh.Effect.SetValue("lightPosition", TgcParserUtils.vector3ToFloat4Array(new Vector3(0,1400,0)));
            mesh.Effect.SetValue("eyePosition", TgcParserUtils.vector3ToFloat4Array(CustomFpsCamera.Instance.getPosition()));
            mesh.Effect.SetValue("lightIntensity", 0.3f);
            mesh.Effect.SetValue("lightAttenuation", 1.0f);
            mesh.Effect.SetValue("reflection", 0.65f);

            //Cargar variables de shader de Material. El Material en realidad deberia ser propio de cada mesh. Pero en este ejemplo se simplifica con uno comun para todos
            mesh.Effect.SetValue("materialEmissiveColor", ColorValue.FromColor(Color.Black));
            mesh.Effect.SetValue("materialAmbientColor", ColorValue.FromColor(Color.White));
            mesh.Effect.SetValue("materialDiffuseColor", ColorValue.FromColor(Color.White));
            mesh.Effect.SetValue("materialSpecularColor", ColorValue.FromColor(Color.White));
            mesh.Effect.SetValue("materialSpecularExp", 9);

            mesh.Effect.SetValue("texCubeMap", GameManager.Instance.cubeMap);

            //creamos las boundingbox
            //a pesar de que las naves no tienen legs ni head, le seteamos boxes "vacias" para no tener problemas con Excepciones de null
            HEADSHOT_BOUNDINGBOX = new TgcBoundingBox();
            CHEST_BOUNDINGBOX = this.mesh.BoundingBox.clone();
            LEGS_BOUNDINGBOX = new TgcBoundingBox();
            //carga de sonido
            SonidoMovimiento = new Tgc3dSound(GuiController.Instance.AlumnoEjemplosMediaDir + "Los_Borbotones\\Audio\\Robot\\ufoHum.wav", getPosicionActual());
            SonidoMovimiento.MinDistance = 130f;
            SonidoMovimiento.play(true);
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Crear nuevo manejador de colsiones
        /// </summary>
        public BspCollisionManager(BspMap bspMap)
        {
            this.bspMap = bspMap;
            this.camera = new Q3FpsCamera();

            jumpSpeed = 80.0f;
            gravity = 80.0f;
            maxStepHeight = 40;

            noClip = false;
            velocidad = new Vector3();
            antCamPos = Vector3.Empty;
            time = 0;
            firstTime = true;
            playerBB = new TgcBoundingBox(new Vector3(-20, -60, -20), new Vector3(20, 20, 20));
        }
Ejemplo n.º 31
0
        public List<TgcMesh> findMeshesToCollide(TgcBoundingBox objeto)
        {
            Vector3 pMax = sceneBounds.PMax;
            Vector3 pMin = sceneBounds.PMin;
            List<TgcMesh> meshes = new List<TgcMesh>();

            collidedNodes = new List<QuadtreeNode>();
            findNodesToCollide(objeto, quadtreeRootNode, pMin.X, pMin.Y, pMin.Z,
                pMax.X, pMax.Y, pMax.Z);

            foreach (QuadtreeNode node in collidedNodes)
            {
                meshes.AddRange(node.models);
            }
            return meshes;
        }
Ejemplo n.º 32
0
        /// <summary>
        /// Clasifica un BoundingBox respecto del Frustum
        /// </summary>
        /// <param name="frustum">Frustum</param>
        /// <param name="aabb">BoundingBox</param>
        /// <returns>Resultado de la clasificación</returns>
        public static FrustumResult classifyFrustumAABB(TgcFrustum frustum, TgcBoundingBox aabb)
        {
            int totalIn = 0;

            Plane[] frustumPlanes = frustum.FrustumPlanes;

            // get the corners of the box into the vCorner array
            Vector3[] aabbCorners = aabb.computeCorners();

            // test all 8 corners against the 6 sides
            // if all points are behind 1 specific plane, we are out
            // if we are in with all points, then we are fully in
            for (int p = 0; p < 6; ++p)
            {
                int inCount = 8;
                int ptIn    = 1;

                for (int i = 0; i < 8; ++i)
                {
                    // test this point against the planes
                    if (classifyPointPlane(aabbCorners[i], frustumPlanes[p]) == PointPlaneResult.BEHIND)
                    {
                        ptIn = 0;
                        --inCount;
                    }
                }

                // were all the points outside of plane p?
                if (inCount == 0)
                {
                    return(FrustumResult.OUTSIDE);
                }

                // check if they were all on the right side of the plane
                totalIn += ptIn;
            }

            // so if iTotalIn is 6, then all are inside the view
            if (totalIn == 6)
            {
                return(FrustumResult.INSIDE);
            }

            // we must be partly in then otherwise
            return(FrustumResult.INTERSECT);
        }
Ejemplo n.º 33
0
 /// <summary>
 /// Indica si un BoundingBox colisiona con otro.
 /// Solo indica si hay colisión o no. No va mas en detalle.
 /// </summary>
 /// <param name="a">BoundingBox 1</param>
 /// <param name="b">BoundingBox 2</param>
 /// <returns>True si hay colisión</returns>
 public static bool testAABBAABB(TgcBoundingBox a, TgcBoundingBox b)
 {
     // Exit with no intersection if separated along an axis
     if (a.PMax.X < b.PMin.X || a.PMin.X > b.PMax.X)
     {
         return(false);
     }
     if (a.PMax.Y < b.PMin.Y || a.PMin.Y > b.PMax.Y)
     {
         return(false);
     }
     if (a.PMax.Z < b.PMin.Z || a.PMin.Z > b.PMax.Z)
     {
         return(false);
     }
     // Overlapping on all axes means AABBs are intersecting
     return(true);
 }
Ejemplo n.º 34
0
        /// <summary>
        /// Indica si el segmento de recta compuesto por p0-p1 colisiona con el BoundingBox.
        /// </summary>
        /// <param name="p0">Punto inicial del segmento</param>
        /// <param name="p1">Punto final del segmento</param>
        /// <param name="aabb">BoundingBox</param>
        /// <param name="q">Punto de intersección</param>
        /// <returns>True si hay colisión</returns>
        public static bool intersectSegmentAABB(Vector3 p0, Vector3 p1, TgcBoundingBox aabb, out Vector3 q)
        {
            Vector3 segmentDir = p1 - p0;
            TgcRay  ray        = new TgcRay(p0, segmentDir);

            if (TgcCollisionUtils.intersectRayAABB(ray, aabb, out q))
            {
                float   segmentLengthSq   = segmentDir.LengthSq();
                Vector3 collisionDiff     = q - p0;
                float   collisionLengthSq = collisionDiff.LengthSq();
                if (collisionLengthSq <= segmentLengthSq)
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 35
0
        public KdTreeNode crearKdTree(List<TgcMesh> modelos, TgcBoundingBox sceneBounds)
        {
            KdTreeNode rootNode = new KdTreeNode();

            //iniciar generacion recursiva de KdTree
            doSectorKdTreeX(rootNode, sceneBounds.PMin, sceneBounds.PMax, 0, modelos);

            //podar nodos innecesarios
            optimizeSectorKdTree(rootNode.children);

            //imprimir por consola el KdTree
            //printDebugKdTree(rootNode);

            //imprimir estadisticas de debug
            //printEstadisticasKdTree(rootNode);

            return rootNode;
        }
Ejemplo n.º 36
0
        /// <summary>
        /// Transforma el BondingBox en base a una matriz de transformación.
        /// Esto implica escalar, rotar y trasladar.
        /// El procedimiento es mas costoso que solo hacer scaleTranslate().
        /// Se construye un nuevo BoundingBox en base a los puntos extremos del original
        /// más la transformación pedida.
        /// Si el BoundingBox se transformó y luego se llama a scaleTranslate(), se respeta
        /// la traslación y la escala, pero la rotación se va a perder.
        /// </summary>
        /// <param name="transform"></param>
        public void transform(Matrix transform)
        {
            //Transformar vertices extremos originales
            Vector3[] corners    = computeCorners(pMinOriginal, pMaxOriginal);
            Vector3[] newCorners = new Vector3[corners.Length];
            for (int i = 0; i < corners.Length; i++)
            {
                newCorners[i] = TgcVectorUtils.transform(corners[i], transform);
            }

            //Calcular nuevo BoundingBox en base a extremos transformados
            TgcBoundingBox newBB = TgcBoundingBox.computeFromPoints(newCorners);

            //actualizar solo pMin y pMax, pMinOriginal y pMaxOriginal quedan sin ser transformados
            pMin = newBB.pMin;
            pMax = newBB.pMax;

            dirtyValues = true;
        }
Ejemplo n.º 37
0
        /// <summary>
        /// Crea el terreno
        /// </summary>
        public TgcEditableLand()
        {
            Device d3dDevice = GuiController.Instance.D3dDevice;

            //16 caras, 32 triangulos, 96 vertices
            vertices     = new CustomVertex.PositionTextured[96];
            vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionTextured), vertices.Length, d3dDevice,
                                            Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionTextured.Format, Pool.Default);

            //Crear los 25 vertices editables, formando una grilla de 5x5 vertices
            editableVertices = new EditableVertex[25];
            float uvStep = 1f / 4f;

            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    EditableVertex v = new EditableVertex();
                    v.Pos = new Vector3(j * PATCH_SIZE, 0, i * PATCH_SIZE);
                    v.UV  = new Vector2(j * uvStep, i * uvStep);
                    editableVertices[i * 5 + j] = v;
                }
            }


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

            //BoundingBox
            boundingBox = new TgcBoundingBox();
            updateBoundingBox();

            //Shader
            this.effect    = GuiController.Instance.Shaders.VariosShader;
            this.technique = TgcShaders.T_POSITION_TEXTURED;
        }
Ejemplo n.º 38
0
 /// <summary>
 /// Clasifica un BoundingBox respecto de otro. Las opciones de clasificacion son:
 /// <para># Adentro: box1 se encuentra completamente dentro de la box2</para>
 /// <para># Afuera: box2 se encuentra completamente afuera de box1</para>
 /// <para># Atravesando: box2 posee una parte dentro de box1 y otra parte fuera de la box1</para>
 /// <para># Encerrando: box1 esta completamente adentro a la box1, es decir, la box1 se encuentra dentro
 ///     de la box2. Es un caso especial de que box2 esté afuera de box1</para>
 /// </summary>
 public static BoxBoxResult classifyBoxBox(TgcBoundingBox box1, TgcBoundingBox box2)
 {
     if (((box1.PMin.X <= box2.PMin.X && box1.PMax.X >= box2.PMax.X) ||
         (box1.PMin.X >= box2.PMin.X && box1.PMin.X <= box2.PMax.X) ||
         (box1.PMax.X >= box2.PMin.X && box1.PMax.X <= box2.PMax.X)) &&
        ((box1.PMin.Y <= box2.PMin.Y && box1.PMax.Y >= box2.PMax.Y) ||
         (box1.PMin.Y >= box2.PMin.Y && box1.PMin.Y <= box2.PMax.Y) ||
         (box1.PMax.Y >= box2.PMin.Y && box1.PMax.Y <= box2.PMax.Y)) &&
        ((box1.PMin.Z <= box2.PMin.Z && box1.PMax.Z >= box2.PMax.Z) ||
         (box1.PMin.Z >= box2.PMin.Z && box1.PMin.Z <= box2.PMax.Z) ||
         (box1.PMax.Z >= box2.PMin.Z && box1.PMax.Z <= box2.PMax.Z)))
     {
         if ((box1.PMin.X <= box2.PMin.X) &&
            (box1.PMin.Y <= box2.PMin.Y) &&
            (box1.PMin.Z <= box2.PMin.Z) &&
            (box1.PMax.X >= box2.PMax.X) &&
            (box1.PMax.Y >= box2.PMax.Y) &&
            (box1.PMax.Z >= box2.PMax.Z))
         {
             return BoxBoxResult.Adentro;
         }
         else if ((box1.PMin.X > box2.PMin.X) &&
                  (box1.PMin.Y > box2.PMin.Y) &&
                  (box1.PMin.Z > box2.PMin.Z) &&
                  (box1.PMax.X < box2.PMax.X) &&
                  (box1.PMax.Y < box2.PMax.Y) &&
                  (box1.PMax.Z < box2.PMax.Z))
         {
             return BoxBoxResult.Encerrando;
         }
         else
         {
             return BoxBoxResult.Atravesando;
         }
     }
     else
     {
         return BoxBoxResult.Afuera;
     }
 }
Ejemplo n.º 39
0
 /// <summary>
 /// Clasifica un BoundingBox respecto de otro. Las opciones de clasificacion son:
 /// <para># Adentro: box1 se encuentra completamente dentro de la box2</para>
 /// <para># Afuera: box2 se encuentra completamente afuera de box1</para>
 /// <para># Atravesando: box2 posee una parte dentro de box1 y otra parte fuera de la box1</para>
 /// <para># Encerrando: box1 esta completamente adentro a la box1, es decir, la box1 se encuentra dentro
 ///     de la box2. Es un caso especial de que box2 esté afuera de box1</para>
 /// </summary>
 public static BoxBoxResult classifyBoxBox(TgcBoundingBox box1, TgcBoundingBox box2)
 {
     if (((box1.PMin.X <= box2.PMin.X && box1.PMax.X >= box2.PMax.X) ||
          (box1.PMin.X >= box2.PMin.X && box1.PMin.X <= box2.PMax.X) ||
          (box1.PMax.X >= box2.PMin.X && box1.PMax.X <= box2.PMax.X)) &&
         ((box1.PMin.Y <= box2.PMin.Y && box1.PMax.Y >= box2.PMax.Y) ||
          (box1.PMin.Y >= box2.PMin.Y && box1.PMin.Y <= box2.PMax.Y) ||
          (box1.PMax.Y >= box2.PMin.Y && box1.PMax.Y <= box2.PMax.Y)) &&
         ((box1.PMin.Z <= box2.PMin.Z && box1.PMax.Z >= box2.PMax.Z) ||
          (box1.PMin.Z >= box2.PMin.Z && box1.PMin.Z <= box2.PMax.Z) ||
          (box1.PMax.Z >= box2.PMin.Z && box1.PMax.Z <= box2.PMax.Z)))
     {
         if ((box1.PMin.X <= box2.PMin.X) &&
             (box1.PMin.Y <= box2.PMin.Y) &&
             (box1.PMin.Z <= box2.PMin.Z) &&
             (box1.PMax.X >= box2.PMax.X) &&
             (box1.PMax.Y >= box2.PMax.Y) &&
             (box1.PMax.Z >= box2.PMax.Z))
         {
             return(BoxBoxResult.Adentro);
         }
         else if ((box1.PMin.X > box2.PMin.X) &&
                  (box1.PMin.Y > box2.PMin.Y) &&
                  (box1.PMin.Z > box2.PMin.Z) &&
                  (box1.PMax.X < box2.PMax.X) &&
                  (box1.PMax.Y < box2.PMax.Y) &&
                  (box1.PMax.Z < box2.PMax.Z))
         {
             return(BoxBoxResult.Encerrando);
         }
         else
         {
             return(BoxBoxResult.Atravesando);
         }
     }
     else
     {
         return(BoxBoxResult.Afuera);
     }
 }
Ejemplo n.º 40
0
        public QuadtreeNode crearQuadtree(List<TgcMesh> TgcMeshs, TgcBoundingBox sceneBounds)
        {
            QuadtreeNode rootNode = new QuadtreeNode();

            //Calcular punto medio y centro
            Vector3 midSize = sceneBounds.calculateAxisRadius();
            Vector3 center = sceneBounds.calculateBoxCenter();

            //iniciar generacion recursiva de octree
            doSectorQuadtreeX(rootNode, center, midSize, 0, TgcMeshs);

            //podar nodos innecesarios
            optimizeSectorQuadtree(rootNode.children);

            //imprimir por consola el octree
            //printDebugQuadtree(rootNode);

            //imprimir estadisticas de debug
            //printEstadisticasQuadtree(rootNode);

            return rootNode;
        }
        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;
        }
Ejemplo n.º 42
0
        /// <summary>
        /// Calcula la mínima distancia al cuadrado entre el punto p y el BoundingBox.
        /// Si no se necesita saber el punto exacto de colisión es más ágil que utilizar closestPointAABB().
        /// </summary>
        /// <param name="p">Punto a testear</param>
        /// <param name="aabb">BoundingBox</param>
        /// <returns>Mínima distacia al cuadrado</returns>
        public static float sqDistPointAABB(Vector3 p, TgcBoundingBox aabb)
        {
            float[] aabbMin = toArray(aabb.PMin);
            float[] aabbMax = toArray(aabb.PMax);
            float[] pArray  = toArray(p);
            float   sqDist  = 0.0f;

            for (int i = 0; i < 3; i++)
            {
                // For each axis count any excess distance outside box extents
                float v = pArray[i];
                if (v < aabbMin[i])
                {
                    sqDist += (aabbMin[i] - v) * (aabbMin[i] - v);
                }
                if (v > aabbMax[i])
                {
                    sqDist += (v - aabbMax[i]) * (v - aabbMax[i]);
                }
            }
            return(sqDist);
        }
Ejemplo n.º 43
0
        /// <summary>
        /// Construye la grilla
        /// </summary>
        private GrillaRegularNode[, ,] buildGrid(List<TgcMesh> modelos, TgcBoundingBox sceneBounds, Vector3 cellDim)
        {
            Vector3 sceneSize = sceneBounds.calculateSize();

            int gx = (int)FastMath.Ceiling(sceneSize.X / cellDim.X) + 1;
            int gy = (int)FastMath.Ceiling(sceneSize.Y / cellDim.Y) + 1;
            int gz = (int)FastMath.Ceiling(sceneSize.Z / cellDim.Z) + 1;

            GrillaRegularNode[, ,] grid = new GrillaRegularNode[gx, gy, gz];

            //Construir grilla
            for (int x = 0; x < gx; x++)
            {
                for (int y = 0; y < gy; y++)
                {
                    for (int z = 0; z < gz; z++)
                    {
                        //Crear celda
                        GrillaRegularNode node = new GrillaRegularNode();
                        
                        //Crear BoundingBox de celda
                        Vector3 pMin = new Vector3(sceneBounds.PMin.X + x * cellDim.X, sceneBounds.PMin.Y + y * cellDim.Y, sceneBounds.PMin.Z + z * cellDim.Z);
                        Vector3 pMax = Vector3.Add(pMin, cellDim);
                        node.BoundingBox = new TgcBoundingBox(pMin, pMax);

                        //Cargar modelos en celda
                        node.Models = new List<TgcMesh>();
                        addModelsToCell(node, modelos);

                        grid[x, y, z] = node;
                    }
                }
            }

            return grid;
        }
Ejemplo n.º 44
0
        /// <summary>
        /// Dado el punto p, devuelve el punto del contorno del BoundingBox mas próximo a p.
        /// </summary>
        /// <param name="p">Punto a testear</param>
        /// <param name="aabb">BoundingBox a testear</param>
        /// <returns>Punto mas cercano a p del BoundingBox</returns>
        public static Vector3 closestPointAABB(Vector3 p, TgcBoundingBox aabb)
        {
            float[] aabbMin = toArray(aabb.PMin);
            float[] aabbMax = toArray(aabb.PMax);
            float[] pArray  = toArray(p);
            float[] q       = new float[3];

            // For each coordinate axis, if the point coordinate value is
            // outside box, clamp it to the box, else keep it as is
            for (int i = 0; i < 3; i++)
            {
                float v = pArray[i];
                if (v < aabbMin[i])
                {
                    v = aabbMin[i];                 // v = max(v, b.min[i])
                }
                if (v > aabbMax[i])
                {
                    v = aabbMax[i];                 // v = min(v, b.max[i])
                }
                q[i] = v;
            }
            return(TgcCollisionUtils.toVector3(q));
        }
Ejemplo n.º 45
0
        /// <summary>
        /// Hacer visible las meshes de un nodo si es visible por el Frustum
        /// </summary>
        private void testChildVisibility(TgcFrustum frustum, QuadtreeNode childNode,
                float boxLowerX, float boxLowerY, float boxLowerZ, float boxUpperX, float boxUpperY, float boxUpperZ)
        {
            //test frustum-box intersection
            TgcBoundingBox caja = new TgcBoundingBox(
                new Vector3(boxLowerX, boxLowerY, boxLowerZ),
                new Vector3(boxUpperX, boxUpperY, boxUpperZ));
            TgcCollisionUtils.FrustumResult c = TgcCollisionUtils.classifyFrustumAABB(frustum, caja);

            //complementamente adentro: cargar todos los hijos directamente, sin testeos
            if (c == TgcCollisionUtils.FrustumResult.INSIDE)
            {
                addAllLeafMeshes(childNode);
            }

            //parte adentro: seguir haciendo testeos con hijos
            else if (c == TgcCollisionUtils.FrustumResult.INTERSECT)
            {
                findVisibleMeshes(frustum, childNode, boxLowerX, boxLowerY, boxLowerZ, boxUpperX, boxUpperY, boxUpperZ);
            }
        }
Ejemplo n.º 46
0
        /// <summary>
        /// Calcular OBB a partir de un conjunto de puntos.
        /// Prueba todas las orientaciones entre initValues y endValues, saltando de angulo en cada intervalo segun step
        /// Continua recursivamente hasta llegar a un step menor a 0.01f
        /// </summary>
        /// <returns></returns>
        private static OBBStruct computeFromPointsRecursive(Vector3[] points, Vector3 initValues, Vector3 endValues, float step)
        {
            OBBStruct minObb        = new OBBStruct();
            float     minVolume     = float.MaxValue;
            Vector3   minInitValues = Vector3.Empty;
            Vector3   minEndValues  = Vector3.Empty;

            Vector3[] transformedPoints = new Vector3[points.Length];
            float     x, y, z;


            x = initValues.X;
            while (x <= endValues.X)
            {
                y = initValues.Y;
                float rotX = FastMath.ToRad(x);
                while (y <= endValues.Y)
                {
                    z = initValues.Z;
                    float rotY = FastMath.ToRad(y);
                    while (z <= endValues.Z)
                    {
                        //Matriz de rotacion
                        float     rotZ        = FastMath.ToRad(z);
                        Matrix    rotM        = Matrix.RotationYawPitchRoll(rotY, rotX, rotZ);
                        Vector3[] orientation = new Vector3[] {
                            new Vector3(rotM.M11, rotM.M12, rotM.M13),
                            new Vector3(rotM.M21, rotM.M22, rotM.M23),
                            new Vector3(rotM.M31, rotM.M32, rotM.M33)
                        };

                        //Transformar todos los puntos a OBB-space
                        for (int i = 0; i < transformedPoints.Length; i++)
                        {
                            transformedPoints[i].X = Vector3.Dot(points[i], orientation[0]);
                            transformedPoints[i].Y = Vector3.Dot(points[i], orientation[1]);
                            transformedPoints[i].Z = Vector3.Dot(points[i], orientation[2]);
                        }

                        //Obtener el AABB de todos los puntos transformados
                        TgcBoundingBox aabb = TgcBoundingBox.computeFromPoints(transformedPoints);

                        //Calcular volumen del AABB
                        Vector3 extents = aabb.calculateAxisRadius();
                        extents = TgcVectorUtils.abs(extents);
                        float volume = extents.X * 2 * extents.Y * 2 * extents.Z * 2;

                        //Buscar menor volumen
                        if (volume < minVolume)
                        {
                            minVolume     = volume;
                            minInitValues = new Vector3(x, y, z);
                            minEndValues  = new Vector3(x + step, y + step, z + step);

                            //Volver centro del AABB a World-space
                            Vector3 center = aabb.calculateBoxCenter();
                            center = center.X * orientation[0] + center.Y * orientation[1] + center.Z * orientation[2];

                            //Crear OBB
                            minObb.center      = center;
                            minObb.extents     = extents;
                            minObb.orientation = orientation;
                        }

                        z += step;
                    }
                    y += step;
                }
                x += step;
            }

            //Recursividad en mejor intervalo encontrado
            if (step > 0.01f)
            {
                minObb = computeFromPointsRecursive(points, minInitValues, minEndValues, step / 10f);
            }

            return(minObb);
        }
Ejemplo n.º 47
0
        /// <summary>
        /// Indica si un Ray colisiona con un AABB.
        /// Si hay intersección devuelve True, q contiene
        /// el punto de intesección.
        /// Basado en el código de: http://www.codercorner.com/RayAABB.cpp
        /// La dirección del Ray puede estar sin normalizar.
        /// </summary>
        /// <param name="ray">Ray</param>
        /// <param name="a">AABB</param>
        /// <param name="q">Punto de intersección</param>
        /// <returns>True si hay colisión</returns>
        public static bool intersectRayAABB(TgcRay ray, TgcBoundingBox aabb, out Vector3 q)
        {
            q = Vector3.Empty;
            bool inside = true;

            float[] aabbMin   = toArray(aabb.PMin);
            float[] aabbMax   = toArray(aabb.PMax);
            float[] rayOrigin = toArray(ray.Origin);
            float[] rayDir    = toArray(ray.Direction);

            float[] max_t = new float[3] {
                -1.0f, -1.0f, -1.0f
            };
            float[] coord = new float[3];

            for (uint i = 0; i < 3; ++i)
            {
                if (rayOrigin[i] < aabbMin[i])
                {
                    inside   = false;
                    coord[i] = aabbMin[i];

                    if (rayDir[i] != 0.0f)
                    {
                        max_t[i] = (aabbMin[i] - rayOrigin[i]) / rayDir[i];
                    }
                }
                else if (rayOrigin[i] > aabbMax[i])
                {
                    inside   = false;
                    coord[i] = aabbMax[i];

                    if (rayDir[i] != 0.0f)
                    {
                        max_t[i] = (aabbMax[i] - rayOrigin[i]) / rayDir[i];
                    }
                }
            }

            // If the Ray's start position is inside the Box, we can return true straight away.
            if (inside)
            {
                q = toVector3(rayOrigin);
                return(true);
            }

            uint plane = 0;

            if (max_t[1] > max_t[plane])
            {
                plane = 1;
            }
            if (max_t[2] > max_t[plane])
            {
                plane = 2;
            }

            if (max_t[plane] < 0.0f)
            {
                return(false);
            }

            for (uint i = 0; i < 3; ++i)
            {
                if (plane != i)
                {
                    coord[i] = rayOrigin[i] + max_t[plane] * rayDir[i];

                    if (coord[i] < aabbMin[i] - float.Epsilon || coord[i] > aabbMax[i] + float.Epsilon)
                    {
                        return(false);
                    }
                }
            }

            q = toVector3(coord);
            return(true);
        }
Ejemplo n.º 48
0
 /// <summary>
 /// Generar OBB a partir de AABB
 /// </summary>
 /// <param name="aabb">BoundingBox</param>
 /// <returns>OBB generado</returns>
 public static TgcObb computeFromAABB(TgcBoundingBox aabb)
 {
     return(TgcObb.computeFromAABB(aabb.toStruct()).toClass());
 }