public ColisionInfo GetColisiones(TgcBoundingAxisAlignBox colisionable) { ColisionInfo colisionInfo = new ColisionInfo(); foreach (IColisionablePelota obstaculo in this.obstaculos) { TgcCollisionUtils.BoxBoxResult result = TgcCollisionUtils.classifyBoxBox(colisionable, obstaculo.GetTgcBoundingBox()); if (result == TgcCollisionUtils.BoxBoxResult.Adentro || result == TgcCollisionUtils.BoxBoxResult.Atravesando) { colisionInfo.Add(obstaculo); } } return colisionInfo; }
/// <summary> /// Crea una caja vacia /// </summary> public TGCBox() { vertices = new CustomVertex.PositionColoredTextured[36]; vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionColoredTextured), vertices.Length, D3DDevice.Instance.Device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColoredTextured.Format, Pool.Default); AutoTransformEnable = false; Transform = TGCMatrix.Identity; translation = TGCVector3.Empty; rotation = TGCVector3.Empty; Enabled = true; Color = Color.White; AlphaBlendEnable = false; UVOffset = TGCVector2.Zero; UVTiling = TGCVector2.One; //BoundingBox BoundingBox = new TgcBoundingAxisAlignBox(); //Shader Effect = TGCShaders.Instance.VariosShader; Technique = TGCShaders.T_POSITION_COLORED; }
private void CheckColisionY(float ElapsedTime) { TgcBoundingAxisAlignBox Collider = Env.Escenario.ColisionY(Mesh.BoundingBox); if (Collider != null) { Mesh.Position = new TGCVector3(Mesh.Position.X, FastMath.Clamp(Mesh.Position.Y, Collider.PMax.Y, Collider.PMax.Y + 2), Mesh.Position.Z); CanJump = VelocidadY < 0; } if (TipoColisionActual == TiposColision.Pozo) { Pozo(); } else if (TipoColisionActual == TiposColision.Caja) { Mesh.Move(posicionPlataforma); } else if (TipoColisionActual == TiposColision.Techo) { Mesh.Position = new TGCVector3(oldPos.X, posicionPlataforma.Y, oldPos.Z); VelocidadY = 0; } }
public SpherePrimitive(MeshCreatorModifier control) : base(control) { bb = new TgcBoundingAxisAlignBox(); Name = "Sphere_" + PRIMITIVE_COUNT++; }
public CamaraJugador(ObjetoJuego jugador, ObjetoJuego pelota, TgcCamera camara, TgcBoundingAxisAlignBox limites) { this.jugador = jugador; this.pelota = pelota; this.camara = camara; this.limites = limites; this.limites.scaleTranslate(new TGCVector3(0, 0, 0), new TGCVector3(0.9f, 0.9f, 0.9f)); lookAt = new TGCVector3(TGCVector3.Empty); cameraPosition = new TGCVector3(0, 100, 225); }
/// <summary> /// Cargar información de PortalRendering /// </summary> public TgcPortalRenderingManager loadFromData(TgcScene scene, TgcPortalRenderingData portalRenderingData) { var manager = new TgcPortalRenderingManager(scene); //Crear dictionary de nombres de los meshes var meshDictionary = new Dictionary <string, TgcMesh>(); foreach (var mesh in scene.Meshes) { meshDictionary.Add(mesh.Name, mesh); } //Cargar celdas foreach (var cellData in portalRenderingData.cells) { //Crear cuerpo Convexo var convexPoly = new TgcConvexPolyhedron(); convexPoly.Planes = new Plane[cellData.facePlanes.Length / 4]; for (var i = 0; i < convexPoly.Planes.Length; i++) { convexPoly.Planes[i] = new Plane( cellData.facePlanes[i * 4], cellData.facePlanes[i * 4 + 1], cellData.facePlanes[i * 4 + 2], cellData.facePlanes[i * 4 + 3] ); } convexPoly.BoundingVertices = new Vector3[cellData.boundingVertices.Length / 3]; for (var i = 0; i < convexPoly.BoundingVertices.Length; i++) { convexPoly.BoundingVertices[i] = new Vector3( cellData.boundingVertices[i * 3], cellData.boundingVertices[i * 3 + 1], cellData.boundingVertices[i * 3 + 2] ); } //Crear celda var cell = new TgcPortalRenderingCell(cellData.name, convexPoly); manager.Cells.Add(cell); //Cargar meshes en celda for (var i = 0; i < cellData.meshes.Length; i++) { var mesh = meshDictionary[cellData.meshes[i]]; cell.Meshes.Add(mesh); } } //Cargar portales foreach (var portalData in portalRenderingData.portals) { //BoundingBox del portal var boundingBox = new TgcBoundingAxisAlignBox( new Vector3(portalData.pMin[0], portalData.pMin[1], portalData.pMin[2]), new Vector3(portalData.pMax[0], portalData.pMax[1], portalData.pMax[2]) ); //Crear portal var portal = new TgcPortalRenderingPortal(portalData.name, boundingBox); manager.Portals.Add(portal); //Cargar conexiones para celdas A y B var cellA = manager.Cells[portalData.cellA]; var cellB = manager.Cells[portalData.cellB]; //Poligono del portal para la celda A var polygonA = new TgcConvexPolygon(); polygonA.BoundingVertices = new Vector3[portalData.boundingVerticesA.Length / 3]; for (var i = 0; i < polygonA.BoundingVertices.Length; i++) { polygonA.BoundingVertices[i] = new Vector3( portalData.boundingVerticesA[i * 3], portalData.boundingVerticesA[i * 3 + 1], portalData.boundingVerticesA[i * 3 + 2] ); } //Plano del portal para la celda A var planeA = TgcParserUtils.float4ArrayToPlane(portalData.planeA); //Crear conexion A var connectionA = new TgcPortalRenderingConnection(portal, cellB, polygonA, planeA); cellA.Connections.Add(connectionA); //Poligono del portal para la celda B var polygonB = new TgcConvexPolygon(); polygonB.BoundingVertices = new Vector3[portalData.boundingVerticesB.Length / 3]; for (var i = 0; i < polygonB.BoundingVertices.Length; i++) { polygonB.BoundingVertices[i] = new Vector3( portalData.boundingVerticesB[i * 3], portalData.boundingVerticesB[i * 3 + 1], portalData.boundingVerticesB[i * 3 + 2] ); } //Plano del portal para la celda B var planeB = TgcParserUtils.float4ArrayToPlane(portalData.planeB); //Crear conexion B var connectionB = new TgcPortalRenderingConnection(portal, cellA, polygonB, planeB); cellB.Connections.Add(connectionB); } return(manager); }
public void Init() { var loader = new TgcSceneLoader(); Items = new List <Recolectable>(); Piezas = new List <Pieza>(); Objetos = new List <Colisionable>(); MeshARenderizar = new List <TgcMesh>(); meshFogatas = new List <TgcMesh>(); IluminacionEscenario = new List <Fogata>(); //Instancia de skybox skyBox = new TgcSkyBox(); skyBox.Center = TGCVector3.Empty; skyBox.Size = new TGCVector3(9000, 9000, 9000); skyBox.setFaceTexture(TgcSkyBox.SkyFaces.Up, MediaDir + "cielo.jpg"); skyBox.setFaceTexture(TgcSkyBox.SkyFaces.Down, MediaDir + "cielo.jpg"); skyBox.setFaceTexture(TgcSkyBox.SkyFaces.Left, MediaDir + "cielo.jpg"); skyBox.setFaceTexture(TgcSkyBox.SkyFaces.Right, MediaDir + "cielo.jpg"); skyBox.setFaceTexture(TgcSkyBox.SkyFaces.Front, MediaDir + "cielo.jpg"); skyBox.setFaceTexture(TgcSkyBox.SkyFaces.Back, MediaDir + "cielo.jpg"); skyBox.SkyEpsilon = 25f; skyBox.Init(); //Instancio la vegetacion var scene = loader.loadSceneFromFile(MediaDir + @"Pino-TgcScene.xml"); var PinoOriginal = scene.Meshes[0]; List <TGCVector3> posicionesArboles = new List <TGCVector3>(); posicionesArboles.Add(new TGCVector3(1, 1, 1)); posicionesArboles.Add(new TGCVector3(-3442, 1, -2736)); posicionesArboles.Add(new TGCVector3(-3689, 1, -3039)); posicionesArboles.Add(new TGCVector3(-3799, 1, -2719)); posicionesArboles.Add(new TGCVector3(-3417, 1, -2480)); posicionesArboles.Add(new TGCVector3(-2917, 1, -2433)); posicionesArboles.Add(new TGCVector3(-3668, 1, -2025)); posicionesArboles.Add(new TGCVector3(-3362, 1, -2009)); posicionesArboles.Add(new TGCVector3(-3451, 1, -3786)); posicionesArboles.Add(new TGCVector3(-4037, 1, -2329)); posicionesArboles.Add(new TGCVector3(-2885, 1, -1826)); posicionesArboles.Add(new TGCVector3(-4123, 1, -1581)); posicionesArboles.Add(new TGCVector3(-3289, 1, -909)); posicionesArboles.Add(new TGCVector3(-4261, 1, -435)); posicionesArboles.Add(new TGCVector3(-2883, 1, -655)); posicionesArboles.Add(new TGCVector3(-3352, 1, -1761)); posicionesArboles.Add(new TGCVector3(-3244, 1, -2394)); posicionesArboles.Add(new TGCVector3(-3978, 1, -2572)); posicionesArboles.Add(new TGCVector3(-3517, 1, -1982)); posicionesArboles.Add(new TGCVector3(-3118, 1, -1524)); posicionesArboles.Add(new TGCVector3(-3349, 1, -980)); posicionesArboles.Add(new TGCVector3(-4110, 1, -407)); posicionesArboles.Add(new TGCVector3(-3304, 1, -1774)); posicionesArboles.Add(new TGCVector3(-3139, 1, -1269)); posicionesArboles.Add(new TGCVector3(-2140, 1, -562)); posicionesArboles.Add(new TGCVector3(-4094, 1, -145)); posicionesArboles.Add(new TGCVector3(-3103, 1, -1337)); posicionesArboles.Add(new TGCVector3(-2896, 1, -1087)); posicionesArboles.Add(new TGCVector3(-2529, 1, 10)); posicionesArboles.Add(new TGCVector3(-3917, 1, 772)); posicionesArboles.Add(new TGCVector3(746, 1, 157)); posicionesArboles.Add(new TGCVector3(951, 1, 637)); posicionesArboles.Add(new TGCVector3(1361, 1, 404)); posicionesArboles.Add(new TGCVector3(1361, 1, 440)); posicionesArboles.Add(new TGCVector3(-3877, 1, -678)); posicionesArboles.Add(new TGCVector3(-3997, 1, -1079)); posicionesArboles.Add(new TGCVector3(-3996, 1, -1617)); posicionesArboles.Add(new TGCVector3(-3701, 1, -1505)); posicionesArboles.Add(new TGCVector3(-3761, 1, -1069)); posicionesArboles.Add(new TGCVector3(-3968, 1, -1952)); posicionesArboles.Add(new TGCVector3(-3550, 1, -1562)); posicionesArboles.Add(new TGCVector3(-3557, 1, -1192)); posicionesArboles.Add(new TGCVector3(-3938, 1, -1048)); posicionesArboles.Add(new TGCVector3(-3148, 1, -268)); posicionesArboles.Add(new TGCVector3(-4120, 1, 433)); posicionesArboles.Add(new TGCVector3(-3136, 1, -135)); posicionesArboles.Add(new TGCVector3(-2793, 1, -476)); var indiceArbolDirectorio = (new Random()).Next(posicionesArboles.Count, posicionesArboles.Count + 100); arbolesMesh = new List <TgcMesh>(); Colisionable Arbol; for (var i = 0; i < posicionesArboles.Count; i++) { var Instance = PinoOriginal.createMeshInstance("Pino" + i); Arbol = new SinEfecto(Instance); Arbol.mesh.Move(0, 0, 0); Arbol.mesh.Scale = new TGCVector3(0.05f * i, 0.05f * i, 0.05f * i); Arbol.mesh.Move(posicionesArboles[i]); Arbol.mesh.Transform = TGCMatrix.Translation(posicionesArboles[i]); Objetos.Add(Arbol); MeshARenderizar.Add(Arbol.mesh); arbolesMesh.Add(Arbol.mesh); } for (var i = posicionesArboles.Count; i < posicionesArboles.Count + 100; i++) { var Instance = PinoOriginal.createMeshInstance("Pino" + i); if (i == indiceArbolDirectorio) { Arbol = new ArbolDirectorio(MediaDir); } else { Arbol = new SinEfecto(Instance); } Arbol.mesh.Move(0, 0, 0); Arbol.mesh.Scale = new TGCVector3(0.01f * i, 0.01f * i, 0.01f * i); Arbol.mesh.Move(new TGCVector3(((float)Math.Pow(i, Math.PI) % 2066) + 98, 1, ((float)Math.Pow(i, Math.E) % 3136) - 1339)); Arbol.mesh.Transform = TGCMatrix.Translation(new TGCVector3(((float)Math.Pow(i, Math.PI) % 2066) + 98, 1, ((float)Math.Pow(i, Math.E) % 3136) - 1339)); Objetos.Add(Arbol); MeshARenderizar.Add(Arbol.mesh); arbolesMesh.Add(Arbol.mesh); } foreach (var mesh in arbolesMesh) { mesh.AlphaBlendEnable = true; } //Instancio el terreno (Heigthmap) terreno = new TgcSimpleTerrain(); var pathTextura = MediaDir + "Textures\\mapa1.jpg"; var pathHeighmap = MediaDir + "mapa1.jpg"; currentScaleXZ = 100f; currentScaleY = 3f; terreno.loadHeightmap(pathHeighmap, currentScaleXZ, currentScaleY, new TGCVector3(0, -30, 0)); terreno.loadTexture(pathTextura); //Instancio el piso var pisoTexture = TgcTexture.createTexture(D3DDevice.Instance.Device, MediaDir + "Textures\\water2.jpg"); Plano = new TgcPlane(new TGCVector3(-tamanioMapa / 2, 0, -tamanioMapa / 2), new TGCVector3(tamanioMapa, 0, tamanioMapa), TgcPlane.Orientations.XZplane, pisoTexture, 50f, 50f); MeshPlano = Plano.toMesh("MeshPlano"); Objetos.Add(new SinEfecto(MeshPlano)); MeshARenderizar.Add(MeshPlano); piezaAsociadaLago = new Pieza(2, "Pieza 2", MediaDir + "\\2D\\windows\\windows_2.png", null); pistaAsociadaLago = new Pista(null, MediaDir + "\\2D\\pista_hacha.png", null); //Instancio la Cabania var sceneCabania = loader.loadSceneFromFile(MediaDir + @"cabania-TgcScene.xml"); foreach (var Mesh in sceneCabania.Meshes) { Mesh.Move(-500, 20, 500); Mesh.Scale = new TGCVector3(4.5f, 4.5f, 4.5f); Mesh.Transform = TGCMatrix.Scaling(Mesh.Scale); Objetos.Add(new SinEfecto(Mesh)); MeshARenderizar.Add(Mesh); } cabaniaBoundingBox = new TgcBoundingAxisAlignBox(new TGCVector3(-500, 20, 500), new TGCVector3(0, 1001, 1080)); var sceneBridge = loader.loadSceneFromFile(MediaDir + @"Bridge-TgcScene.xml"); foreach (var Mesh in sceneBridge.Meshes) { Mesh.Move(-2561, 12, 159); Mesh.Scale = new TGCVector3(4.5f, .75f, 1.35f); Mesh.Transform = TGCMatrix.Scaling(Mesh.Scale); Objetos.Add(new SinEfecto(Mesh)); MeshARenderizar.Add(Mesh); } var sceneCanoa = loader.loadSceneFromFile(MediaDir + @"Canoa-TgcScene.xml"); foreach (var Mesh in sceneCanoa.Meshes) { Mesh.Move(-482, 20, -3110); Mesh.Scale = new TGCVector3(1.5f, 1.5f, 1.5f); Mesh.Transform = TGCMatrix.Scaling(Mesh.Scale); Objetos.Add(new SinEfecto(Mesh)); MeshARenderizar.Add(Mesh); } //Cabania es lugar seguro if (TgcCollisionUtils.testAABBAABB(personaje.mesh.BoundingBox, cabaniaBoundingBox)) { personaje.tiempoDesprotegido = 0; } }
public TgcKeyFrameAnimation(TgcKeyFrameAnimationData data, TgcBoundingAxisAlignBox boundingBox) { Data = data; BoundingBox = boundingBox; }
public Personaje() { estoyAdentro = true; estoyEscondido = false; positionChanged = true; rotationChanged = true; posicionInicial = new TGCVector3(100f, 15f, 100f); //Estaria piola que arranque afuera del indoor target = new TGCVector3(100f, 15f, 150f); eye = new TGCVector3(100f, 15f, 100f); ItemVacioDefault itemDefault = new ItemVacioDefault(); objetosInteractuables.Add(itemDefault); this.itemEnMano = itemDefault; var loader = new TgcSceneLoader(); var scene2 = loader.loadSceneFromFile(MediaDir + "Modelame\\GhostGrande-TgcScene.xml"); //Con demon no funca, aca rompe //Solo nos interesa el primer modelo de esta escena (tiene solo uno) meshPersonaje = scene2.Meshes[0]; const float cte = 15f; meshPersonaje.Position = new TGCVector3(100f, cte, 100f); meshPersonaje.Scale = new TGCVector3(0f, 0.5f, 0f); const int cteY = -570; meshPersonaje.BoundingBox = new TgcBoundingAxisAlignBox(new TGCVector3(-20, cteY, -20), new TGCVector3(20, 20, 20)); // \todo: configurable float half_box = 4.0f; boundingBox = new TgcBoundingAxisAlignBox( new TGCVector3(eye.X - half_box, 0.0f, eye.Z - half_box), new TGCVector3(eye.X + half_box, eye.Y, eye.Z + half_box)); vM = TGCMatrix.Identity; xAxis = new TGCVector3(); yAxis = new TGCVector3(); zAxis = new TGCVector3(); forward = new TGCVector3(); key_left = 'A'; key_back = 'S'; key_right = 'D'; key_forward = 'W'; absoluteRotationX = 0.0f; MovementSpeed = 50.0f; ForwardFactor = 1.5f; RotationSpeed = 1.5f; MaxTopAngle = 88.0f; MaxBottomAngle = -80.0f; CurrentSpeed = MovementSpeed; Control window = D3DDevice.Instance.Device.CreationParameters.FocusWindow; windowCenter = window.PointToScreen( new Point(window.Width / 2, window.Height / 2)); lockMouse = false; Enable = true; setCamera(eye, target); }
public SmartTerrain() { BoundingBox = new TgcBoundingAxisAlignBox(); }
public BoundingOrientedBox(TgcBoundingAxisAlignBox AABB) { this.obb = TgcBoundingOrientedBox.computeFromAABB(AABB); this.y = this.obb.Position.Y; }
/// <summary> /// Velocidad de incremento del mouse cuando traslada un objeto, segun la distancia del objeto a la camara /// </summary> public static float getMouseTranslateIncrementSpeed(MeshCreatorCamera camera, TgcBoundingAxisAlignBox aabb, float movement) { var dist = distanceFromCameraToObject(camera, aabb); return(movement * dist / 50); }
/// <summary> /// Velocidad de incremento del mouse cuando escala un objeto, segun la distancia del objeto a la camara /// </summary> public static float getMouseScaleIncrementSpeed(MeshCreatorCamera camera, TgcBoundingAxisAlignBox aabb, float scaling) { var dist = distanceFromCameraToObject(camera, aabb); return(scaling * dist / 1000); }
/// <summary> /// Velocidad de incremento de altura en Y con el mouse, segun la distancia /// del objeto a la camara /// </summary> public static float getMouseIncrementHeightSpeed(MeshCreatorCamera camera, TgcBoundingAxisAlignBox aabb, float heightY) { var dist = distanceFromCameraToObject(camera, aabb); return(heightY * dist / 500); }
/// <summary> /// Distancia entre un objeto y la camara /// </summary> public static float distanceFromCameraToObject(MeshCreatorCamera camera, TgcBoundingAxisAlignBox aabb) { return(distanceFromCameraToPoint(camera, aabb.calculateBoxCenter())); }
/* * /// <summary> * /// Proyecta un BoundingBox a un rectangulo 2D de screen space * /// </summary> * public static Rectangle projectAABB(TgcBoundingBox aabb) * { * return aabb.projectToScreen(); * } */ /// <summary> /// Proyectar AABB a 2D /// </summary> /// <param name="box3d">BoundingBox 3D</param> /// <param name="box2D">Rectangulo 2D proyectado</param> /// <returns>False si es un caso degenerado de proyeccion y no debe considerarse</returns> public static bool projectBoundingBox(TgcBoundingAxisAlignBox box3d, out Rectangle box2D) { //Datos de viewport var d3dDevice = D3DDevice.Instance.Device; var viewport = d3dDevice.Viewport; var view = d3dDevice.Transform.View; var proj = d3dDevice.Transform.Projection; var width = viewport.Width; var height = viewport.Height; box2D = new Rectangle(); //Proyectar los 8 puntos, sin dividir aun por W var corners = box3d.computeCorners(); var m = view * proj; var projVertices = new TGCVector3[corners.Length]; for (var i = 0; i < corners.Length; i++) { var pOut = TGCVector3.Transform(corners[i], TGCMatrix.FromMatrix(m)); if (pOut.W < 0) { return(false); } projVertices[i] = toScreenSpace(pOut, width, height); } //Buscar los puntos extremos var min = new TGCVector2(float.MaxValue, float.MaxValue); var max = new TGCVector2(float.MinValue, float.MinValue); var minDepth = float.MaxValue; foreach (var v in projVertices) { if (v.X < min.X) { min.X = v.X; } if (v.Y < min.Y) { min.Y = v.Y; } if (v.X > max.X) { max.X = v.X; } if (v.Y > max.Y) { max.Y = v.Y; } if (v.Z < minDepth) { minDepth = v.Z; } } //Clamp if (min.X < 0f) { min.X = 0f; } if (min.Y < 0f) { min.Y = 0f; } if (max.X >= width) { max.X = width - 1; } if (max.Y >= height) { max.Y = height - 1; } //Control de tamaño minimo if (max.X - min.X < 1f) { return(false); } if (max.Y - min.Y < 1f) { return(false); } //Cargar valores de box2D box2D.Location = new Point((int)min.X, (int)min.Y); box2D.Size = new Size((int)(max.X - min.X), (int)(max.Y - min.Y)); return(true); }
public override TgcBoundingAxisAlignBox ColisionXZ(TgcBoundingAxisAlignBox boundingBox) { // null => no hay colision TgcBoundingAxisAlignBox Colisionador = null; foreach (var Mesh in Scene.Meshes.FindAll(m => m.Enabled)) { if (!ListaMeshesSinColision.Contains(Mesh) && Escenario.testAABBAABB(Mesh.BoundingBox, boundingBox)) { if (ListaPozos.Contains(Mesh)) { Env.Personaje.SetTipoColisionActual(TiposColision.Pozo); break; } else if (ListaPlataformas.Contains(Mesh)) { if (Mesh.BoundingBox.PMax.Y > Env.Personaje.Mesh.Position.Y || Mesh.BoundingBox.PMin.Y < Env.Personaje.Mesh.Position.Y) { Colisionador = Mesh.BoundingBox; break; } } else if (ListaPisosResbalosos.Contains(Mesh)) { Env.Personaje.SetTipoColisionActual(TiposColision.PisoResbaloso); break; } else if (ListaEscalones.Contains(Mesh)) { var c = Mesh.BoundingBox; var aabb = Env.Personaje.Mesh.BoundingBox; Env.Personaje.setposition(new TGCVector3(0, c.PMax.Y - Env.Personaje.Position().Y, 0)); Env.Personaje.SetTipoColisionActual(TiposColision.Caja); break; } else if (ListaLogos.Contains(Mesh)) { ListaLogosQuitados.Add(Mesh); Scene.Meshes.Remove(Mesh); //Mesh.Enabled = false; //Deberia dejar de mostrarse ListaLogos.Remove(Mesh); //lo quito de la lista asi no se contabiliza CantLogos = ListaLogos.Count; break; } else { Colisionador = Mesh.BoundingBox; } break; } } foreach (var caja in ListaCajasEmpujables) { var aabb = caja.Mesh.BoundingBox; if (!Escenario.testAABBAABB(aabb, boundingBox)) { continue; } var oldCajaPos = caja.Mesh.Position; caja.ColisionXZ(Env.Personaje); bool colisionDeCaja = false; foreach (var Mesh in Scene.Meshes.FindAll(m => m.Enabled)) { if (Escenario.testAABBAABB(aabb, Mesh.BoundingBox)) { colisionDeCaja = true; continue; } } if (colisionDeCaja) { Colisionador = aabb; caja.Mesh.Position = oldCajaPos; break; } foreach (var pozo in ListaPozos) { if (Escenario.testAABBAABBXZIn(aabb, pozo.BoundingBox)) { caja.caer(); continue; } } } foreach (var Mesh in MeshConMovimiento) { if (!ListaMeshesSinColision.Contains(Mesh) && Escenario.testAABBAABB(Mesh.BoundingBox, boundingBox)) { if (ListaPozos.Contains(Mesh)) { Env.Personaje.SetTipoColisionActual(TiposColision.Pozo); } else if (ListaPlataformas.Contains(Mesh)) { if (PlataformaY.Equals(Mesh)) { posMuerte = -255; } if (Mesh.BoundingBox.PMax.Y > Env.Personaje.Mesh.Position.Y || (Mesh.BoundingBox.PMin.Y < Env.Personaje.Mesh.BoundingBox.PMax.Y && Mesh.BoundingBox.PMax.Y > Env.Personaje.Mesh.BoundingBox.PMax.Y)) { Colisionador = Mesh.BoundingBox; } } else if (ListaPisosResbalosos.Contains(Mesh)) { Env.Personaje.SetTipoColisionActual(TiposColision.PisoResbaloso); } else { Colisionador = Mesh.BoundingBox; } break; } } return(Colisionador); }
public void ActualizarBoundingOrientedBox(TgcBoundingAxisAlignBox AABB) { this.obb = TgcBoundingOrientedBox.computeFromAABB(AABB); this.obb.rotate(new TGCVector3(0, this.rotacionObb, 0)); this.obb.updateValues(); }
public override TgcBoundingAxisAlignBox ColisionY(TgcBoundingAxisAlignBox boundingBox) { TgcBoundingAxisAlignBox Colisionador = null; foreach (var plataforma in Plataformas) { if (Escenario.testAABBAABB(plataforma.Mesh.BoundingBox, boundingBox)) { if (plataforma.Mesh.BoundingBox.PMin.Y < Env.Personaje.Mesh.BoundingBox.PMax.Y && plataforma.Mesh.BoundingBox.PMin.Y + (plataforma.Mesh.BoundingBox.PMax.Y - plataforma.Mesh.BoundingBox.PMin.Y) * 0.5f > Env.Personaje.Mesh.BoundingBox.PMax.Y) { Env.Personaje.setposition(plataforma.Mesh.BoundingBox.PMin - (Env.Personaje.Mesh.BoundingBox.PMax - Env.Personaje.Mesh.BoundingBox.PMin)); Env.Personaje.SetTipoColisionActual(TiposColision.Techo); } else { if (plataforma.Mesh.BoundingBox.PMin.Y < Env.Personaje.Mesh.Position.Y) { Colisionador = plataforma.Mesh.BoundingBox; } Env.Personaje.setposition(plataforma.deltaPosicion()); Env.Personaje.SetTipoColisionActual(TiposColision.Caja); } } } foreach (var escalon in ListaEscalones) { if (Escenario.testAABBAABB(escalon.BoundingBox, boundingBox)) { //Env.Personaje.SetTipoColisionActual(TiposColision.Escalon); Colisionador = escalon.BoundingBox; } } foreach (var caja in ListaCajasEmpujables) { var colision = caja.ColisionY(Env.Personaje, Env.ElapsedTime); if (colision != null) { Colisionador = colision; } } if (Colisionador != null) { return(Colisionador); } var piso = ColisionConPiso(boundingBox); if (piso != null) { bool agujero = false; foreach (var pozo in ListaPozos) { if (Escenario.testAABBAABBXZIn(boundingBox, pozo.BoundingBox)) { Env.Personaje.SetTipoColisionActual(TiposColision.Pozo); agujero = true; break; } } if (!agujero) { Colisionador = piso; } } return(Colisionador); }
public bool Colisionar(TgcBoundingAxisAlignBox bb) { return(TgcCollisionUtils.intersectRayAABB(this.ray, bb, out this.puntoInterseccion)); }
/// <summary> /// Carga la escena a partir de un objeto TgcSceneData ya parseado /// </summary> /// <param name="sceneData">Objeto con datos de la escena ya parseados</param> /// <param name="mediaPath">Path a partir del cual hay que buscar los recursos de escena (Texturas, LightMaps, etc.)</param> /// <returns></returns> public TgcScene loadScene(TgcSceneData sceneData, string mediaPath) { var tgcScene = new TgcScene(sceneData.name, null); //Cargar Texturas var materialsArray = new TgcSceneLoaderMaterialAux[sceneData.materialsData.Length]; for (var i = 0; i < sceneData.materialsData.Length; i++) { var materialData = sceneData.materialsData[i]; var texturesPath = mediaPath + sceneData.texturesDir + "\\"; //Crear StandardMaterial if (materialData.type.Equals(TgcMaterialData.StandardMaterial)) { materialsArray[i] = createTextureAndMaterial(materialData, texturesPath); } //Crear MultiMaterial else if (materialData.type.Equals(TgcMaterialData.MultiMaterial)) { var matAux = new TgcSceneLoaderMaterialAux(); materialsArray[i] = matAux; matAux.subMaterials = new TgcSceneLoaderMaterialAux[materialData.subMaterials.Length]; for (var j = 0; j < materialData.subMaterials.Length; j++) { matAux.subMaterials[j] = createTextureAndMaterial(materialData.subMaterials[j], texturesPath); } } } //Cargar Meshes for (var i = 0; i < sceneData.meshesData.Length; i++) { var meshData = sceneData.meshesData[i]; TgcMesh tgcMesh = null; //Crear malla original if (meshData.instanceType.Equals(TgcMeshData.ORIGINAL)) { //Crear mesh que no tiene Material, con un color simple if (meshData.materialId == -1) { tgcMesh = crearMeshSoloColor(meshData); } //Para los que si tienen Material else { //Crear MeshFormat que soporte LightMaps if (meshData.lightmapEnabled) { tgcMesh = crearMeshDiffuseMapLightmap(sceneData, mediaPath, materialsArray, meshData); } //Formato de Mesh con Textura pero sin Lightmap else { tgcMesh = crearMeshDiffuseMap(materialsArray, meshData); } } //Fixloader tgcMesh.AutoTransformEnable = true; } //Crear malla instancia else if (meshData.instanceType.Equals(TgcMeshData.INSTANCE)) { tgcMesh = crearMeshInstance(meshData, tgcScene.Meshes); tgcMesh.AutoTransformEnable = true; } //Crear BoundingBox, aprovechar lo que viene del XML o crear uno por nuestra cuenta if (meshData.pMin != null && meshData.pMax != null) { tgcMesh.BoundingBox = new TgcBoundingAxisAlignBox( TGCVector3.Float3ArrayToVector3(meshData.pMin), TGCVector3.Float3ArrayToVector3(meshData.pMax), tgcMesh.Position, tgcMesh.Scale ); } else { tgcMesh.createBoundingBox(); } //Cargar layer tgcMesh.Layer = meshData.layerName; //Cargar AlphaBlending tgcMesh.AlphaBlendEnable = meshData.alphaBlending; //agregar mesh a escena tgcMesh.Enabled = true; tgcScene.Meshes.Add(tgcMesh); //Cargar userProperties, si hay tgcMesh.UserProperties = meshData.userProperties; } //BoundingBox del escenario, utilizar el que viene del XML o crearlo nosotros if (sceneData.pMin != null && sceneData.pMax != null) { tgcScene.BoundingBox = new TgcBoundingAxisAlignBox( new TGCVector3(sceneData.pMin[0], sceneData.pMin[1], sceneData.pMin[2]), new TGCVector3(sceneData.pMax[0], sceneData.pMax[1], sceneData.pMax[2]) ); } else { var boundingBoxes = new List <TgcBoundingAxisAlignBox>(); foreach (var mesh in tgcScene.Meshes) { boundingBoxes.Add(mesh.BoundingBox); } tgcScene.BoundingBox = TgcBoundingAxisAlignBox.computeFromBoundingBoxes(boundingBoxes); } //Cargar parte de PortalRendering, solo hay información if (sceneData.portalData != null) { var portalLoader = new TgcPortalRenderingLoader(); tgcScene.PortalRendering = portalLoader.loadFromData(tgcScene, sceneData.portalData); } return(tgcScene); }
/// <summary> /// Crear una nueva camara /// </summary> public ThirdPersonCamera() { resetValues(); aabb = new TgcBoundingAxisAlignBox(new TGCVector3(-1, -1, -1), new TGCVector3(0.2f, 0.2f, 0.2f)); }
public override TgcBoundingAxisAlignBox ColisionConPiso(TgcBoundingAxisAlignBox boundingBox) { return(null); }
public abstract TgcBoundingAxisAlignBox ColisionY(TgcBoundingAxisAlignBox boundingBox);
/// <summary> /// Detección de colisiones recursiva /// </summary> public void doCollideWithWorld(TgcBoundingSphere characterSphere, Vector3 movementVector, List <TgcBoundingAxisAlignBox> obstaculos, int recursionDepth) { //Limitar recursividad if (recursionDepth > 5) { return; } //Ver si la distancia a recorrer es para tener en cuenta var distanceToTravelSq = movementVector.LengthSq(); if (distanceToTravelSq < EPSILON) { return; } //Posicion deseada var originalSphereCenter = characterSphere.Center; var nextSphereCenter = originalSphereCenter + movementVector; //Buscar el punto de colision mas cercano de todos los objetos candidatos var minCollisionDistSq = float.MaxValue; var realMovementVector = movementVector; TgcBoundingAxisAlignBox.Face collisionFace = null; TgcBoundingAxisAlignBox collisionObstacle = null; var nearestPolygonIntersectionPoint = Vector3.Empty; foreach (var obstaculoBB in obstaculos) { //Obtener los polígonos que conforman las 6 caras del BoundingBox var bbFaces = obstaculoBB.computeFaces(); foreach (var bbFace in bbFaces) { var pNormal = TgcCollisionUtils.getPlaneNormal(bbFace.Plane); var movementRay = new TgcRay(originalSphereCenter, movementVector); float brutePlaneDist; Vector3 brutePlaneIntersectionPoint; if (!TgcCollisionUtils.intersectRayPlane(movementRay, bbFace.Plane, out brutePlaneDist, out brutePlaneIntersectionPoint)) { continue; } var 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; var planeNormalRay = new TgcRay(originalSphereCenter, -pNormal); var embebbed = false; var collisionFound = false; if (TgcCollisionUtils.intersectRayPlane(planeNormalRay, bbFace.Plane, out pDist, out planeIntersectionPoint)) { //Ver si el plano está embebido en la esfera if (isEmbebbed(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 var 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"); characterSphere.moveCenter(new Vector3(originalSphereCenter.X, 0, originalSphereCenter.Z) - new Vector3(pNormal.X, 0, pNormal.Z) * characterSphere.Radius); } 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 var 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 var 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 var movementLength = realMovementVector.Length(); realMovementVector.Multiply((movementLength - EPSILON) / movementLength); characterSphere.moveCenter(realMovementVector); } //Calcular plano de Sliding var slidePlaneOrigin = nearestPolygonIntersectionPoint; var slidePlaneNormal = characterSphere.Center - nearestPolygonIntersectionPoint; slidePlaneNormal.Normalize(); var slidePlane = Plane.FromPointNormal(slidePlaneOrigin, slidePlaneNormal); //Proyectamos el punto original de destino en el plano de sliding var 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 var slideMovementVector = slideDestinationPoint - nearestPolygonIntersectionPoint; if (slideMovementVector.LengthSq() < EPSILON) { return; } //Recursividad para aplicar sliding doCollideWithWorld(characterSphere, slideMovementVector, obstaculos, recursionDepth + 1); } }
public BoundingBoxCollider() { eAABB = new TgcBoundingAxisAlignBox(); }
/// <summary> /// Ver si un punto pertenece a una cara de un BoundingBox /// </summary> /// <returns>True si pertenece</returns> private bool pointInBounbingBoxFace(Vector3 p, TgcBoundingAxisAlignBox.Face bbFace) { Vector3 min = bbFace.Extremes[0]; Vector3 max = bbFace.Extremes[3]; return p.X >= min.X && p.Y >= min.Y && p.Z >= min.Z && p.X <= max.X && p.Y <= max.Y && p.Z <= max.Z; }
public TgcPortalRenderingPortal(string name, TgcBoundingAxisAlignBox boundingBox) { Name = name; BoundingBox = boundingBox; }
public static bool testAABBAABB(TgcBoundingAxisAlignBox a, TgcBoundingAxisAlignBox b) { return((a.PMin.X <= b.PMax.X && a.PMax.X >= b.PMin.X) && (a.PMin.Y <= b.PMax.Y && a.PMax.Y >= b.PMin.Y) && (a.PMin.Z <= b.PMax.Z && a.PMax.Z >= b.PMin.Z)); }
public void MoveXZ(TGCVector3 movimiento, TgcBoundingAxisAlignBox lastCollider = null) { PosBeforeMovingInXZ = Mesh.Position; Mesh.Position += movimiento; var Collider = Env.Escenario.ColisionXZ(Mesh.BoundingBox); if (movimiento == TGCVector3.Empty) { return; } if (Collider == null && TipoColisionActual == TiposColision.Pozo) { Pozo(); } //El personaje se movera con la plataforma else if (Collider == null && TipoColisionActual == TiposColision.Caja) { Mesh.Move(posicionPlataforma); } else if (Collider != null) { Collider = Collider.clone(); Collider.scaleTranslate(TGCVector3.Empty, new TGCVector3(1.05f, 1.05f, 1.05f)); var movementRay = PosBeforeMovingInXZ - Mesh.Position; var rs = TGCVector3.Empty; if (((Mesh.BoundingBox.PMax.X > Collider.PMax.X && movementRay.X > 0) || (Mesh.BoundingBox.PMin.X < Collider.PMin.X && movementRay.X < 0)) && ((Mesh.BoundingBox.PMax.Z > Collider.PMax.Z && movementRay.Z > 0) || (Mesh.BoundingBox.PMin.Z < Collider.PMin.Z && movementRay.Z < 0))) { //Este primero es un caso particularse dan las dos condiciones simultaneamente entonces para saber de que lado moverse hay que hacer algunos calculos mas. //por el momento solo se esta verificando que la posicion actual este dentro de un bounding para moverlo en ese plano. if (Mesh.Position.X > Collider.PMin.X && Mesh.Position.X < Collider.PMax.X) { //El personaje esta contenido en el bounding X //Sliding Z Dentro de X rs = new TGCVector3(movementRay.X, movementRay.Y, 0); } if (Mesh.Position.Z > Collider.PMin.Z && Mesh.Position.Z < Collider.PMax.Z) { //El personaje esta contenido en el bounding Z //Sliding X Dentro de Z rs = new TGCVector3(0, movementRay.Y, movementRay.Z); } //Seria ideal sacar el punto mas proximo al bounding que colisiona y chequear con eso, en ves que con la posicion. } else { if ((Mesh.BoundingBox.PMax.X > Collider.PMax.X && movementRay.X > 0) || (Mesh.BoundingBox.PMin.X < Collider.PMin.X && movementRay.X < 0)) { //Sliding X rs = new TGCVector3(0, movementRay.Y, movementRay.Z); } if ((Mesh.BoundingBox.PMax.Z > Collider.PMax.Z && movementRay.Z > 0) || (Mesh.BoundingBox.PMin.Z < Collider.PMin.Z && movementRay.Z < 0)) { //Sliding Z rs = new TGCVector3(movementRay.X, movementRay.Y, 0); } } Mesh.Position = PosBeforeMovingInXZ; MoveXZ(rs * -0.9f, Collider); } }
public bool GetDistanceWithObject(TgcBoundingAxisAlignBox objectAABB, out float distance) { pickingRay.updateRay(); distance = TgcCollisionUtils.sqDistPointAABB(pickingRay.Ray.Origin, objectAABB); return(distance > 0); }
public PlataformaAscensor getPlataformaAscensor(TgcBoundingAxisAlignBox piso) { return(pAscensor.Find(p => p.getAABB() == piso)); }