/// <summary> /// Centrar la camara sobre un objeto seleccionado /// </summary> public void zoomObject() { TgcBoundingBox aabb = MeshCreatorUtils.getSelectionBoundingBox(control.SelectionList); if (aabb != null) { control.Camera.CameraCenter = aabb.calculateBoxCenter(); } }
/// <summary> /// Proyectar punto 3D a 2D /// </summary> /// <param name="box3d">Punto 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 projectPoint(Vector3 p, out Rectangle box2D) { //Datos de viewport Device d3dDevice = GuiController.Instance.D3dDevice; Viewport viewport = d3dDevice.Viewport; Matrix view = d3dDevice.Transform.View; Matrix proj = d3dDevice.Transform.Projection; int width = viewport.Width; int height = viewport.Height; Matrix m = view * proj; //Proyectar box2D = new Rectangle(); Vector4 pOut = Vector3.Transform(p, m); if (pOut.W < 0) { return(false); } Vector3 projVertex = MeshCreatorUtils.toScreenSpace(pOut, width, height); Vector2 min = new Vector2(projVertex.X, projVertex.Y); Vector2 max = min + new Vector2(1, 1); //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); }
/// <summary> /// Poner la camara en front view respecto de un objeto seleccionado /// </summary> public void setFrontView() { TgcBoundingBox aabb = MeshCreatorUtils.getSelectionBoundingBox(control.SelectionList); Vector3 lookAt; if (aabb != null) { lookAt = aabb.calculateBoxCenter(); } else { lookAt = new Vector3(0, 0, 0); } control.Camera.setFixedView(lookAt, 0, 0, control.Camera.CameraDistance); }
/// <summary> /// Proyectar un poligono 3D a 2D en la pantalla /// </summary> /// <param name="vertices">Vertices del poligono</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 projectPolygon(Vector3[] vertices, out Rectangle box2D) { //Datos de viewport Device d3dDevice = GuiController.Instance.D3dDevice; Viewport viewport = d3dDevice.Viewport; Matrix view = d3dDevice.Transform.View; Matrix proj = d3dDevice.Transform.Projection; int width = viewport.Width; int height = viewport.Height; box2D = new Rectangle(); //Proyectar todos los puntos, sin dividir aun por W Matrix m = view * proj; Vector3[] projVertices = new Vector3[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { Vector4 pOut = Vector3.Transform(vertices[i], m); if (pOut.W < 0) { return(false); } projVertices[i] = MeshCreatorUtils.toScreenSpace(pOut, width, height); } //Buscar los puntos extremos Vector2 min = new Vector2(float.MaxValue, float.MaxValue); Vector2 max = new Vector2(float.MinValue, float.MinValue); float minDepth = float.MaxValue; foreach (Vector3 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); }
/// <summary> /// Actualizar y dibujar seleccion /// </summary> public void render() { TgcD3dInput input = GuiController.Instance.D3dInput; //Mantiene el mouse apretado if (input.buttonDown(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //Definir recuadro Vector2 mousePos = new Vector2(input.Xpos, input.Ypos); Vector2 min = Vector2.Minimize(initMousePos, mousePos); Vector2 max = Vector2.Maximize(initMousePos, mousePos); rectMesh.updateMesh(min, max); } //Solo el mouse else if (input.buttonUp(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //Definir recuadro Vector2 mousePos = new Vector2(input.Xpos, input.Ypos); Vector2 min = Vector2.Minimize(initMousePos, mousePos); Vector2 max = Vector2.Maximize(initMousePos, mousePos); Rectangle r = new Rectangle((int)min.X, (int)min.Y, (int)(max.X - min.X), (int)(max.Y - min.Y)); //Usar recuadro de seleccion solo si tiene un tamaño minimo if (r.Width > 1 && r.Height > 1) { //Limpiar seleccionar anterior si no estamos agregando en forma aditiva if (!selectiveObjectsAdditive) { clearSelection(); } //Buscar que objetos del escenario caen dentro de la seleccion y elegirlos foreach (EditorPrimitive p in control.Meshes) { //Solo los visibles if (p.Visible) { //Ver si hay colision contra la proyeccion del AABB del mesh //Rectangle primRect = MeshCreatorUtils.projectAABB(p.BoundingBox); Rectangle primRect; if (MeshCreatorUtils.projectBoundingBox(p.BoundingBox, out primRect)) { if (r.IntersectsWith(primRect)) { //Agregar el objeto en forma aditiva if (selectiveObjectsAdditive) { selectOrRemoveObjectIfPresent(p); } //Agregar el objeto en forma simple else { selectObject(p); } } } } } } //Si el recuadro no tiene tamaño suficiente, hacer seleccion directa else { doDirectSelection(selectiveObjectsAdditive); } control.CurrentState = MeshCreatorControl.State.SelectObject; //Si quedo algo seleccionado activar gizmo if (control.SelectionList.Count > 0) { activateCurrentGizmo(); } //Actualizar panel de Modify con lo que se haya seleccionado, o lo que no control.updateModifyPanel(); } //Dibujar recuadro rectMesh.render(); }
/// <summary> /// Obtener pivote central para efectuar la rotacion. /// Se busca el centro de todos los AABB /// </summary> public Vector3 getRotationPivot() { TgcBoundingBox aabb = MeshCreatorUtils.getSelectionBoundingBox(control.SelectionList); return(aabb.calculateBoxCenter()); }