Ticket #678: atlas_selection-01182012.patch
File atlas_selection-01182012.patch, 48.8 KB (added by , 12 years ago) |
---|
-
binaries/data/mods/public/simulation/templates/other/bridge_hele.xml
20 20 <Obstruction> 21 21 <Static width="59" depth="15"/> 22 22 </Obstruction> 23 <Selectable disable=""/> 23 <Selectable> 24 <EditorOnly/> 25 </Selectable> 24 26 <Vision> 25 27 <Range>72</Range> 26 28 <RetainInFog>true</RetainInFog> -
binaries/data/mods/public/simulation/templates/other/bridge_wooden.xml
20 20 <Obstruction> 21 21 <Static width="59" depth="15"/> 22 22 </Obstruction> 23 <Selectable disable=""/> 23 <Selectable> 24 <EditorOnly/> 25 </Selectable> 24 26 <Vision> 25 27 <Range>72</Range> 26 28 <RetainInFog>true</RetainInFog> -
binaries/data/mods/public/simulation/templates/special/territory_block.xml
21 21 <Floating>false</Floating> 22 22 <TurnRate>6.0</TurnRate> 23 23 </Position> 24 <Selectable/> 24 <Selectable> 25 <EditorOnly disable=""/> 26 </Selectable> 25 27 <TerritoryInfluence> 26 28 <OverrideCost>64</OverrideCost> 27 29 <Root>false</Root> -
binaries/data/mods/public/simulation/templates/special/territory_pull.xml
21 21 <Floating>false</Floating> 22 22 <TurnRate>6.0</TurnRate> 23 23 </Position> 24 <Selectable/> 24 <Selectable> 25 <EditorOnly disable=""/> 26 </Selectable> 25 27 <TerritoryInfluence> 26 28 <OverrideCost>0</OverrideCost> 27 29 <Root>false</Root> -
binaries/data/mods/public/simulation/templates/template_entity_quasi.xml
8 8 <Floating>false</Floating> 9 9 <TurnRate>6.0</TurnRate> 10 10 </Position> 11 <Selectable> 12 <EditorOnly/> 13 </Selectable> 11 14 </Entity> -
binaries/data/mods/public/simulation/templates/template_gaia_flora_bush_berry.xml
16 16 <Amount>120</Amount> 17 17 <Type>food.fruit</Type> 18 18 </ResourceSupply> 19 <Selectable/> 19 <Selectable> 20 <EditorOnly disable=""/> 21 </Selectable> 20 22 </Entity> -
binaries/data/mods/public/simulation/templates/template_gaia_flora_tree.xml
15 15 <Amount>200</Amount> 16 16 <Type>wood.tree</Type> 17 17 </ResourceSupply> 18 <Selectable/> 18 <Selectable> 19 <EditorOnly disable=""/> 20 </Selectable> 19 21 <VisualActor> 20 22 <SelectionShape> 21 23 <Footprint/> -
binaries/data/mods/public/simulation/templates/template_gaia_geo_mineral.xml
15 15 <Amount>1000</Amount> 16 16 <Type>metal.ore</Type> 17 17 </ResourceSupply> 18 <Selectable/> 18 <Selectable> 19 <EditorOnly disable=""/> 20 </Selectable> 19 21 </Entity> -
binaries/data/mods/public/simulation/templates/template_gaia_geo_rock.xml
15 15 <Amount>1000</Amount> 16 16 <Type>stone.rock</Type> 17 17 </ResourceSupply> 18 <Selectable/> 18 <Selectable> 19 <EditorOnly disable=""/> 20 </Selectable> 19 21 </Entity> -
binaries/data/mods/public/simulation/templates/template_gaia_ruins.xml
22 22 <Amount>500</Amount> 23 23 <Type>stone.rock</Type> 24 24 </ResourceSupply> 25 <Selectable/> 25 <Selectable> 26 <EditorOnly disable=""/> 27 </Selectable> 26 28 </Entity> -
binaries/data/mods/public/simulation/templates/template_gaia_treasure.xml
22 22 <Amount>300</Amount> 23 23 <Type>treasure.metal</Type> 24 24 </ResourceSupply> 25 <Selectable/> 25 <Selectable> 26 <EditorOnly disable=""/> 27 </Selectable> 26 28 </Entity> -
source/graphics/UnitManager.cpp
85 85 m_Units.clear(); 86 86 } 87 87 88 89 88 /////////////////////////////////////////////////////////////////////////////// 90 // PickUnit: iterate through units testing given ray against bounds of each91 // unit; return the closest unit, or null if everything missed92 CUnit* CUnitManager::PickUnit(const CVector3D& origin, const CVector3D& dir) const93 {94 // closest object found so far95 CUnit* hit = 0;96 // closest approach offset (easier to pick small stuff in forests than standard ScEd style selection)97 float minrel = FLT_MAX;98 99 for (size_t i=0; i<m_Units.size(); i++) {100 CUnit* unit = m_Units[i];101 float tmin, tmax;102 103 const CBoundingBoxOriented& selectionBox = unit->GetModel().GetSelectionBox();104 if (selectionBox.RayIntersect(origin, dir, tmin, tmax))105 {106 // Point of closest approach107 // TODO: this next bit is virtually identical to Selection::PickEntitiesAtPoint; might be useful to factor it out and108 // reuse it109 CVector3D delta = selectionBox.m_Center - origin;110 float distance = delta.Dot(dir);111 CVector3D closest = origin + dir * distance;112 CVector3D offset = selectionBox.m_Center - closest;113 114 float rel = offset.Length();115 if (rel < minrel) {116 hit = unit;117 minrel = rel;118 }119 }120 }121 return hit;122 }123 124 ///////////////////////////////////////////////////////////////////////////////125 89 // CreateUnit: create a new unit and add it to the world 126 90 CUnit* CUnitManager::CreateUnit(const CStrW& actorName, uint32_t seed, const std::set<CStr8>& selections) 127 91 { -
source/graphics/UnitManager.h
55 55 // return the units 56 56 const std::vector<CUnit*>& GetUnits() const { return m_Units; } 57 57 58 // iterate through units testing given ray against bounds of each unit;59 // return the closest unit, or null if everything missed60 CUnit* PickUnit(const CVector3D& origin, const CVector3D& dir) const;61 62 58 void SetObjectManager(CObjectManager& objectManager) { m_ObjectManager = &objectManager; } 63 59 64 60 private: -
source/gui/scripting/ScriptFunctions.cpp
128 128 129 129 std::vector<entity_id_t> PickEntitiesAtPoint(void* UNUSED(cbdata), int x, int y) 130 130 { 131 return EntitySelection::PickEntitiesAtPoint(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x, y, g_Game->GetPlayerID() );131 return EntitySelection::PickEntitiesAtPoint(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x, y, g_Game->GetPlayerID(), false); 132 132 } 133 133 134 134 std::vector<entity_id_t> PickFriendlyEntitiesInRect(void* UNUSED(cbdata), int x0, int y0, int x1, int y1, int player) 135 135 { 136 return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, player );136 return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, player, false); 137 137 } 138 138 139 139 std::vector<entity_id_t> PickSimilarFriendlyEntities(void* UNUSED(cbdata), std::string templateName, bool includeOffScreen, bool matchRank) 140 140 { 141 return EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, g_Game->GetPlayerID(), includeOffScreen, matchRank );141 return EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, g_Game->GetPlayerID(), includeOffScreen, matchRank, false); 142 142 } 143 143 144 144 CFixedVector3D GetTerrainAtPoint(void* UNUSED(cbdata), int x, int y) -
source/ps/GameSetup/GameSetup.cpp
97 97 #include "ps/GameSetup/CmdLineArgs.h" 98 98 #include "ps/GameSetup/HWDetect.h" 99 99 100 #include "tools/atlas/GameInterface/GameLoop.h" 101 #include "tools/atlas/GameInterface/View.h" 102 103 100 104 #if !(OS_WIN || OS_MACOSX) // assume all other platforms use X11 for wxWidgets 101 105 #define MUST_INIT_X11 1 102 106 #include <X11/Xlib.h> … … 248 252 249 253 ogl_WarnIfError(); 250 254 255 if (g_GameLoop && g_GameLoop->view) 256 g_GameLoop->view->DrawOverlays(); 257 258 ogl_WarnIfError(); 259 251 260 // Text: 252 261 253 262 // Use the GL_ALPHA texture as the alpha channel with a flat colouring -
source/simulation2/components/CCmpSelectable.cpp
1 /* Copyright (C) 201 0Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 48 48 SOverlayLine m_Overlay; 49 49 SOverlayLine* m_DebugBoundingBoxOverlay; 50 50 SOverlayLine* m_DebugSelectionBoxOverlay; 51 bool m_EditorOnly; 51 52 52 53 CCmpSelectable() 53 54 : m_DebugBoundingBoxOverlay(NULL), m_DebugSelectionBoxOverlay(NULL) … … 66 67 return 67 68 "<a:help>Allows this entity to be selected by the player.</a:help>" 68 69 "<a:example/>" 69 "<empty/>"; 70 "<optional>" 71 "<element name='EditorOnly' a:help='If this element is present, the entity is only selectable in Atlas'>" 72 "<empty/>" 73 "</element>" 74 "</optional>"; 70 75 } 71 76 72 virtual void Init(const CParamNode& UNUSED(paramNode))77 virtual void Init(const CParamNode& paramNode) 73 78 { 79 m_EditorOnly = paramNode.GetChild("EditorOnly").IsOk(); 74 80 } 75 81 76 82 virtual void Deinit() … … 112 118 } 113 119 } 114 120 121 virtual bool IsEditorOnly() 122 { 123 return m_EditorOnly; 124 } 125 115 126 virtual void SetSelectionHighlight(CColor color) 116 127 { 117 128 m_Overlay.m_Color = color; -
source/simulation2/components/CCmpTemplateManager.cpp
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 369 369 // Copy the actor template 370 370 out = m_TemplateFileData[templateName]; 371 371 372 // Initialise the actor's name 372 // Initialise the actor's name and make it an Atlas selectable entity. 373 373 std::string name = utf8_from_wstring(CParamNode::EscapeXMLString(wstring_from_utf8(actorName))); 374 std::string xml = "<Entity><VisualActor><Actor>" + name + "</Actor></VisualActor>< /Entity>";374 std::string xml = "<Entity><VisualActor><Actor>" + name + "</Actor></VisualActor><Selectable><EditorOnly/></Selectable></Entity>"; 375 375 CParamNode::LoadXMLString(out, xml.c_str()); 376 376 } 377 377 -
source/simulation2/components/ICmpSelectable.h
1 /* Copyright (C) 201 0Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 26 26 { 27 27 public: 28 28 /** 29 * Returns true if the entity is only selectable in Atlas editor, e.g. a decorative visual actor. 30 */ 31 virtual bool IsEditorOnly() = 0; 32 33 /** 29 34 * Set the color of the selection highlight (typically a circle/square 30 35 * around the unit). Set a = 0 to disable. 31 36 */ -
source/simulation2/helpers/Selection.cpp
1 /* Copyright (C) 201 0Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 28 28 #include "simulation2/components/ICmpSelectable.h" 29 29 #include "simulation2/components/ICmpVisual.h" 30 30 31 std::vector<entity_id_t> EntitySelection::PickEntitiesAtPoint(CSimulation2& simulation, const CCamera& camera, int screenX, int screenY, int player )31 std::vector<entity_id_t> EntitySelection::PickEntitiesAtPoint(CSimulation2& simulation, const CCamera& camera, int screenX, int screenY, int player, bool editorSelectable) 32 32 { 33 33 CVector3D origin, dir; 34 34 camera.BuildCameraRay(screenX, screenY, origin, dir); … … 43 43 { 44 44 entity_id_t ent = it->first; 45 45 46 // Check if this entity is only selectable in Atlas 47 if (static_cast<ICmpSelectable*>(it->second)->IsEditorOnly() && !editorSelectable) 48 continue; 49 46 50 // Ignore entities hidden by LOS (or otherwise hidden, e.g. when not IsInWorld) 47 51 if (cmpRangeManager->GetLosVisibility(ent, player) == ICmpRangeManager::VIS_HIDDEN) 48 52 continue; … … 51 55 if (cmpVisual.null()) 52 56 continue; 53 57 58 CVector3D center; 59 float tmin, tmax; 60 54 61 CBoundingBoxOriented selectionBox = cmpVisual->GetSelectionBox(); 55 62 if (selectionBox.IsEmpty()) 56 continue; 63 { 64 if (!editorSelectable) 65 continue; 57 66 58 float tmin, tmax; 59 if (!selectionBox.RayIntersect(origin, dir, tmin, tmax)) 60 continue; 67 // Fall back to using old AABB selection method for decals 68 // see: http://trac.wildfiregames.com/ticket/1032 69 CBoundingBoxAligned aABBox = cmpVisual->GetBounds(); 70 if (aABBox.IsEmpty()) 71 continue; 61 72 73 if (!aABBox.RayIntersect(origin, dir, tmin, tmax)) 74 continue; 75 76 aABBox.GetCentre(center); 77 } 78 else 79 { 80 if (!selectionBox.RayIntersect(origin, dir, tmin, tmax)) 81 continue; 82 83 center = selectionBox.m_Center; 84 } 85 62 86 // Find the perpendicular distance from the object's centre to the picker ray 63 87 64 CVector3D closest = origin + dir * (selectionBox.m_Center - origin).Dot(dir); 65 float dist2 = (closest - selectionBox.m_Center).LengthSquared(); 88 float dist2; 89 CVector3D closest = origin + dir * (center - origin).Dot(dir); 90 dist2 = (closest - center).LengthSquared(); 66 91 67 92 hits.push_back(std::make_pair(dist2, ent)); 68 93 } … … 78 103 return hitEnts; 79 104 } 80 105 81 std::vector<entity_id_t> EntitySelection::PickEntitiesInRect(CSimulation2& simulation, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, int owner )106 std::vector<entity_id_t> EntitySelection::PickEntitiesInRect(CSimulation2& simulation, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, int owner, bool editorSelectable) 82 107 { 83 108 // Make sure sx0 <= sx1, and sy0 <= sy1 84 109 if (sx0 > sx1) … … 96 121 { 97 122 entity_id_t ent = it->first; 98 123 124 // Check if this entity is only selectable in Atlas 125 if (static_cast<ICmpSelectable*>(it->second)->IsEditorOnly() && !editorSelectable) 126 continue; 127 99 128 // Ignore entities hidden by LOS (or otherwise hidden, e.g. when not IsInWorld) 100 129 if (cmpRangeManager->GetLosVisibility(ent, owner) == ICmpRangeManager::VIS_HIDDEN) 101 130 continue; 102 131 103 132 // Ignore entities not owned by 'owner' 104 133 CmpPtr<ICmpOwnership> cmpOwnership(simulation.GetSimContext(), ent); 105 if ( cmpOwnership.null() || cmpOwnership->GetOwner() != owner)134 if (owner != -1 && (cmpOwnership.null() || cmpOwnership->GetOwner() != owner)) 106 135 continue; 107 136 108 137 // Find the current interpolated model position. … … 132 161 return hitEnts; 133 162 } 134 163 135 std::vector<entity_id_t> EntitySelection::PickSimilarEntities(CSimulation2& simulation, const CCamera& camera, const std::string& templateName, int owner, bool includeOffScreen, bool matchRank )164 std::vector<entity_id_t> EntitySelection::PickSimilarEntities(CSimulation2& simulation, const CCamera& camera, const std::string& templateName, int owner, bool includeOffScreen, bool matchRank, bool editorSelectable) 136 165 { 137 166 CmpPtr<ICmpTemplateManager> cmpTemplateManager(simulation, SYSTEM_ENTITY); 138 167 CmpPtr<ICmpRangeManager> cmpRangeManager(simulation, SYSTEM_ENTITY); … … 144 173 { 145 174 entity_id_t ent = it->first; 146 175 176 // Check if this entity is only selectable in Atlas 177 if (static_cast<ICmpSelectable*>(it->second)->IsEditorOnly() && !editorSelectable) 178 continue; 179 147 180 if (matchRank) 148 181 { 149 182 // Exact template name matching … … 158 191 159 192 // Ignore entities not owned by 'owner' 160 193 CmpPtr<ICmpOwnership> cmpOwnership(simulation.GetSimContext(), ent); 161 if ( cmpOwnership.null() || cmpOwnership->GetOwner() != owner)194 if (owner != -1 && (cmpOwnership.null() || cmpOwnership->GetOwner() != owner)) 162 195 continue; 163 196 164 197 // Ignore off screen entities -
source/simulation2/helpers/Selection.h
1 /* Copyright (C) 201 0Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 37 37 * Finds all selectable entities under the given screen coordinates. 38 38 * Returns list ordered by closeness of picking, closest first. 39 39 * Restricted to entities in the LOS of @p player, but with any owner. 40 * If @p editorSelectable then all entities with the IID_Selectable interface 41 * will be selected, else only selectable entities without the EditorOnly flag set. 40 42 */ 41 std::vector<entity_id_t> PickEntitiesAtPoint(CSimulation2& simulation, const CCamera& camera, int screenX, int screenY, int player );43 std::vector<entity_id_t> PickEntitiesAtPoint(CSimulation2& simulation, const CCamera& camera, int screenX, int screenY, int player, bool editorSelectable); 42 44 43 45 /** 44 46 * Finds all selectable entities within the given screen coordinate rectangle, 45 47 * that belong to player @p owner. 48 * If @p owner is -1 then ownership is ignored. 49 * If @p editorSelectable then all entities with the IID_Selectable interface 50 * will be selected, else only selectable entities without the EditorOnly flag set. 46 51 * Returns unordered list. 47 52 */ 48 std::vector<entity_id_t> PickEntitiesInRect(CSimulation2& simulation, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, int owner );53 std::vector<entity_id_t> PickEntitiesInRect(CSimulation2& simulation, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, int owner, bool editorSelectable); 49 54 50 55 /** 51 56 * Finds all entities with the given entity template name, that belong to player @p owner. 57 * If @p owner is -1 then ownership is ignored. 52 58 * If @p includeOffScreen then all entities visible in the world will be selected, 53 59 * else only entities visible on the screen will be selected. 54 60 * If @p matchRank then only entities that exactly match @p templateName will be selected, 55 61 * else entities with matching SelectionGroupName will be selected. 62 * If @p editorSelectable then all entities with the IID_Selectable interface 63 * will be selected, else only selectable entities without the EditorOnly flag set. 56 64 */ 57 std::vector<entity_id_t> PickSimilarEntities(CSimulation2& simulation, const CCamera& camera, const std::string& templateName, int owner, bool includeOffScreen, bool matchRank );65 std::vector<entity_id_t> PickSimilarEntities(CSimulation2& simulation, const CCamera& camera, const std::string& templateName, int owner, bool includeOffScreen, bool matchRank, bool editorSelectable); 58 66 59 67 } // namespace 60 68 -
source/tools/atlas/AtlasUI/CustomControls/Canvas/Canvas.cpp
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 96 96 } 97 97 98 98 BEGIN_EVENT_TABLE(Canvas, wxGLCanvas) 99 EVT_SIZE (Canvas::OnResize) 100 EVT_LEFT_DOWN (Canvas::OnMouse) 101 EVT_LEFT_UP (Canvas::OnMouse) 102 EVT_RIGHT_DOWN (Canvas::OnMouse) 103 EVT_RIGHT_UP (Canvas::OnMouse) 104 EVT_MIDDLE_DOWN(Canvas::OnMouse) 105 EVT_MIDDLE_UP (Canvas::OnMouse) 106 EVT_MOUSEWHEEL (Canvas::OnMouse) 107 EVT_MOTION (Canvas::OnMouse) 99 EVT_SIZE (Canvas::OnResize) 100 EVT_LEFT_DCLICK (Canvas::OnMouse) 101 EVT_LEFT_DOWN (Canvas::OnMouse) 102 EVT_LEFT_UP (Canvas::OnMouse) 103 EVT_RIGHT_DCLICK (Canvas::OnMouse) 104 EVT_RIGHT_DOWN (Canvas::OnMouse) 105 EVT_RIGHT_UP (Canvas::OnMouse) 106 EVT_MIDDLE_DCLICK (Canvas::OnMouse) 107 EVT_MIDDLE_DOWN (Canvas::OnMouse) 108 EVT_MIDDLE_UP (Canvas::OnMouse) 109 EVT_MOUSEWHEEL (Canvas::OnMouse) 110 EVT_MOTION (Canvas::OnMouse) 108 111 EVT_MOUSE_CAPTURE_LOST(Canvas::OnMouseCaptureLost) 109 112 END_EVENT_TABLE() -
source/tools/atlas/AtlasUI/ScenarioEditor/Tools/TransformObject.cpp
1 /* Copyright (C) 20 09Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 31 31 DECLARE_DYNAMIC_CLASS(TransformObject); 32 32 33 33 int m_dx, m_dy; 34 AtlasMessage::ObjectID m_lastSelected; 35 wxPoint m_startPoint; 34 36 37 // TODO: If we don't plan to change hotkeys, just replace with evt.ShiftDown(), etc. 38 static const wxKeyCode SELECTION_ADD_HOTKEY = WXK_SHIFT; 39 static const wxKeyCode SELECTION_REMOVE_HOTKEY = WXK_CONTROL; // COMMAND on Macs 40 static const wxKeyCode SELECTION_ACTORS_HOTKEY = WXK_ALT; 41 35 42 public: 36 TransformObject() 43 TransformObject() : m_lastSelected(0) 37 44 { 38 45 SetState(&Waiting); 39 46 } … … 52 59 { 53 60 bool OnMouse(TransformObject* obj, wxMouseEvent& evt) 54 61 { 55 if (evt.LeftD own())62 if (evt.LeftDClick() && AtlasMessage::ObjectIDIsValid(obj->m_lastSelected)) 56 63 { 64 SET_STATE(SelectSimilar); 65 return true; 66 } 67 else if (evt.LeftDown()) 68 { 69 bool selectionAdd = wxGetKeyState(SELECTION_ADD_HOTKEY); 70 bool selectionRemove = wxGetKeyState(SELECTION_REMOVE_HOTKEY); 71 bool selectionActors = wxGetKeyState(SELECTION_ACTORS_HOTKEY); 72 57 73 // New selection - never merge with movements of other objects 58 74 ScenarioEditor::GetCommandProc().FinaliseLastCommand(); 59 75 60 76 // Select the object clicked on: 61 77 62 AtlasMessage::qPickObject qry(Position(evt.GetPosition()) );78 AtlasMessage::qPickObject qry(Position(evt.GetPosition()), selectionActors); 63 79 qry.Post(); 64 80 65 // TODO: handle multiple selections66 g_SelectedObjects.clear();67 68 81 // Check they actually clicked on a valid object 69 82 if (AtlasMessage::ObjectIDIsValid(qry.id)) 70 83 { 71 g_SelectedObjects.push_back(qry.id); 72 // Remember the screen-space offset of the mouse from the 73 // object's centre, so we can add that back when moving it 74 // (instead of just moving the object's centre to directly 75 // beneath the mouse) 76 obj->m_dx = qry.offsetx; 77 obj->m_dy = qry.offsety; 78 SET_STATE(Dragging); 84 std::vector<AtlasMessage::ObjectID>::iterator it = std::find(g_SelectedObjects.begin(), g_SelectedObjects.end(), qry.id); 85 bool objectIsSelected = (it != g_SelectedObjects.end()); 86 87 if (selectionRemove) 88 { 89 // Remove from selection 90 if (objectIsSelected) 91 g_SelectedObjects.erase(it); 92 } 93 else if (!objectIsSelected) 94 { 95 // Add to selection 96 if (!selectionAdd) 97 g_SelectedObjects.clear(); 98 99 g_SelectedObjects.push_back(qry.id); 100 } 101 102 obj->m_lastSelected = qry.id; 103 104 // If we're selecting the whole group 105 if (!selectionAdd && !selectionRemove && !g_SelectedObjects.empty()) 106 { 107 // Remember the screen-space offset of the mouse from the 108 // object's centre, so we can add that back when moving it 109 // (instead of just moving the object's centre to directly 110 // beneath the mouse) 111 obj->m_dx = qry.offsetx; 112 obj->m_dy = qry.offsety; 113 SET_STATE(Dragging); 114 } 115 116 g_SelectedObjects.NotifyObservers(); 117 POST_MESSAGE(SetSelectionPreview, (g_SelectedObjects)); 79 118 } 80 g_SelectedObjects.NotifyObservers(); 81 POST_MESSAGE(SetSelectionPreview, (g_SelectedObjects)); 119 else 120 { 121 // Bandboxing 122 obj->m_lastSelected = 0; 123 obj->m_startPoint = evt.GetPosition(); 124 SET_STATE(Bandboxing); 125 } 126 82 127 return true; 83 128 } 84 else if ( (evt.Dragging() && evt.RightIsDown()) || evt.RightDown())129 else if (g_SelectedObjects.size() == 1 && ((evt.Dragging() && evt.RightIsDown()) || evt.RightDown())) 85 130 { 131 // TODO: Rotation of selections with multiple objects? 132 86 133 // Dragging with right mouse button -> rotate objects to look 87 134 // at mouse 88 135 Position pos (evt.GetPosition()); … … 91 138 92 139 return true; 93 140 } 141 else if (evt.Moving()) 142 { 143 // Prevent certain events from reaching game UI in this mode 144 // to prevent selection ring confusion 145 return true; 146 } 94 147 else 95 148 return false; 96 149 } … … 132 185 else if (evt.Dragging()) 133 186 { 134 187 Position pos (evt.GetPosition() + wxPoint(obj->m_dx, obj->m_dy)); 135 for (size_t i = 0; i < g_SelectedObjects.size(); ++i) 136 POST_COMMAND(MoveObject, (g_SelectedObjects[i], pos));188 189 POST_COMMAND(MoveObjects, (g_SelectedObjects, obj->m_lastSelected, pos)); 137 190 return true; 138 191 } 139 192 else 140 193 return false; 141 194 } 195 196 bool OnKey(TransformObject* obj, wxKeyEvent& evt, KeyEventType type) 197 { 198 if (type == KEY_UP && evt.GetKeyCode() == WXK_ESCAPE) 199 { 200 // Cancel move action 201 ScenarioEditor::GetCommandProc().FinaliseLastCommand(); 202 ScenarioEditor::GetCommandProc().Undo(); 203 SET_STATE(Waiting); 204 205 return true; 206 } 207 else 208 return false; 209 } 142 210 } 143 211 Dragging; 212 213 struct sBandboxing : public State 214 { 215 bool OnMouse(TransformObject* obj, wxMouseEvent& evt) 216 { 217 if (evt.LeftIsDown() && evt.Dragging()) 218 { 219 // Update bandbox overlay 220 POST_MESSAGE(SetBandbox, (true, obj->m_startPoint.x, obj->m_startPoint.y, evt.GetPosition().x, evt.GetPosition().y)); 221 return true; 222 } 223 else if (evt.LeftUp()) 224 { 225 bool selectionAdd = wxGetKeyState(SELECTION_ADD_HOTKEY); 226 bool selectionRemove = wxGetKeyState(SELECTION_REMOVE_HOTKEY); 227 bool selectionActors = wxGetKeyState(SELECTION_ACTORS_HOTKEY); 228 229 // Now we have both corners of the box, pick objects 230 AtlasMessage::qPickObjectsInRect qry(Position(obj->m_startPoint), Position(evt.GetPosition()), selectionActors); 231 qry.Post(); 232 233 std::vector<AtlasMessage::ObjectID> ids = *qry.ids; 234 235 if (!selectionAdd && !selectionRemove) 236 { 237 // Just copy new selections (clears list if no selections) 238 g_SelectedObjects = ids; 239 } 240 else 241 { 242 for (size_t i = 0; i < ids.size(); ++i) 243 { 244 std::vector<AtlasMessage::ObjectID>::iterator it = std::find(g_SelectedObjects.begin(), g_SelectedObjects.end(), ids[i]); 245 bool objectIsSelected = (it != g_SelectedObjects.end()); 246 if (selectionRemove) 247 { 248 // Remove from selection 249 if (objectIsSelected) 250 g_SelectedObjects.erase(it); 251 } 252 else if (!objectIsSelected) 253 { 254 // Add to selection 255 g_SelectedObjects.push_back(ids[i]); 256 } 257 } 258 } 259 260 POST_MESSAGE(SetBandbox, (false, 0, 0, 0, 0)); 261 262 g_SelectedObjects.NotifyObservers(); 263 POST_MESSAGE(SetSelectionPreview, (g_SelectedObjects)); 264 265 SET_STATE(Waiting); 266 return true; 267 } 268 else 269 return false; 270 } 271 272 bool OnKey(TransformObject* obj, wxKeyEvent& evt, KeyEventType type) 273 { 274 if (type == KEY_UP && evt.GetKeyCode() == WXK_ESCAPE) 275 { 276 // Clear bandbox and return to waiting state 277 POST_MESSAGE(SetBandbox, (false, 0, 0, 0, 0)); 278 SET_STATE(Waiting); 279 return true; 280 } 281 else 282 return false; 283 } 284 } 285 Bandboxing; 286 287 struct sSelectSimilar : public State 288 { 289 bool OnMouse(TransformObject* obj, wxMouseEvent& evt) 290 { 291 if (evt.LeftUp()) 292 { 293 bool selectionAdd = wxGetKeyState(SELECTION_ADD_HOTKEY); 294 bool selectionRemove = wxGetKeyState(SELECTION_REMOVE_HOTKEY); 295 296 // Select similar objects 297 AtlasMessage::qPickSimilarObjects qry(obj->m_lastSelected); 298 qry.Post(); 299 300 std::vector<AtlasMessage::ObjectID> ids = *qry.ids; 301 302 if (!selectionAdd && !selectionRemove) 303 { 304 // Just copy new selections (clears list if no selections) 305 g_SelectedObjects = ids; 306 } 307 else 308 { 309 for (size_t i = 0; i < ids.size(); ++i) 310 { 311 std::vector<AtlasMessage::ObjectID>::iterator it = std::find(g_SelectedObjects.begin(), g_SelectedObjects.end(), ids[i]); 312 bool objectIsSelected = (it != g_SelectedObjects.end()); 313 if (selectionRemove) 314 { 315 // Remove from selection 316 if (objectIsSelected) 317 g_SelectedObjects.erase(it); 318 } 319 else if (!objectIsSelected) 320 { 321 // Add to selection 322 g_SelectedObjects.push_back(ids[i]); 323 } 324 } 325 } 326 327 g_SelectedObjects.NotifyObservers(); 328 POST_MESSAGE(SetSelectionPreview, (g_SelectedObjects)); 329 330 SET_STATE(Waiting); 331 return true; 332 } 333 else 334 return false; 335 } 336 } 337 SelectSimilar; 144 338 }; 145 339 146 340 IMPLEMENT_DYNAMIC_CLASS(TransformObject, StateDrivenTool<TransformObject>); -
source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 18 18 #include "precompiled.h" 19 19 20 20 #include <cfloat> 21 #include <map> 21 22 22 23 #include "MessageHandler.h" 23 24 #include "../CommandProc.h" … … 31 32 #include "graphics/ObjectManager.h" 32 33 #include "graphics/Terrain.h" 33 34 #include "graphics/Unit.h" 34 #include "graphics/UnitManager.h"35 35 #include "lib/ogl.h" 36 36 #include "maths/MathUtil.h" 37 37 #include "maths/Matrix3D.h" 38 38 #include "ps/CLogger.h" 39 39 #include "ps/Game.h" 40 #include "ps/Overlay.h" 40 41 #include "ps/World.h" 41 42 #include "renderer/Renderer.h" 42 43 #include "renderer/WaterManager.h" 43 44 #include "simulation2/Simulation2.h" 44 45 #include "simulation2/components/ICmpOwnership.h" 45 46 #include "simulation2/components/ICmpPosition.h" 47 #include "simulation2/components/ICmpPlayer.h" 48 #include "simulation2/components/ICmpPlayerManager.h" 46 49 #include "simulation2/components/ICmpSelectable.h" 47 50 #include "simulation2/components/ICmpTemplateManager.h" 51 #include "simulation2/helpers/Selection.h" 48 52 49 53 50 54 namespace AtlasMessage { … … 56 60 return wcscmp(a.name.c_str(), b.name.c_str()) < 0; 57 61 } 58 62 59 bool IsFloating(const CUnit* unit)60 {61 if (! unit)62 return false;63 64 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), unit->GetID());65 if (cmpPosition.null())66 return false;67 return cmpPosition->IsFloating();68 }69 70 CUnitManager& GetUnitManager()71 {72 return g_Game->GetWorld()->GetUnitManager();73 }74 63 } 75 64 76 65 QUERYHANDLER(GetObjectsList) … … 111 100 112 101 MESSAGEHANDLER(SetSelectionPreview) 113 102 { 103 CSimulation2& sim = *g_Game->GetSimulation2(); 104 105 // Cache player colours for performance 106 typedef std::map<player_id_t, CColor> PlayerColourMap; 107 PlayerColourMap playerColours; 108 109 CmpPtr<ICmpPlayerManager> cmpPlayerManager(sim, SYSTEM_ENTITY); 110 111 // Clear old selection rings 114 112 for (size_t i = 0; i < g_Selection.size(); ++i) 115 113 { 116 CmpPtr<ICmpSelectable> cmpSelectable( *g_Game->GetSimulation2(), g_Selection[i]);114 CmpPtr<ICmpSelectable> cmpSelectable(sim, g_Selection[i]); 117 115 if (!cmpSelectable.null()) 118 116 cmpSelectable->SetSelectionHighlight(CColor(1, 1, 1, 0)); 119 117 } 120 118 121 119 g_Selection = *msg->ids; 122 120 121 // Set new selection rings 123 122 for (size_t i = 0; i < g_Selection.size(); ++i) 124 123 { 125 CmpPtr<ICmpSelectable> cmpSelectable(*g_Game->GetSimulation2(), g_Selection[i]); 126 if (!cmpSelectable.null()) 127 cmpSelectable->SetSelectionHighlight(CColor(1, 1, 1, 1)); 124 entity_id_t ent = g_Selection[i]; 125 CmpPtr<ICmpSelectable> cmpSelectable(sim, ent); 126 if (cmpSelectable.null()) 127 continue; 128 129 // Default to white for ownerless entities 130 CColor colour(1.0f, 1.0f, 1.0f, 1.0f); 131 132 CmpPtr<ICmpOwnership> cmpOwnership(sim, ent); 133 if (!cmpOwnership.null() && !cmpPlayerManager.null()) 134 { 135 player_id_t owner = cmpOwnership->GetOwner(); 136 if (playerColours.find(owner) != playerColours.end()) 137 { 138 colour = playerColours[owner]; 139 } 140 else 141 { 142 // Add colour to cache 143 entity_id_t playerEnt = cmpPlayerManager->GetPlayerByID(owner); 144 CmpPtr<ICmpPlayer> cmpPlayer(sim, playerEnt); 145 if (!cmpPlayer.null()) 146 { 147 colour = cmpPlayer->GetColour(); 148 playerColours[owner] = colour; 149 } 150 } 151 } 152 153 cmpSelectable->SetSelectionHighlight(colour); 128 154 } 129 155 } 130 156 … … 401 427 float x, y; 402 428 msg->pos->GetScreenSpace(x, y); 403 429 404 CVector3D rayorigin, raydir;405 g_Game->GetView()->GetCamera()->BuildCameraRay((int)x, (int)y, rayorigin, raydir);430 // Normally this function would be called with a player ID to check LOS, but in Atlas the entire map is revealed, so we just pass -1 431 std::vector<AtlasMessage::ObjectID> ents = EntitySelection::PickEntitiesAtPoint(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x, y, -1, msg->selectActors); 406 432 407 CUnit* target = GetUnitManager().PickUnit(rayorigin, raydir); 433 // Multiple entities may have been picked, but they are sorted by distance, 434 // so only take the first one 435 if (!ents.empty()) 436 { 437 msg->id = ents[0]; 408 438 409 if (target) 410 msg->id = target->GetID(); 411 else 412 msg->id = INVALID_ENTITY; 413 414 if (target) 415 { 416 // Get screen coordinates of the point on the ground underneath the 417 // object's model-centre, so that callers know the offset to use when 418 // working out the screen coordinates to move the object to. 439 // Calculate offset of object from original mouse click position 440 // so it gets moved by that offset 419 441 420 CVector3D centre = target->GetModel().GetTransform().GetTranslation(); 442 CmpPtr<ICmpPosition> cmpPos(*g_Game->GetSimulation2(), (entity_id_t)ents[0]); 443 if (cmpPos.null() || !cmpPos->IsInWorld()) 444 { 445 // error 446 msg->offsetx = msg->offsety = 0; 447 } 448 else 449 { 450 CFixedVector3D fixed = cmpPos->GetPosition(); 451 CVector3D centre = CVector3D(fixed.X.ToFloat(), fixed.Y.ToFloat(), fixed.Z.ToFloat()); 421 452 422 centre.Y = g_Game->GetWorld()->GetTerrain()->GetExactGroundLevel(centre.X, centre.Z); 423 if (IsFloating(target)) 424 centre.Y = std::max(centre.Y, g_Renderer.GetWaterManager()->m_WaterHeight); 453 float cx, cy; 454 g_Game->GetView()->GetCamera()->GetScreenCoordinates(centre, cx, cy); 425 455 426 float cx, cy; 427 g_Game->GetView()->GetCamera()->GetScreenCoordinates(centre, cx, cy); 428 429 msg->offsetx = (int)(cx - x); 430 msg->offsety = (int)(cy - y); 456 msg->offsetx = (int)(cx - x); 457 msg->offsety = (int)(cy - y); 458 } 431 459 } 432 460 else 433 461 { 462 // No entity picked 463 msg->id = INVALID_ENTITY; 434 464 msg->offsetx = msg->offsety = 0; 435 465 } 436 466 } 437 467 468 QUERYHANDLER(PickObjectsInRect) 469 { 470 float x0, y0, x1, y1; 471 msg->start->GetScreenSpace(x0, y0); 472 msg->end->GetScreenSpace(x1, y1); 438 473 439 BEGIN_COMMAND(MoveObject) 474 msg->ids = EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, -1, msg->selectActors); 475 } 476 477 QUERYHANDLER(PickSimilarObjects) 440 478 { 441 CVector3D m_PosOld, m_PosNew; 479 CmpPtr<ICmpTemplateManager> cmpTemplateManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY); 480 ENSURE(!cmpTemplateManager.null()); 481 std::string templateName = cmpTemplateManager->GetCurrentTemplateName((entity_id_t)msg->id); 442 482 483 msg->ids = EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, -1, false, true, true); 484 } 485 486 BEGIN_COMMAND(MoveObjects) 487 { 488 // Mapping from object to position 489 typedef std::map<AtlasMessage::ObjectID, CVector3D> ObjectPositionMap; 490 ObjectPositionMap m_PosOld, m_PosNew; 491 443 492 void Do() 444 493 { 445 CmpPtr<ICmpPosition> cmpPos(*g_Game->GetSimulation2(), (entity_id_t)msg->id); 446 if (cmpPos.null()) 494 std::vector<ObjectID> ids = *msg->ids; 495 496 // All selected objects move relative to a pivot object, 497 // so get its position and whether it's floating 498 CVector3D pivotPos(0, 0, 0); 499 bool pivotFloating = false; 500 501 CmpPtr<ICmpPosition> cmpPos(*g_Game->GetSimulation2(), (entity_id_t)msg->pivot); 502 if (!cmpPos.null() && cmpPos->IsInWorld()) 447 503 { 448 // error 449 m_PosOld = m_PosNew = CVector3D(0, 0, 0); 504 pivotFloating = cmpPos->IsFloating(); 505 CFixedVector3D pivotFixed = cmpPos->GetPosition(); 506 pivotPos = CVector3D(pivotFixed.X.ToFloat(), pivotFixed.Y.ToFloat(), pivotFixed.Z.ToFloat()); 450 507 } 451 else 508 509 // Calculate directional vector of movement for pivot object, 510 // we apply the same movement to all objects 511 CVector3D targetPos = GetUnitPos(msg->pos, pivotFloating); 512 CVector3D dir = targetPos - pivotPos; 513 514 for (size_t i = 0; i < ids.size(); ++i) 452 515 { 453 m_PosNew = GetUnitPos(msg->pos, cmpPos->IsFloating()); 516 entity_id_t id = (entity_id_t)ids[i]; 517 CmpPtr<ICmpPosition> cmpPos(*g_Game->GetSimulation2(), id); 518 if (cmpPos.null() || !cmpPos->IsInWorld()) 519 { 520 // error 521 m_PosOld[id] = m_PosNew[id] = CVector3D(0, 0, 0); 522 } 523 else 524 { 525 // Calculate this object's position 526 CFixedVector3D posFixed = cmpPos->GetPosition(); 527 CVector3D pos = CVector3D(posFixed.X.ToFloat(), posFixed.Y.ToFloat(), posFixed.Z.ToFloat()); 454 528 455 CFixedVector3D pos = cmpPos->GetPosition(); 456 m_PosOld = CVector3D(pos.X.ToFloat(), pos.Y.ToFloat(), pos.Z.ToFloat()); 529 m_PosNew[id] = pos + dir; 530 m_PosOld[id] = pos; 531 } 457 532 } 458 533 459 534 SetPos(m_PosNew); 460 535 } 461 536 462 void SetPos( CVector3D& pos)537 void SetPos(ObjectPositionMap& map) 463 538 { 464 CmpPtr<ICmpPosition> cmpPos(*g_Game->GetSimulation2(), (entity_id_t)msg->id); 465 if (cmpPos.null()) 466 return; 539 ObjectPositionMap::iterator it; 540 for (it = map.begin(); it != map.end(); ++it) 541 { 542 CmpPtr<ICmpPosition> cmpPos(*g_Game->GetSimulation2(), (entity_id_t)it->first); 543 if (cmpPos.null()) 544 return; 467 545 468 cmpPos->JumpTo(entity_pos_t::FromFloat(pos.X), entity_pos_t::FromFloat(pos.Z)); 546 // Set 2D position, ignoring height 547 CVector3D pos = it->second; 548 cmpPos->JumpTo(entity_pos_t::FromFloat(pos.X), entity_pos_t::FromFloat(pos.Z)); 549 } 469 550 } 470 551 471 552 void Redo() … … 478 559 SetPos(m_PosOld); 479 560 } 480 561 481 void MergeIntoPrevious(cMoveObject * prev)562 void MergeIntoPrevious(cMoveObjects* prev) 482 563 { 483 // TODO: do something valid if prev unit != this unit484 ENSURE( prev->msg->id == msg->id);564 // TODO: do something valid if prev selection != this selection 565 ENSURE(*(prev->msg->ids) == *(msg->ids)); 485 566 prev->m_PosNew = m_PosNew; 486 567 } 487 568 }; 488 END_COMMAND(MoveObject )569 END_COMMAND(MoveObjects) 489 570 490 571 491 572 BEGIN_COMMAND(RotateObject) … … 645 726 msg->ids = ids; 646 727 } 647 728 729 MESSAGEHANDLER(SetBandbox) 730 { 731 View::GetView_Game()->SetBandbox(msg->show, (float)msg->sx0, (float)msg->sy0, (float)msg->sx1, (float)msg->sy1); 648 732 } 733 734 } -
source/tools/atlas/GameInterface/Messages.h
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 484 484 ////////////////////////////////////////////////////////////////////////// 485 485 486 486 QUERY(PickObject, 487 ((Position, pos)) 488 , 489 ((ObjectID, id)) 490 ((int, offsetx)) // offset of object centre from input position 491 ((int, offsety)) // 492 ); 487 ((Position, pos)) 488 ((bool, selectActors)) 489 , 490 ((ObjectID, id)) 491 ((int, offsetx)) // offset of object centre from input position 492 ((int, offsety)) // 493 ); 493 494 494 COMMAND(MoveObject, MERGE, 495 QUERY(PickObjectsInRect, 496 ((Position, start)) 497 ((Position, end)) 498 ((bool, selectActors)) 499 , 500 ((std::vector<ObjectID>, ids)) 501 ); 502 503 QUERY(PickSimilarObjects, 495 504 ((ObjectID, id)) 505 , 506 ((std::vector<ObjectID>, ids)) 507 ); 508 509 COMMAND(MoveObjects, MERGE, 510 ((std::vector<ObjectID>, ids)) 511 ((ObjectID, pivot)) 496 512 ((Position, pos)) 497 513 ); 498 514 … … 512 528 ); 513 529 514 530 QUERY(GetObjectSettings, 515 516 517 518 519 531 ((int, view)) // eRenderView 532 ((ObjectID, id)) 533 , 534 ((sObjectSettings, settings)) 535 ); 520 536 521 537 COMMAND(SetObjectSettings, NOMERGE, 522 538 ((int, view)) // eRenderView … … 530 546 ((std::vector<ObjectID>, ids)) 531 547 ); 532 548 549 MESSAGE(SetBandbox, 550 ((bool, show)) 551 ((int, sx0)) 552 ((int, sy0)) 553 ((int, sx1)) 554 ((int, sy1)) 555 ); 556 533 557 ////////////////////////////////////////////////////////////////////////// 534 558 535 559 QUERY(GetCinemaPaths, -
source/tools/atlas/GameInterface/Shareable.h
1 /* Copyright (C) 20 09Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 118 118 // Shareable containers must have shareable contents - but it's easy to forget 119 119 // to declare them, so make sure the errors are almost readable, like: 120 120 // "use of undefined type 'REQUIRE_TYPE_TO_BE_SHAREABLE_FAILURE<T,__formal> 121 // with [ T=AtlasMessage::sTerrain GroupPreview, __formal=false ]"121 // with [ T=AtlasMessage::sTerrainTexturePreview, __formal=false ]" 122 122 // 123 123 // (Implementation based on boost/static_assert) 124 124 template <typename T, bool> struct REQUIRE_TYPE_TO_BE_SHAREABLE_FAILURE; -
source/tools/atlas/GameInterface/SharedTypes.h
1 /* Copyright (C) 20 09Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 84 84 85 85 86 86 typedef size_t ObjectID; 87 inline bool ObjectIDIsValid(ObjectID id) { return (id != ~(size_t)0); }87 inline bool ObjectIDIsValid(ObjectID id) { return (id != 0); } 88 88 89 89 90 90 struct sCinemaSplineNode -
source/tools/atlas/GameInterface/View.cpp
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 166 166 } 167 167 168 168 ViewGame::ViewGame() 169 : m_SpeedMultiplier(0.f)169 : m_SpeedMultiplier(0.f) 170 170 { 171 171 ENSURE(g_Game); 172 172 } … … 262 262 Atlas_GLSwapBuffers((void*)g_GameLoop->glCanvas); 263 263 } 264 264 265 void ViewGame::DrawOverlays() 266 { 267 glDisable(GL_TEXTURE_2D); 268 glClear(GL_DEPTH_BUFFER_BIT); 269 270 // Invert y coordinates to match GUI 271 glPushMatrix(); 272 glLoadIdentity(); 273 glTranslatef(0.0f, (GLfloat)g_yres, 0.0f); 274 glScalef(1.0f, -1.f, 1.0f); 275 276 if (m_BandboxArray.size() > 0) 277 { 278 // Enable line antialiasing 279 glEnable(GL_LINE_SMOOTH); 280 281 glEnableClientState(GL_COLOR_ARRAY); 282 glEnableClientState(GL_VERTEX_ARRAY); 283 284 // Render bandbox as array of lines 285 glVertexPointer(2, GL_FLOAT, sizeof(SBandboxVertex), &m_BandboxArray[0].x); 286 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(SBandboxVertex), &m_BandboxArray[0].r); 287 288 glDrawArrays(GL_LINES, 0, m_BandboxArray.size()); 289 290 glDisableClientState(GL_VERTEX_ARRAY); 291 glDisableClientState(GL_COLOR_ARRAY); 292 293 glDisable(GL_LINE_SMOOTH); 294 } 295 296 glPopMatrix(); 297 glEnable(GL_TEXTURE_2D); 298 } 299 265 300 void ViewGame::SetParam(const std::wstring& name, bool value) 266 301 { 267 302 if (name == L"priorities") … … 353 388 } 354 389 } 355 390 391 void ViewGame::SetBandbox(bool visible, float x0, float y0, float x1, float y1) 392 { 393 m_BandboxArray.clear(); 394 395 if (visible) 396 { 397 // Make sure corners are arranged in correct order 398 if (x0 > x1) 399 std::swap(x0, x1); 400 if (y0 > y1) 401 std::swap(y0, y1); 402 403 // Bandbox is draw as lines comprising two rectangles, the inner 404 // is white and the outer is black. They are offset by 0.5 pixels 405 // so the antialiasing looks better. 406 SBandboxVertex vert[] = { 407 SBandboxVertex(x0, y0, 0, 0, 0, 255), SBandboxVertex(x1, y0, 0, 0, 0, 255), SBandboxVertex(x1, y1, 0, 0, 0, 255), SBandboxVertex(x0, y1, 0, 0, 0, 255), 408 SBandboxVertex(x0+0.5f, y0+0.5f, 255, 255, 255, 255), SBandboxVertex(x1-0.5f, y0+0.5f, 255, 255, 255, 255), SBandboxVertex(x1-0.5f, y1-0.5f, 255, 255, 255, 255), SBandboxVertex(x0+0.5f, y1-0.5f, 255, 255, 255, 255) 409 }; 410 411 for (size_t i = 0; i < 4; ++i) 412 { 413 m_BandboxArray.push_back(vert[i]); 414 m_BandboxArray.push_back(vert[(i+1)%4]); 415 } 416 for (size_t i = 0; i < 4; ++i) 417 { 418 m_BandboxArray.push_back(vert[i+4]); 419 m_BandboxArray.push_back(vert[(i+1)%4+4]); 420 } 421 } 422 } 423 356 424 ////////////////////////////////////////////////////////////////////////// 357 425 358 426 ViewNone* view_None = NULL; -
source/tools/atlas/GameInterface/View.h
1 /* Copyright (C) 201 0Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 37 37 virtual ~View(); 38 38 virtual void Update(float UNUSED(frameLength)) { }; 39 39 virtual void Render() { }; 40 virtual void DrawOverlays() { }; 40 41 virtual CCamera& GetCamera() = 0; 41 42 virtual CSimulation2* GetSimulation2() { return NULL; } 42 43 virtual entity_id_t GetEntityId(AtlasMessage::ObjectID obj) { return (entity_id_t)obj; } … … 76 77 virtual ~ViewGame(); 77 78 virtual void Update(float frameLength); 78 79 virtual void Render(); 80 virtual void DrawOverlays(); 79 81 virtual CCamera& GetCamera(); 80 82 virtual CSimulation2* GetSimulation2(); 81 83 virtual bool WantsHighFramerate(); … … 87 89 void SaveState(const std::wstring& label); 88 90 void RestoreState(const std::wstring& label); 89 91 std::wstring DumpState(bool binary); 92 void SetBandbox(bool visible, float x0, float y0, float x1, float y1); 90 93 91 94 private: 92 95 float m_SpeedMultiplier; 93 96 std::map<std::wstring, SimState*> m_SavedStates; 94 97 std::string m_DisplayPassability; 98 99 typedef struct SBandboxVertex 100 { 101 SBandboxVertex(float x, float y, u8 r, u8 g, u8 b, u8 a) : x(x), y(y), r(r), g(g), b(b), a(a) {} 102 u8 r, g, b, a; 103 float x, y; 104 } SBandboxVertex; 105 106 std::vector<SBandboxVertex> m_BandboxArray; 95 107 }; 96 108 97 109 class ActorViewer;