#include "stdafx.h" #include "MW4GameEd.h" #include "MoveCommand.h" #include "EditorWaypoint.h" #include #include #include #include #include #include #include #include "DisplayWindow.h" #include "OverviewWindow.h" #include "Selection.h" extern CMW4GameEdApp theApp; MoveCommand::MoveCommand(Entity *object) : Command() { Check_Object(object); moveOffset = Point3D::Identity; cursorPosition = object->GetLocalToWorld(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MoveCommand::~MoveCommand() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MoveCommand::Execute() { Move(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MoveCommand::Undo() { theApp.MakeObjectsZoneBased(); LinearMatrix4D new_local_to_world; Point3D target_in_world; CSelectionNode *selection_node; YawPitchRoll current_rotation; Entity* entity; if (!selectedEntities.IsEmpty()) { ChainIteratorOf iterator(&selectedEntities); while((selection_node = iterator.ReadAndNext()) != NULL) { entity = selection_node->selectedEntity; target_in_world = entity->GetLocalToWorld(); target_in_world -= moveOffset; current_rotation = entity->GetLocalToParent(); new_local_to_world.BuildTranslation(target_in_world); new_local_to_world.BuildRotation(current_rotation); Check_Object(entity); entity->SetNewLocalToParent(new_local_to_world); entity->SyncMatrices(true); if (entity->IsDerivedFrom(EditorPathNode::DefaultData)) { EditorPathNode* node; node = Cast_Object(EditorPathNode*,entity); node->pathSlot.GetCurrent()->pathSlot.GetCurrent()->pathPoints[node->index] = target_in_world; node->UpdateLinkPointData(); } else if (entity->IsDerivedFrom(EditorBoundaryNode::DefaultData)) { EditorBoundaryNode* node; node = Cast_Object(EditorBoundaryNode*,entity); (*node->myBoundary)[node->index].x = target_in_world.x; (*node->myBoundary)[node->index].y = target_in_world.z; node->UpdateLinkPointData(); } else if (entity->IsDerivedFrom(EditorDropNode::DefaultData)) { EditorDropNode* node; node = Cast_Object(EditorDropNode*,entity); node->dropZone->SetNewLocalToParent(new_local_to_world); node->dropZone->SyncMatrices(true); EditorDropZonePoint* point; Point3D newPoint; LinearMatrix4D matrix = LinearMatrix4D::Identity; ChainIteratorOf iterator(&node->pointChain); while((point = iterator.ReadAndNext()) != NULL) { newPoint = new_local_to_world; newPoint -= point->offset; newPoint.y = theApp.displayWindow->GetMapPointVertical(newPoint.x,newPoint.z); matrix.BuildTranslation(newPoint); point->SetNewLocalToParent(matrix); point->SyncMatrices(true); point->UpdateLinkPointData(); } node->UpdatePoints(); } else if (entity->IsDerivedFrom(EditorDropZonePoint::DefaultData)) { EditorDropZonePoint* node; node = Cast_Object(EditorDropZonePoint*,entity); node->SetNewLocalToParent(new_local_to_world); node->SyncMatrices(true); node->UpdateLinkPointData(); node->dropNode->UpdatePoints(); } /* else if (entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData)) { EditorObjectiveMarker* node; node = Cast_Object(EditorObjectiveMarker*,entity); node->objective->SetNewLocalToParent(new_local_to_world); node->objective->SyncMatrices(true); } */ else if (entity->IsDerivedFrom(EditorPointLight::DefaultData)) { EditorPointLight* pointLight; pointLight = Cast_Object(EditorPointLight*,entity); pointLight->SetLightToWorldMatrix(pointLight->GetLocalToWorld()); } else if (entity->IsDerivedFrom(EditorSpotLight::DefaultData)) { EditorSpotLight* spotLight; spotLight = Cast_Object(EditorSpotLight*,entity); spotLight->SetLightToWorldMatrix(spotLight->GetLocalToWorld()); } else if (entity->IsDerivedFrom(EditorCameraShip::DefaultData)) { EditorCameraShip* node; node = Cast_Object(EditorCameraShip*,entity); node->cameraShip->SetNewLocalToParent(new_local_to_world); node->cameraShip->SyncMatrices(true); } } } theApp.MakeObjectsTileBased(); theApp.overviewWindow->DrawWindow(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MoveCommand::Move() { //This function needs to run through the list and move all according //to the offset of the cursor. This is not going to be as easy as it //seems. First just move one. Check_Object(Map::Instance); theApp.MakeObjectsZoneBased(); Point3D new_offset; LinearMatrix4D new_local_to_world; CSelectionNode *selection_node; Entity* entity; Point3D translation = Point3D::Identity; Check_Object(Player::Instance); Check_Object(Player::Instance->playerInterface); int x_down = GetAsyncKeyState(KEY_X) & 0x8000; int y_down = GetAsyncKeyState(KEY_Y) & 0x8000; int z_down = GetAsyncKeyState(KEY_Z) & 0x8000; Entity *reticule; reticule = Player::Instance->playerInterface->reticuleEntity.GetCurrent(); if(reticule) { Point3D world_offset = Player::Instance->playerInterface->reticuleOffset; LinearMatrix4D new_local_to_parent = LinearMatrix4D::Identity; new_local_to_parent.Multiply(reticule->GetLocalToParent(), world_offset); translation = new_local_to_parent; } else if (!y_down) // make sure we're not trying to move vertically. return; // must be pointing at the sky bool x_blocked = false, y_blocked = true, z_blocked = false; if (x_down || y_down || z_down) { x_blocked = !x_down; y_blocked = !y_down; z_blocked = !z_down; } new_offset = translation; new_offset -= cursorPosition; if (x_blocked) new_offset.x = 0; if (z_blocked) new_offset.z = 0; if (!(selectedEntities.IsEmpty())) { ChainIteratorOf iterator(&selectedEntities); iterator.First(); while((selection_node = iterator.ReadAndNext()) != NULL) { entity = selection_node->selectedEntity; Point3D target_in_world,old_entity_pos; target_in_world = entity->GetLocalToWorld(); old_entity_pos = target_in_world; YawPitchRoll current_rotation; current_rotation = entity->GetLocalToParent(); if (y_blocked) { target_in_world += new_offset; moveOffset += new_offset; target_in_world.y = theApp.displayWindow->GetMapPointVertical(target_in_world.x,target_in_world.z); CEditorEntityData *exdata=theApp.GetEntityData(entity); if(exdata) target_in_world.y+=exdata->VOffset; } else { Vector2DOf cursor; gos_GetMouseInfo(&cursor.x, &cursor.y, NULL, NULL, NULL, NULL); // Clean out the interface data Check_Object(VideoRenderer::Instance); EntityComponentWeb *web = Cast_Object(EntityComponentWeb*,VideoRenderer::Instance->GetSceneCamera()->GetComponentWeb()); Interface *intface = Cast_Object(Interface*, web->GetEntity()); intface->reticuleEntity.Remove(); // Figure out the eyeline Line3D world_line; VideoRenderer::Instance->GetSceneCamera()->ComputeEyeLine(&world_line, cursor); Point3D point,y_offset; point = entity->GetLocalToWorld(); Vector3D vector(world_line.m_direction.x,0,world_line.m_direction.z); Normal3D plane_normal; plane_normal.Normalize(vector); Stuff::Plane plane(plane_normal,plane_normal * point); Scalar axis; Scalar length = world_line.GetDistanceTo(plane,&axis); world_line.Project(length,&y_offset); target_in_world += new_offset; moveOffset += new_offset; } if (theApp.gridOn && !(x_down || y_down || z_down)) theApp.GetGridCoords(target_in_world); new_local_to_world.BuildTranslation(target_in_world); new_local_to_world.BuildRotation(current_rotation); Check_Object(entity); entity->SetNewLocalToParent(new_local_to_world); entity->SyncMatrices(true); // EntityManager::Instance->RequestPostCollisionExecution(entity); Map::Instance->UpdateZone(entity); Check_Object(EntityManager::Instance); if (entity->GetSolidVolume() || entity->GetCollisionMask() == Entity::EditorIsMovingFlag) { if (entity->IsMultiZone()) entity->GetElement()->SetCallbackIndex(ElementRenderer::Element::DrawRedBounds); else if (entity->IsMultiTile()) entity->GetElement()->SetCallbackIndex(ElementRenderer::Element::DrawYellowBounds); else entity->GetElement()->SetCallbackIndex(ElementRenderer::Element::DrawGreenBounds); } else entity->GetElement()->SetCallbackIndex(ElementRenderer::Element::DrawGreenBounds); if (entity->IsDerivedFrom(EditorLatticeNode::DefaultData)) { EditorLatticeNode* node; node = Cast_Object(EditorLatticeNode*,entity); node->railNode->Location(target_in_world); node->railNode->UpdateRadiusPointData(); } else if (entity->IsDerivedFrom(EditorPathNode::DefaultData)) { EditorPathNode* node; node = Cast_Object(EditorPathNode*,entity); node->pathSlot.GetCurrent()->pathSlot.GetCurrent()->pathPoints[node->index] = target_in_world; node->UpdateLinkPointData(); } else if (entity->IsDerivedFrom(EditorBoundaryNode::DefaultData)) { EditorBoundaryNode* node; node = Cast_Object(EditorBoundaryNode*,entity); (*node->myBoundary)[node->index].x = target_in_world.x; (*node->myBoundary)[node->index].y = target_in_world.z; node->CheckValidPos(); node->UpdateLinkPointData(); } else if (entity->IsDerivedFrom(EditorDropNode::DefaultData)) { EditorDropNode* node; node = Cast_Object(EditorDropNode*,entity); node->dropZone->SetNewLocalToParent(new_local_to_world); node->dropZone->SyncMatrices(true); EditorDropZonePoint* point; LinearMatrix4D matrix = LinearMatrix4D::Identity; ChainIteratorOf iterator(&node->pointChain); Point3D newPoint; while((point = iterator.ReadAndNext()) != NULL) { newPoint = new_local_to_world; newPoint -= point->offset; newPoint.y = theApp.displayWindow->GetMapPointVertical(newPoint.x,newPoint.z); matrix.BuildTranslation(newPoint); point->SetNewLocalToParent(matrix); point->SyncMatrices(true); point->UpdateLinkPointData(); } node->UpdatePoints(); } else if (entity->IsDerivedFrom(EditorDropZonePoint::DefaultData)) { EditorDropZonePoint* node; node = Cast_Object(EditorDropZonePoint*,entity); node->SetNewLocalToParent(new_local_to_world); node->SyncMatrices(true); node->UpdateLinkPointData(); Point3D newPoint; newPoint = new_local_to_world; node->offset = node->dropNode->GetLocalToWorld(); node->offset -= newPoint; node->dropNode->UpdatePoints(); } /* else if (entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData)) { EditorObjectiveMarker* node; node = Cast_Object(EditorObjectiveMarker*,entity); node->objective->SetNewLocalToParent(new_local_to_world); node->objective->SyncMatrices(true); } */ else if (entity->IsDerivedFrom(EditorPointLight::DefaultData) || entity->IsDerivedFrom(EditorSpotLight::DefaultData)) { EditorLight* light; light = Cast_Object(EditorLight*,entity); light->SetLightToWorldMatrix(light->GetLocalToWorld()); } else if (entity->IsDerivedFrom(EditorCameraShip::DefaultData)) { EditorCameraShip* node; node = Cast_Object(EditorCameraShip*,entity); node->cameraShip->SetNewLocalToParent(new_local_to_world); node->cameraShip->SyncMatrices(true); } } cursorPosition = translation; } theApp.MakeObjectsTileBased(); }