/// <summary> /// Construir plano /// </summary> public override void doCreation() { TgcD3dInput input = GuiController.Instance.D3dInput; //Si hacen clic con el mouse, ver si hay colision con el suelo if (input.buttonDown(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //Obtener altura en Y segun movimient en Y del mouse float heightY = creatingInitMouseY - input.Ypos; float adjustedHeightY = MeshCreatorUtils.getMouseIncrementHeightSpeed(Control.Camera, this.BoundingBox, heightY); //Determinar posicion X segun la colision con el grid Vector3 collisionPoint = Control.Grid.getPicking(); Vector3 extensionPoint = new Vector3(collisionPoint.X, initSelectionPoint.Y + adjustedHeightY, initSelectionPoint.Z); //Obtener maximo y minimo Vector3 min = Vector3.Minimize(initSelectionPoint, extensionPoint); Vector3 max = Vector3.Maximize(initSelectionPoint, extensionPoint); min.Z = initSelectionPoint.Z; max.Z = initSelectionPoint.Z + 1; //Configurar plano mesh.setExtremes(min, max); mesh.updateValues(); } //Solto el clic del mouse, generar plano definitivo else if (input.buttonUp(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //Tiene el tamaño minimo tolerado Vector3 size = mesh.BoundingBox.calculateSize(); if (size.X > 1 && size.Y > 1) { //Guardar size original del plano para hacer Scaling originalSize = mesh.Size; //Dejar cargado para que se pueda crear un nuevo plano Control.CurrentState = MeshCreatorControl.State.CreatePrimitiveSelected; Control.CreatingPrimitive = new PlaneXYPrimitive(Control); //Agregar plano a la lista de modelos Control.addMesh(this); //Seleccionar plano Control.SelectionRectangle.clearSelection(); Control.SelectionRectangle.selectObject(this); Control.updateModifyPanel(); } //Sino, descartar else { Control.CurrentState = MeshCreatorControl.State.CreatePrimitiveSelected; mesh.dispose(); mesh = null; } } }
/// <summary> /// Construir plano /// </summary> public override void doCreation() { TgcD3dInput input = GuiController.Instance.D3dInput; //Si hacen clic con el mouse, ver si hay colision con el suelo if (input.buttonDown(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //Determinar el size en XZ del box Vector3 collisionPoint = Control.Grid.getPicking(); //Obtener extremos del rectángulo de selección Vector3 min = Vector3.Minimize(initSelectionPoint, collisionPoint); Vector3 max = Vector3.Maximize(initSelectionPoint, collisionPoint); min.Y = 0; max.Y = 1; //Configurar plano mesh.setExtremes(min, max); mesh.updateValues(); } //Solto el clic del mouse, generar plano definitivo else if (input.buttonUp(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //Tiene el tamaño minimo tolerado Vector3 size = mesh.BoundingBox.calculateSize(); if (size.X > 1 && size.Z > 1) { //Guardar size original del plano para hacer Scaling originalSize = mesh.Size; //Dejar cargado para que se pueda crear un nuevo plano Control.CurrentState = MeshCreatorControl.State.CreatePrimitiveSelected; Control.CreatingPrimitive = new PlaneXZPrimitive(Control); //Agregar plano a la lista de modelos Control.addMesh(this); //Seleccionar plano Control.SelectionRectangle.clearSelection(); Control.SelectionRectangle.selectObject(this); Control.updateModifyPanel(); } //Sino, descartar else { Control.CurrentState = MeshCreatorControl.State.CreatePrimitiveSelected; mesh.dispose(); mesh = null; } } }
/// <summary> /// Manejar eventos de Input /// </summary> private void handleInput() { TgcD3dInput input = GuiController.Instance.D3dInput; //Seleccionar modelo if (currentState == GuiState.SelectionMode) { //Picking con mouse Izquierdo if (input.buttonPressed(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { findSelectedMeshWithPicking(); } } //Trasladar modelo seleccionado else if (currentState == GuiState.TranslateMode) { if (selectedMeshList.Count > 0) { //Comenzar a trasladar if (input.buttonPressed(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { initGizmoDragging(); } //Arrastrando gizmo else if (input.buttonDown(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { doGizmoTranslate(); } //Terminar el traslado else if (input.buttonUp(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { endGizmoDragging(); } } } }
public override void update() { TgcD3dInput input = GuiController.Instance.D3dInput; switch (currentState) { case State.Init: selectedAxis = Axis.None; //Iniciar seleccion de eje if (input.buttonDown(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { Control.PickingRay.updateRay(); Vector3 collP; //Buscar colision con eje con Picking if (TgcCollisionUtils.intersectRayAABB(Control.PickingRay.Ray, boxX.BoundingBox, out collP)) { selectedAxis = Axis.X; } else if (TgcCollisionUtils.intersectRayAABB(Control.PickingRay.Ray, boxY.BoundingBox, out collP)) { selectedAxis = Axis.Y; } else if (TgcCollisionUtils.intersectRayAABB(Control.PickingRay.Ray, boxZ.BoundingBox, out collP)) { selectedAxis = Axis.Z; } else { selectedAxis = Axis.None; } //Si eligio un eje, iniciar dragging if (selectedAxis != Axis.None) { currentState = State.Dragging; initMouseP = new Vector2(input.XposRelative, input.YposRelative); } else { if (input.buttonPressed(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { bool additive = input.keyDown(Microsoft.DirectX.DirectInput.Key.LeftControl) || input.keyDown(Microsoft.DirectX.DirectInput.Key.RightControl); Control.CurrentState = MeshCreatorControl.State.SelectObject; Control.SelectionRectangle.doDirectSelection(additive); } } } //Hacer mouse over sobre los ejes else { Control.PickingRay.updateRay(); Vector3 collP; //Buscar colision con eje con Picking if (TgcCollisionUtils.intersectRayAABB(Control.PickingRay.Ray, boxX.BoundingBox, out collP)) { selectedAxis = Axis.X; } else if (TgcCollisionUtils.intersectRayAABB(Control.PickingRay.Ray, boxY.BoundingBox, out collP)) { selectedAxis = Axis.Y; } else if (TgcCollisionUtils.intersectRayAABB(Control.PickingRay.Ray, boxZ.BoundingBox, out collP)) { selectedAxis = Axis.Z; } else { selectedAxis = Axis.None; } } break; case State.Dragging: //Mover if (input.buttonDown(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //Obtener vector 2D de movimiento relativo del mouse Vector2 mouseScreenVec = new Vector2(input.XposRelative, input.YposRelative); //mouseScreenVec.Normalize(); //Projectar vector 2D del eje elegido TgcBox currentAxisBox = getAxisBox(selectedAxis); Vector2 axisScreenVec = MeshCreatorUtils.projectAABBScreenVec(currentAxisBox.BoundingBox); //Hacer DOT product entre ambos vectores para obtener la contribucion del mouse en esa direccion float scaling = Vector2.Dot(axisScreenVec, mouseScreenVec); scaling = MeshCreatorUtils.getMouseScaleIncrementSpeed(Control.Camera, currentAxisBox.BoundingBox, scaling); Vector3 currentScale = new Vector3(0, 0, 0); //Escala en eje X if (selectedAxis == Axis.X) { currentScale.X = scaling; } //Escala en eje Y else if (selectedAxis == Axis.Y) { currentScale.Y = scaling; } //Escala en eje Z else if (selectedAxis == Axis.Z) { currentScale.Z = scaling; } //Escalar objetos foreach (EditorPrimitive p in Control.SelectionList) { //Agregar scaling, controlando que no sea menor a cero Vector3 scale = p.Scale; Vector3 oldMin = p.BoundingBox.PMin; scale += currentScale; scale.X = scale.X < 0.01f ? 0.01f : scale.X; scale.Y = scale.Y < 0.01f ? 0.01f : scale.Y; scale.Z = scale.Z < 0.01f ? 0.01f : scale.Z; p.Scale = scale; //Si se escala para una sola direccion hay que desplazar el objeto if (!Control.ScaleBothDirections) { p.move(oldMin - p.BoundingBox.PMin); } } //TODO: Hay que ir estirando los ejes a medida que se agranda la escala //Actualizar datos de modify Control.updateModifyPanel(); } //Soltar movimiento else if (input.buttonUp(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { currentState = State.Init; selectedAxis = Axis.None; } break; } //Ajustar tamaño de ejes setAxisPositionAndSize(); }
/// <summary> /// Llamado una vez por frame /// </summary> /// <param name="input"></param> public void Update(TgcD3dInput input) { nitroActivado = false; volanteo = false; BugFixAutoNoAparece(); SeleccionarMeshesCercanos(400f); huboMovimiento = huboRotacion = false; bool collisionFound = huboSalto = false; //pintarObb = false; PosicionAnterior = Mesh.Position; RotacionAnterior = Mesh.Rotation; marchaAtras = false; //1 acelerar if (input.keyDown(Key.W)) { Acelero(1); huboMovimiento = true; if (input.keyDown(Key.LeftShift)) { Acelero(0.5f); //turbo! nitroActivado = true; } } //2 frenar, reversa if (input.keyDown(Key.S)) { Freno(); huboMovimiento = true; marchaAtras = true; } //3 izquierda TODO//girar ruedas if (input.keyDown(Key.A)) { DoblarRuedas(1); } //4 derecha TODO //girar ruedas if (input.keyDown(Key.D)) { DoblarRuedas(-1); } if (input.keyDown(Key.F)) { pintarObb = !pintarObb; } //5 disparar TODO -- if (input.buttonUp(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //disparar //this.ArmaSeleccionada.ammo--; //TODO falta evento de fin de ammo. } //6 cambiar de arma TODO if (input.buttonUp(TgcD3dInput.MouseButtons.BUTTON_RIGHT)) { } //7 freno de mano? maybe TODO if (input.keyPressed(Microsoft.DirectX.DirectInput.Key.Space)) { } //8 saltar if (input.keyDown(Key.Space) && (Mesh.Position.Y == 5)) { huboSalto = true; } else { //aceleracionVertical = -1; descomentar cuando el auto choque con el suelo. } //RuedasDelanteras.Update(Mesh.Position,Velocidad,DireccionRuedas); //RuedasTraseras.Update(Mesh.Position, Velocidad, DireccionRuedas); ProcesarInercia(); MoverMesh(); if (RenderLuces) { Luces.Update(); } if (motionBlur != null) { motionBlur.Update(0f); } if (RenderLuces) { Luces.Update(); } GameModel.FinishedLoading = true; RecobrarForma(); }
public override void update() { TgcD3dInput input = GuiController.Instance.D3dInput; switch (currentState) { case State.Init: acumMovement = Vector3.Empty; gizmoMesh.unSelect(); //Iniciar seleccion de eje if (input.buttonDown(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //Buscar colision con ejes del gizmo Control.PickingRay.updateRay(); gizmoMesh.selectAxisByPicking(Control.PickingRay.Ray); if (gizmoMesh.SelectedAxis == TranslateGizmoMesh.Axis.X) { initMouseP3d = Control.Grid.getPickingX(Control.PickingRay.Ray, gizmoMesh.GizmoCenter); } else if (gizmoMesh.SelectedAxis == TranslateGizmoMesh.Axis.Y) { initMouseP3d = Control.Grid.getPickingY(Control.PickingRay.Ray, gizmoMesh.GizmoCenter); } else if (gizmoMesh.SelectedAxis == TranslateGizmoMesh.Axis.Z) { initMouseP3d = Control.Grid.getPickingZ(Control.PickingRay.Ray, gizmoMesh.GizmoCenter); } else if (gizmoMesh.SelectedAxis == TranslateGizmoMesh.Axis.XZ) { initMouseP3d = Control.Grid.getPickingXZ(Control.PickingRay.Ray, gizmoMesh.GizmoCenter); } else if (gizmoMesh.SelectedAxis == TranslateGizmoMesh.Axis.XY) { initMouseP3d = Control.Grid.getPickingXY(Control.PickingRay.Ray, gizmoMesh.GizmoCenter); } else if (gizmoMesh.SelectedAxis == TranslateGizmoMesh.Axis.YZ) { initMouseP3d = Control.Grid.getPickingYZ(Control.PickingRay.Ray, gizmoMesh.GizmoCenter); } //Si eligio un eje, iniciar dragging if (gizmoMesh.SelectedAxis != TranslateGizmoMesh.Axis.None) { currentState = State.Dragging; } else { if (input.buttonPressed(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { bool additive = input.keyDown(Microsoft.DirectX.DirectInput.Key.LeftControl) || input.keyDown(Microsoft.DirectX.DirectInput.Key.RightControl); Control.CurrentState = MeshCreatorControl.State.SelectObject; Control.SelectionRectangle.doDirectSelection(additive); } } } //Hacer mouse over sobre los ejes else { //Buscar colision con eje con Picking Control.PickingRay.updateRay(); gizmoMesh.selectAxisByPicking(Control.PickingRay.Ray); } break; case State.Dragging: //Mover if (input.buttonDown(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { Control.PickingRay.updateRay(); Vector3 endMouseP3d = initMouseP3d; //Solo se mueve un eje Vector3 currentMove = new Vector3(0, 0, 0); if (gizmoMesh.isSingleAxis(gizmoMesh.SelectedAxis)) { //Desplazamiento en eje X if (gizmoMesh.SelectedAxis == TranslateGizmoMesh.Axis.X) { endMouseP3d = Control.Grid.getPickingX(Control.PickingRay.Ray, gizmoMesh.GizmoCenter); currentMove.X = endMouseP3d.X - initMouseP3d.X; } //Desplazamiento en eje Y else if (gizmoMesh.SelectedAxis == TranslateGizmoMesh.Axis.Y) { endMouseP3d = Control.Grid.getPickingY(Control.PickingRay.Ray, gizmoMesh.GizmoCenter); currentMove.Y = endMouseP3d.Y - initMouseP3d.Y; } //Desplazamiento en eje Z else if (gizmoMesh.SelectedAxis == TranslateGizmoMesh.Axis.Z) { endMouseP3d = Control.Grid.getPickingZ(Control.PickingRay.Ray, gizmoMesh.GizmoCenter); currentMove.Z = endMouseP3d.Z - initMouseP3d.Z; } } //Desplazamiento en dos ejes else { //Plano XZ if (gizmoMesh.SelectedAxis == TranslateGizmoMesh.Axis.XZ) { endMouseP3d = Control.Grid.getPickingXZ(Control.PickingRay.Ray, gizmoMesh.GizmoCenter); currentMove.X = endMouseP3d.X - initMouseP3d.X; currentMove.Z = endMouseP3d.Z - initMouseP3d.Z; } //Plano XY else if (gizmoMesh.SelectedAxis == TranslateGizmoMesh.Axis.XY) { endMouseP3d = Control.Grid.getPickingXY(Control.PickingRay.Ray, gizmoMesh.GizmoCenter); currentMove.X = endMouseP3d.X - initMouseP3d.X; currentMove.Y = endMouseP3d.Y - initMouseP3d.Y; } //Plano YZ else if (gizmoMesh.SelectedAxis == TranslateGizmoMesh.Axis.YZ) { endMouseP3d = Control.Grid.getPickingYZ(Control.PickingRay.Ray, gizmoMesh.GizmoCenter); currentMove.Y = endMouseP3d.Y - initMouseP3d.Y; currentMove.Z = endMouseP3d.Z - initMouseP3d.Z; } } //Actualizar pos del mouse 3D para proximo cuadro initMouseP3d = endMouseP3d; //Ajustar currentMove con Snap to grid if (Control.SnapToGridEnabled) { snapMovementToGrid(ref currentMove.X, ref acumMovement.X, Control.SnapToGridCellSize); snapMovementToGrid(ref currentMove.Y, ref acumMovement.Y, Control.SnapToGridCellSize); snapMovementToGrid(ref currentMove.Z, ref acumMovement.Z, Control.SnapToGridCellSize); } //Mover objetos foreach (EditorPrimitive p in Control.SelectionList) { p.move(currentMove); } //Mover ejes gizmoMesh.moveGizmo(currentMove); //Actualizar datos de modify Control.updateModifyPanel(); } //Soltar movimiento else if (input.buttonUp(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { currentState = State.Init; gizmoMesh.unSelect(); } break; } //Ajustar tamaño de ejes gizmoMesh.setCenter(gizmoMesh.GizmoCenter, Control.Camera); }
/// <summary> /// Construir caja /// </summary> public override void doCreation() { TgcD3dInput input = GuiController.Instance.D3dInput; switch (currentCreatingState) { case CreatingBoxState.DraggingSize: //Si hacen clic con el mouse, ver si hay colision con el suelo if (input.buttonDown(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //Determinar el size en XZ del box Vector3 collisionPoint = Control.Grid.getPicking(); //Obtener extremos del rectángulo de selección Vector3 min = Vector3.Minimize(initSelectionPoint, collisionPoint); Vector3 max = Vector3.Maximize(initSelectionPoint, collisionPoint); min.Y = initSelectionPoint.Y; max.Y = initSelectionPoint.Y + 0.2f; //Configurar BOX mesh.setExtremes(min, max); mesh.updateValues(); } //Solto el clic del mouse, pasar a configurar el Height del box else if (input.buttonUp(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //Tiene el tamaño minimo tolerado Vector3 size = mesh.BoundingBox.calculateSize(); if (size.X > 1 && size.Z > 1) { currentCreatingState = CreatingBoxState.DraggingHeight; creatingBoxInitMouseY = input.Ypos; } //Sino, descartar else { Control.CurrentState = MeshCreatorControl.State.CreatePrimitiveSelected; mesh.dispose(); mesh = null; } } break; case CreatingBoxState.DraggingHeight: //Si presiona clic, terminar de configurar la altura y generar box definitivo if (input.buttonPressed(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //Guardar size original del Box para hacer Scaling originalSize = mesh.BoundingBox.calculateSize(); //Dejar cargado para que se pueda crear un nuevo box Control.CurrentState = MeshCreatorControl.State.CreatePrimitiveSelected; Control.CreatingPrimitive = new BoxPrimitive(Control); //Agregar box a la lista de modelos Control.addMesh(this); //Seleccionar Box Control.SelectionRectangle.clearSelection(); Control.SelectionRectangle.selectObject(this); Control.updateModifyPanel(); } //Determinar altura en base a la posicion Y del mouse else { float heightY = creatingBoxInitMouseY - input.Ypos; float adjustedHeightY = MeshCreatorUtils.getMouseIncrementHeightSpeed(Control.Camera, this.BoundingBox, heightY); Vector3 min = mesh.BoundingBox.PMin; min.Y = initSelectionPoint.Y; Vector3 max = mesh.BoundingBox.PMax; max.Y = initSelectionPoint.Y + adjustedHeightY; //Configurar BOX mesh.setExtremes(min, max); mesh.updateValues(); } break; } }
/// <summary> /// Estado: Cuando se esta arrastrando el mouse para armar el cuadro de seleccion /// </summary> private void doSelectingObject() { 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 primitivas caen dentro de la seleccion y elegirlos int i = 0; EditPolyPrimitive p = iteratePrimitive(currentPrimitive, i); while (p != null) { //Ver si hay colision contra la proyeccion de la primitiva y el rectangulo 2D Rectangle primRect; if (p.projectToScreen(mesh.Transform, out primRect)) { if (r.IntersectsWith(primRect)) { //Agregar el objeto en forma aditiva if (selectiveObjectsAdditive) { selectOrRemovePrimitiveIfPresent(p); } //Agregar el objeto en forma simple else { selectPrimitive(p); } } } p = iteratePrimitive(currentPrimitive, ++i); } } //Si el recuadro no tiene tamaño suficiente, hacer seleccion directa else { doDirectSelection(selectiveObjectsAdditive); } currentState = State.SelectObject; /* * //Si quedo algo seleccionado activar gizmo * if (selectionList.Count > 0) * { * activateTranslateGizmo(); * } */ //Actualizar panel de Modify con lo que se haya seleccionado, o lo que no updateUiPanel(); } //Dibujar recuadro rectMesh.render(); }
/// <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(); }