SceneEditor3D.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. //
  2. // Copyright (c) 2014-2016 THUNDERBEAST GAMES LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include <Atomic/IO/Log.h>
  23. #include <Atomic/Core/CoreEvents.h>
  24. #include <Atomic/Scene/SceneEvents.h>
  25. #include <Atomic/Scene/Scene.h>
  26. #include <Atomic/Graphics/Camera.h>
  27. #include <Atomic/Graphics/DebugRenderer.h>
  28. #include <Atomic/Graphics/Viewport.h>
  29. #include <Atomic/Graphics/Octree.h>
  30. #include <Atomic/IO/FileSystem.h>
  31. #include <Atomic/Resource/ResourceCache.h>
  32. #include <Atomic/Physics/PhysicsWorld.h>
  33. #include <Atomic/Input/Input.h>
  34. #include <Atomic/UI/UI.h>
  35. #include <ToolCore/ToolSystem.h>
  36. #include <ToolCore/Project/Project.h>
  37. #include <ToolCore/Project/ProjectEvents.h>
  38. #include <ToolCore/Project/ProjectUserPrefs.h>
  39. #include <ToolCore/Assets/AssetDatabase.h>
  40. #include <ToolCore/Assets/Asset.h>
  41. #include <ToolCore/Assets/SceneImporter.h>
  42. #include "../../EditorMode/AEEditorEvents.h"
  43. #include "SceneEditor3D.h"
  44. #include "SceneSelection.h"
  45. #include "SceneEditHistory.h"
  46. #include "SceneEditor3DEvents.h"
  47. using namespace ToolCore;
  48. namespace AtomicEditor
  49. {
  50. Vector<WeakPtr<SceneEditor3D>> SceneEditor3D::sceneEditors_;
  51. SceneEditor3D::SceneEditor3D(Context* context, const String &fullpath, UITabContainer *container) :
  52. ResourceEditor(context, fullpath, container),
  53. cubemapRenderCount_(0)
  54. {
  55. // store a local reference to user project prefs
  56. ToolSystem* tsystem = GetSubsystem<ToolSystem>();
  57. Project* project = tsystem->GetProject();
  58. userPrefs_ = project->GetUserPrefs();
  59. ResourceCache* cache = GetSubsystem<ResourceCache>();
  60. scene_ = new Scene(context_);
  61. SharedPtr<File> xmlFile = cache->GetFile(fullpath);
  62. if (GetExtension(fullpath) == ".scene")
  63. scene_->LoadXML(*xmlFile);
  64. else
  65. scene_->Load(*xmlFile);
  66. scene_->SetUpdateEnabled(false);
  67. selection_ = new SceneSelection(context, this);
  68. sceneView_ = new SceneView3D(context_, this);
  69. editHistory_ = new SceneEditHistory(context, this);
  70. AssetDatabase* assetDB = GetSubsystem<AssetDatabase>();
  71. Asset* sceneAsset = assetDB->GetAssetByPath(fullpath);
  72. if (sceneAsset)
  73. {
  74. sceneImporter_ = static_cast<SceneImporter*>(sceneAsset->GetImporter());
  75. sceneView_->GetCameraNode()->SetWorldPosition(sceneImporter_->GetSceneCamPosition());
  76. sceneView_->SetPitch(sceneImporter_->GetSceneCamRotation().PitchAngle());
  77. sceneView_->SetYaw(sceneImporter_->GetSceneCamRotation().YawAngle());
  78. }
  79. else
  80. {
  81. LOGERRORF("SceneEditor3D::SceneEditor3D - Unable to get scene asset");
  82. }
  83. sceneView_->SetGravity(UI_GRAVITY_ALL);
  84. rootContentWidget_->AddChild(sceneView_);
  85. gizmo3D_ = new Gizmo3D(context_);
  86. gizmo3D_->SetView(sceneView_);
  87. gizmo3D_->Show();
  88. UpdateGizmoSnapSettings();
  89. SubscribeToEvent(E_UPDATE, HANDLER(SceneEditor3D, HandleUpdate));
  90. SubscribeToEvent(E_GIZMOEDITMODECHANGED, HANDLER(SceneEditor3D, HandleGizmoEditModeChanged));
  91. SubscribeToEvent(E_GIZMOAXISMODECHANGED, HANDLER(SceneEditor3D, HandleGizmoAxisModeChanged));
  92. // FIXME: Set the size at the end of setup, so all children are updated accordingly
  93. // future size changes will be handled automatically
  94. IntRect rect = container_->GetContentRoot()->GetRect();
  95. rootContentWidget_->SetSize(rect.Width(), rect.Height());
  96. SubscribeToEvent(E_PROJECTUSERPREFSAVED, HANDLER(SceneEditor3D, HandleUserPrefSaved));
  97. SubscribeToEvent(scene_, E_SCENEEDITNODECREATED, HANDLER(SceneEditor3D, HandleSceneEditNodeCreated));
  98. SubscribeToEvent(E_EDITORPLAYERSTARTED, HANDLER(SceneEditor3D, HandlePlayStarted));
  99. SubscribeToEvent(E_EDITORPLAYERSTOPPED, HANDLER(SceneEditor3D, HandlePlayStopped));
  100. SubscribeToEvent(scene_, E_SCENEEDITSCENEMODIFIED, HANDLER(SceneEditor3D, HandleSceneEditSceneModified));
  101. SubscribeToEvent(scene_, E_CUBEMAPRENDERBEGIN, HANDLER(SceneEditor3D, HandleCubemapRenderBegin));
  102. SubscribeToEvent(scene_, E_CUBEMAPRENDEREND, HANDLER(SceneEditor3D, HandleCubemapRenderEnd));
  103. RegisterSceneEditor();
  104. }
  105. SceneEditor3D::~SceneEditor3D()
  106. {
  107. }
  108. bool SceneEditor3D::OnEvent(const TBWidgetEvent &ev)
  109. {
  110. if (ev.type == EVENT_TYPE_KEY_UP)
  111. {
  112. if (ev.special_key == TB_KEY_DELETE || ev.special_key == TB_KEY_BACKSPACE)
  113. {
  114. selection_->Delete();
  115. }
  116. }
  117. if (ev.type == EVENT_TYPE_SHORTCUT)
  118. {
  119. if (ev.ref_id == TBIDC("copy"))
  120. {
  121. selection_->Copy();
  122. return true;
  123. }
  124. else if (ev.ref_id == TBIDC("paste"))
  125. {
  126. selection_->Paste();
  127. return true;
  128. }
  129. else if (ev.ref_id == TBIDC("close"))
  130. {
  131. RequestClose();
  132. return true;
  133. }
  134. else if (ev.ref_id == TBIDC("undo"))
  135. {
  136. Undo();
  137. return true;
  138. }
  139. else if (ev.ref_id == TBIDC("redo"))
  140. {
  141. Redo();
  142. return true;
  143. }
  144. }
  145. if (ev.type == EVENT_TYPE_CLICK)
  146. {
  147. SetFocus();
  148. if (ev.target)
  149. {
  150. if (ev.target->GetID() == TBIDC("3d_translate"))
  151. {
  152. gizmo3D_->SetEditMode(EDIT_MOVE);
  153. return false;
  154. }
  155. else if (ev.target->GetID() == TBIDC("3d_rotate"))
  156. {
  157. gizmo3D_->SetEditMode(EDIT_ROTATE);
  158. return false;
  159. }
  160. else if (ev.target->GetID() == TBIDC("3d_scale"))
  161. {
  162. gizmo3D_->SetEditMode(EDIT_SCALE);
  163. return false;
  164. }
  165. }
  166. }
  167. return false;
  168. }
  169. void SceneEditor3D::SetFocus()
  170. {
  171. sceneView_->SetFocus();
  172. }
  173. void SceneEditor3D::HandleUpdate(StringHash eventType, VariantMap& eventData)
  174. {
  175. if (!cubemapRenderCount_)
  176. gizmo3D_->Update();
  177. }
  178. void SceneEditor3D::HandlePlayStarted(StringHash eventType, VariantMap& eventData)
  179. {
  180. }
  181. void SceneEditor3D::HandlePlayStopped(StringHash eventType, VariantMap& eventData)
  182. {
  183. }
  184. void SceneEditor3D::HandleGizmoEditModeChanged(StringHash eventType, VariantMap& eventData)
  185. {
  186. EditMode mode = (EditMode) (eventData[GizmoEditModeChanged::P_MODE].GetInt());
  187. gizmo3D_->SetEditMode(mode);
  188. }
  189. void SceneEditor3D::HandleGizmoAxisModeChanged(StringHash eventType, VariantMap& eventData)
  190. {
  191. AxisMode mode = (AxisMode) (eventData[GizmoAxisModeChanged::P_MODE].GetInt());
  192. gizmo3D_->SetAxisMode(mode);
  193. }
  194. void SceneEditor3D::Close(bool navigateToAvailableResource)
  195. {
  196. VariantMap data;
  197. data["Scene"] = scene_;
  198. SendEvent("EditorSceneClosed", data);
  199. if (sceneImporter_.NotNull())
  200. {
  201. sceneImporter_->SetSceneCamPosition(sceneView_->GetCameraNode()->GetWorldPosition());
  202. sceneImporter_->SetSceneCamRotation(sceneView_->GetCameraNode()->GetWorldRotation());
  203. sceneImporter_->GetAsset()->Save();
  204. sceneImporter_ = nullptr;
  205. }
  206. ResourceEditor::Close(navigateToAvailableResource);
  207. }
  208. bool SceneEditor3D::Save()
  209. {
  210. File file(context_);
  211. if (file.Open(fullpath_, FILE_WRITE))
  212. {
  213. scene_->SaveXML(file);
  214. file.Close();
  215. }
  216. SetModified(false);
  217. return true;
  218. }
  219. void SceneEditor3D::RegisterNode(Node * node)
  220. {
  221. VariantMap eventData;
  222. eventData[SceneEditAddRemoveNodes::P_END] = false;
  223. scene_->SendEvent(E_SCENEEDITADDREMOVENODES, eventData);
  224. // generate scene edit event
  225. VariantMap nodeAddedEventData;
  226. nodeAddedEventData[SceneEditNodeAdded::P_NODE] = node;
  227. nodeAddedEventData[SceneEditNodeAdded::P_PARENT] = node->GetParent();
  228. nodeAddedEventData[SceneEditNodeAdded::P_SCENE] = scene_;
  229. scene_->SendEvent(E_SCENEEDITNODEADDED, nodeAddedEventData);
  230. eventData[SceneEditAddRemoveNodes::P_END] = true;
  231. scene_->SendEvent(E_SCENEEDITADDREMOVENODES, eventData);
  232. }
  233. void SceneEditor3D::RegisterNodes(const PODVector<Node*>& nodes)
  234. {
  235. VariantMap eventData;
  236. eventData[SceneEditAddRemoveNodes::P_END] = false;
  237. scene_->SendEvent(E_SCENEEDITADDREMOVENODES, eventData);
  238. // generate scene edit event
  239. for (unsigned i = 0; i < nodes.Size(); i++)
  240. {
  241. Node* node = nodes[i];
  242. VariantMap nodeAddedEventData;
  243. nodeAddedEventData[SceneEditNodeAdded::P_NODE] = node;
  244. nodeAddedEventData[SceneEditNodeAdded::P_PARENT] = node->GetParent();
  245. nodeAddedEventData[SceneEditNodeAdded::P_SCENE] = scene_;
  246. scene_->SendEvent(E_SCENEEDITNODEADDED, nodeAddedEventData);
  247. }
  248. eventData[SceneEditAddRemoveNodes::P_END] = true;
  249. scene_->SendEvent(E_SCENEEDITADDREMOVENODES, eventData);
  250. }
  251. void SceneEditor3D::Undo()
  252. {
  253. editHistory_->Undo();
  254. }
  255. void SceneEditor3D::Redo()
  256. {
  257. editHistory_->Redo();
  258. }
  259. void SceneEditor3D::Cut()
  260. {
  261. selection_->Cut();
  262. }
  263. void SceneEditor3D::Copy()
  264. {
  265. selection_->Copy();
  266. }
  267. void SceneEditor3D::Paste()
  268. {
  269. selection_->Paste();
  270. }
  271. void SceneEditor3D::HandleSceneEditNodeCreated(StringHash eventType, VariantMap& eventData)
  272. {
  273. PODVector<Node*> nodes;
  274. nodes.Push(static_cast<Node*>(eventData[SceneEditNodeCreated::P_NODE].GetPtr()));
  275. RegisterNodes(nodes);
  276. selection_->AddNode(nodes[0], true);
  277. }
  278. void SceneEditor3D::HandleSceneEditSceneModified(StringHash eventType, VariantMap& eventData)
  279. {
  280. SetModified(true);
  281. }
  282. void SceneEditor3D::HandleUserPrefSaved(StringHash eventType, VariantMap& eventData)
  283. {
  284. UpdateGizmoSnapSettings();
  285. }
  286. void SceneEditor3D::UpdateGizmoSnapSettings()
  287. {
  288. gizmo3D_->SetSnapTranslationX(userPrefs_->GetSnapTranslationX());
  289. gizmo3D_->SetSnapTranslationY(userPrefs_->GetSnapTranslationY());
  290. gizmo3D_->SetSnapTranslationZ(userPrefs_->GetSnapTranslationZ());
  291. gizmo3D_->SetSnapRotation(userPrefs_->GetSnapRotation());
  292. gizmo3D_->SetSnapScale(userPrefs_->GetSnapScale());
  293. }
  294. void SceneEditor3D::InvokeShortcut(const String& shortcut)
  295. {
  296. if (shortcut == "frameselected")
  297. {
  298. sceneView_->FrameSelection();
  299. return;
  300. }
  301. ResourceEditor::InvokeShortcut(shortcut);
  302. }
  303. void SceneEditor3D::ReparentNode(Node* node, Node* newParent)
  304. {
  305. // can't parent to self
  306. if (node == newParent)
  307. return;
  308. // already parented
  309. Node* oldParent = node->GetParent();
  310. if (oldParent == newParent)
  311. return;
  312. // must be in same scene
  313. if (node->GetScene() != newParent->GetScene())
  314. {
  315. return;
  316. }
  317. // check if dropping on child of ourselves
  318. Node* parent = newParent;
  319. while (parent)
  320. {
  321. if (parent == node)
  322. {
  323. return;
  324. }
  325. parent = parent->GetParent();
  326. }
  327. selection_->AddNode(node, true);
  328. Matrix3x4 transform = node->GetWorldTransform();
  329. newParent->AddChild(node);
  330. node->SetWorldTransform(transform.Translation(), transform.Rotation(), transform.Scale());
  331. scene_->SendEvent(E_SCENEEDITEND);
  332. PODVector<Node*> nodes;
  333. node->GetChildren(nodes, true);
  334. nodes.Insert(0, node);
  335. VariantMap evData;
  336. for (unsigned i = 0; i < nodes.Size(); i++)
  337. {
  338. evData[SceneEditNodeReparent::P_NODE] = nodes[i];
  339. evData[SceneEditNodeReparent::P_ADDED] = false;
  340. scene_->SendEvent(E_SCENEEDITNODEREPARENT, evData);
  341. }
  342. evData[SceneEditNodeReparent::P_NODE] = node;
  343. evData[SceneEditNodeReparent::P_ADDED] = true;
  344. scene_->SendEvent(E_SCENEEDITNODEREPARENT, evData);
  345. selection_->AddNode(node, true);
  346. }
  347. void SceneEditor3D::RegisterSceneEditor()
  348. {
  349. // prune released scene editors
  350. for (Vector<WeakPtr<SceneEditor3D> >::Iterator i = sceneEditors_.Begin(); i != sceneEditors_.End();)
  351. {
  352. if (*i)
  353. {
  354. ++i;
  355. }
  356. else
  357. {
  358. i = sceneEditors_.Erase(i);
  359. }
  360. }
  361. sceneEditors_.Push(WeakPtr<SceneEditor3D>(this));
  362. }
  363. SceneEditor3D* SceneEditor3D::GetSceneEditor(Scene* scene)
  364. {
  365. for (Vector<WeakPtr<SceneEditor3D> >::Iterator i = sceneEditors_.Begin(); i != sceneEditors_.End();)
  366. {
  367. if (*i && scene == (*i)->GetScene())
  368. return *i;
  369. i++;
  370. }
  371. return NULL;
  372. }
  373. void SceneEditor3D::HandleCubemapRenderBegin(StringHash eventType, VariantMap& eventData)
  374. {
  375. cubemapRenderCount_++;
  376. if (cubemapRenderCount_ == 1)
  377. {
  378. // first time
  379. sceneView_->GetDebugRenderer()->SetEnabled(false);
  380. gizmo3D_->Hide();
  381. }
  382. }
  383. void SceneEditor3D::HandleCubemapRenderEnd(StringHash eventType, VariantMap& eventData)
  384. {
  385. cubemapRenderCount_--;
  386. if (cubemapRenderCount_ == 0)
  387. {
  388. // last one
  389. sceneView_->GetDebugRenderer()->SetEnabled(true);
  390. gizmo3D_->Show();
  391. }
  392. }
  393. }