!B (CE-20826) (Sandbox) Use highlight instead of aux to draw selection preview
[CRYENGINE.git] / Code / Sandbox / Plugins / CryDesigner / Objects / DesignerObject.cpp
blob04cbf792d037aa39b61d6564b5c0845b2799bf82
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
4 #include "DesignerObject.h"
6 #include "Util/Converter.h"
7 #include "Util/Display.h"
8 #include "Util/PrimitiveShape.h"
9 #include "Util/Undo.h"
10 #include "DesignerEditor.h"
12 #include <IAIManager.h>
13 #include <Material/MaterialManager.h>
14 #include <GameEngine.h>
16 #include <Controls/DynamicPopupMenu.h>
17 #include <Objects/ObjectLoader.h>
18 #include <Objects/InspectorWidgetCreator.h>
19 #include <Preferences/ViewportPreferences.h>
20 #include <Serialization/Decorators/EditorActionButton.h>
22 #include <CryCore/Base64.h>
24 namespace Designer
26 IMPLEMENT_DYNCREATE(DesignerObject, CBaseObject)
28 REGISTER_CLASS_DESC(BoxObjectClassDesc)
29 REGISTER_CLASS_DESC(SphereObjectClassDesc)
30 REGISTER_CLASS_DESC(ConeObjectClassDesc)
31 REGISTER_CLASS_DESC(CylinderObjectClassDesc)
33 REGISTER_CLASS_DESC(DesignerObjectClassDesc)
35 REGISTER_CLASS_DESC(SolidObjectClassDesc)
37 DesignerObject::DesignerObject()
39 m_pCompiler = new ModelCompiler(eCompiler_General);
40 m_nBrushUniqFileId = s_nGlobalBrushDesignerFileId;
41 m_EngineFlags.m_pObj = this;
42 ++s_nGlobalBrushDesignerFileId;
43 m_bSupportsBoxHighlight = false;
46 void GeneratePrimitiveShape(PolygonList& polygonList, string primitiveType)
48 PrimitiveShape bp;
50 BrushVec3 min(0.0, 0.0, 0.0);
51 BrushVec3 max(1.0, 1.0, 1.0);
53 if (primitiveType == "DesignerSphere")
55 min -= BrushVec3(0.0, 0.0, 0.5);
56 max -= BrushVec3(0.0, 0.0, 0.5);
58 bp.CreateSphere(
59 min,
60 max,
61 16,
62 &polygonList);
64 else if (primitiveType == "DesignerBox")
66 bp.CreateBox(
67 min,
68 max,
69 &polygonList);
71 else if (primitiveType == "DesignerCylinder")
73 bp.CreateCylinder(
74 min,
75 max,
76 16,
77 &polygonList);
79 else if (primitiveType == "DesignerCone")
81 bp.CreateCone(
82 min,
83 max,
84 16,
85 &polygonList);
89 bool DesignerObject::Init(CBaseObject* prev, const string& file)
91 SetMaterial(BrushDesignerDefaultMaterial);
93 if (prev)
95 DesignerObject* pGeomObj = static_cast<DesignerObject*>(prev);
97 Model* pModel = pGeomObj->GetModel();
98 if (pModel)
100 Model* pClonedModel = new Model(*pModel);
101 SetModel(pClonedModel);
104 ModelCompiler* pFrontBrush = pGeomObj->GetCompiler();
105 if (pFrontBrush)
107 ModelCompiler* pClonedCompilier = new ModelCompiler(*pFrontBrush);
108 SetCompiler(pClonedCompilier);
109 ApplyPostProcess(GetMainContext(), ePostProcess_Mesh);
113 bool ret = CBaseObject::Init(prev, file);
115 // Finished initialization, now generate geometry for this object type.
116 // Do this only for new objects, or we risk duplicating lots of cubes
117 if (ret && !prev && (!file.IsEmpty()))
119 PolygonList polygonList;
121 polygonList.clear();
123 GeneratePrimitiveShape(polygonList, file);
125 MODEL_SHELF_RECONSTRUCTOR(GetModel());
127 GetModel()->SetShelf(eShelf_Base);
128 GetModel()->Clear();
129 for (int i = 0, iPolygonCount(polygonList.size()); i < iPolygonCount; ++i)
131 polygonList[i]->SetSubMatID(0);
132 GetModel()->AddUnionPolygon(polygonList[i]);
135 ApplyPostProcess(GetMainContext(), ePostProcess_Mesh);
138 return ret;
141 void DesignerObject::Display(CObjectRenderHelper& objRenderHelper)
143 SDisplayContext& dc = objRenderHelper.GetDisplayContextRef();
145 if (dc.display2D)
147 dc.PushMatrix(GetWorldTM());
148 Display::DisplayModel(dc, GetModel(), NULL, eShelf_Any, 2, IsSelected() ? kSelectedColor : ColorB(0, 0, 0));
149 dc.PopMatrix();
151 else
153 DrawDefault(dc);
154 DrawOpenPolygons(dc);
158 const ColorB& DesignerObject::GetSelectionPreviewHighlightColor()
160 return gViewportSelectionPreferences.solidBrushGeometryColor;
163 void DesignerObject::DrawOpenPolygons(SDisplayContext& dc)
165 dc.PushMatrix(GetWorldTM());
167 ColorB oldColor = dc.GetColor();
168 int oldLineWidth = dc.GetLineWidth();
170 dc.SetColor(ColorB(0, 0, 2));
171 dc.SetLineWidth(2);
172 for (int i = 0, iPolygonCount(GetModel()->GetPolygonCount()); i < iPolygonCount; ++i)
174 PolygonPtr pPolygon = GetModel()->GetPolygon(i);
175 if (!pPolygon->IsOpen())
176 continue;
177 Display::DisplayPolygon(dc, pPolygon);
179 dc.SetColor(oldColor);
180 dc.SetLineWidth(oldLineWidth);
182 dc.PopMatrix();
185 void DesignerObject::GetBoundBox(AABB& box)
187 if (GetModel())
189 for (int i = eShelf_Base; i < cShelfMax; ++i)
191 if (!GetModel()->IsEmpty(static_cast<ShelfID>(i)))
193 box.SetTransformedAABB(GetWorldTM(), GetModel()->GetBoundBox(static_cast<ShelfID>(i)));
194 return;
199 BrushVec3 vWorldPos = GetWorldTM().GetTranslation();
200 box = AABB(vWorldPos, vWorldPos);
203 void DesignerObject::GetLocalBounds(AABB& box)
205 if (GetModel())
207 box = GetModel()->GetBoundBox(eShelf_Base);
209 else
211 box = AABB(Vec3(0, 0, 0), Vec3(0, 0, 0));
215 bool DesignerObject::HitTest(HitContext& hc)
217 BrushRay ray;
218 GetLocalViewRay(GetWorldTM(), hc.view, hc.point2d, ray);
220 if (Designer::HitTest(ray, GetMainContext(), hc))
222 hc.object = this;
223 return true;
225 else if (GetModel())
227 BrushMatrix34 invMat = GetWorldTM().GetInverted();
228 for (int i = 0, iPolygonCount(GetModel()->GetPolygonCount()); i < iPolygonCount; ++i)
230 PolygonPtr pPolygon = GetModel()->GetPolygon(i);
231 if (!pPolygon->IsOpen())
232 continue;
233 for (int k = 0, iEdgeCount(pPolygon->GetEdgeCount()); k < iEdgeCount; ++k)
235 BrushEdge3D edge = pPolygon->GetEdge(k);
236 if (HitTestEdge(ray, pPolygon->GetPlane().Normal(), edge, hc.view))
238 hc.object = this;
239 return true;
244 return false;
247 IPhysicalEntity* DesignerObject::GetCollisionEntity() const
249 if (GetCompiler() == NULL)
250 return NULL;
251 if (GetCompiler()->GetRenderNode())
252 return GetCompiler()->GetRenderNode()->GetPhysics();
253 return NULL;
256 void DesignerObject::OnContextMenu(CPopupMenuItem* menu)
258 // Add button to enter edit mode
259 menu->Add("Edit", [=]()
261 BeginUndoAndEnsureSelection();
262 GetIEditor()->GetIUndoManager()->Accept("Select Object");
263 GetIEditor()->ExecuteCommand("general.open_pane 'Modeling'");
265 // then show the rest of object properties
266 CBaseObject::OnContextMenu(menu);
269 void DesignerObject::Serialize(CObjectArchive& ar)
271 CBaseObject::Serialize(ar);
273 XmlNodeRef xmlNode = ar.node;
275 if (ar.bLoading)
277 string typeName("Designer");
278 xmlNode->getAttr("Type", typeName);
280 bool bDesignerBinary = false;
281 xmlNode->getAttr("DesignerBinary", bDesignerBinary);
283 XmlNodeRef brushNode = xmlNode->findChild("Brush");
284 if (brushNode)
286 bool bDesignerObject = true;
287 if (!brushNode->haveAttr("DesignerModeFlags"))
288 bDesignerObject = false;
290 if (!GetCompiler())
291 SetCompiler(new ModelCompiler(eCompiler_General));
293 if (!GetModel())
294 SetModel(new Model);
296 if (bDesignerObject)
298 if (ar.bUndo || !bDesignerBinary)
299 GetModel()->Serialize(brushNode, ar.bLoading, ar.bUndo);
301 else
303 bool bConvertSuccess = Converter::ConvertSolidXMLToDesignerObject(brushNode, this);
304 CRY_ASSERT(bConvertSuccess);
308 if (ar.bUndo)
310 if (GetCompiler())
311 GetCompiler()->DeleteAllRenderNodes();
314 if (GetCompiler())
316 uint64 nRenderFlag = ERF_HAS_CASTSHADOWMAPS | ERF_CASTSHADOWMAPS;
317 ar.node->getAttr("RndFlags", nRenderFlag, false);
318 if (nRenderFlag & ERF_CASTSHADOWMAPS)
319 nRenderFlag |= ERF_HAS_CASTSHADOWMAPS;
320 GetCompiler()->SetRenderFlags(nRenderFlag);
321 int nStatObjFlag = 0;
322 if (ar.node->getAttr("StaticObjFlags", nStatObjFlag))
323 GetCompiler()->SetStaticObjFlags(nStatObjFlag);
324 int nViewDistRadio = kDefaultViewDist;
325 ar.node->getAttr("ViewDistRatio", nViewDistRadio);
326 GetCompiler()->SetViewDistRatio(nViewDistRadio);
328 XmlNodeRef meshNode = ar.node->findChild("Mesh");
329 if (meshNode)
331 const char* encodedStr;
332 int nVersion = 0;
333 meshNode->getAttr("Version", nVersion);
334 if (meshNode->getAttr("BinaryData", &encodedStr))
336 int nLength = strlen(encodedStr);
337 if (nLength > 0)
339 int nDestBufferLen = Base64::decodedsize_base64(nLength);
340 std::vector<char> buffer;
341 buffer.resize(nDestBufferLen, 0);
342 Base64::decode_base64(&buffer[0], encodedStr, nLength, false);
343 GetCompiler()->LoadMesh(nVersion, buffer, this, GetModel());
344 bDesignerBinary = true;
349 m_EngineFlags.Set();
352 if (ar.bUndo || !bDesignerBinary)
354 if (GetModel()->GetSubdivisionLevel() > 0)
355 GetModel()->ResetDB(eDBRF_Vertex);
356 ApplyPostProcess(GetMainContext(), ePostProcess_Mesh);
359 else
361 if (GetModel())
363 XmlNodeRef brushNode = xmlNode->newChild("Brush");
364 GetModel()->Serialize(brushNode, ar.bLoading, ar.bUndo);
366 if (m_pCompiler)
368 ar.node->setAttr("RndFlags", ERF_GET_WRITABLE(GetCompiler()->GetRenderFlags()), false);
369 ar.node->setAttr("StaticObjFlags", ERF_GET_WRITABLE(GetCompiler()->GetStaticObjFlags()));
370 ar.node->setAttr("ViewDistRatio", GetCompiler()->GetViewDistRatio());
371 if (!GetCompiler()->IsValid())
372 GetCompiler()->Compile(this, GetModel());
374 if (GetCompiler()->IsValid() && !ar.bUndo)
376 XmlNodeRef meshNode = xmlNode->newChild("Mesh");
377 std::vector<char> meshBuffer;
378 const int nMeshVersion = 2;
379 if (GetCompiler()->SaveMesh(nMeshVersion, meshBuffer, this, GetModel()))
381 unsigned int meshBufferSize = meshBuffer.size();
382 std::vector<char> encodedStr(Base64::encodedsize_base64(meshBufferSize) + 1);
383 Base64::encode_base64(&encodedStr[0], &meshBuffer[0], meshBufferSize, true);
384 meshNode->setAttr("Version", nMeshVersion);
385 meshNode->setAttr("BinaryData", &encodedStr[0]);
392 // Get a list of incompatible subtools with current Designer Object type
393 std::vector<EDesignerTool> DesignerObject::GetIncompatibleSubtools()
395 return std::vector<EDesignerTool>();
398 void DesignerObject::CreateInspectorWidgets(CInspectorWidgetCreator& creator)
400 CBaseObject::CreateInspectorWidgets(creator);
402 creator.AddPropertyTree<DesignerObject>("Designer", [](DesignerObject* pObject, Serialization::IArchive& ar, bool bMultiEdit)
404 pObject->m_EngineFlags.Serialize(ar);
406 if (ar.openBlock("Edit", "<Edit"))
408 ar(Serialization::ActionButton([=]
410 GetIEditor()->ExecuteCommand("general.open_pane 'Modeling'");
412 , "edit", "^Edit");
413 ar.closeBlock();
416 if (ar.isInput())
418 pObject->UpdateGameResource();
423 void DesignerObject::SetMaterial(IEditorMaterial* mtl)
425 bool bAssignedSubmaterial = false;
427 if (mtl == NULL)
428 mtl = GetIEditor()->GetMaterialManager()->LoadMaterial(BrushDesignerDefaultMaterial);
430 CMaterial* pParentMat = mtl ? ((CMaterial*)mtl)->GetParent() : NULL;
431 if (pParentMat && pParentMat == GetMaterial())
433 DesignerSession* pSession = DesignerSession::GetInstance();
434 Model* pModel = GetModel();
436 for (int i = 0, iSubMatCount(pParentMat->GetSubMaterialCount()); i < iSubMatCount; ++i)
438 if (pParentMat->GetSubMaterial(i) != mtl)
439 continue;
441 if (pSession->GetIsActive())
443 CBaseObject* pObject = pSession->GetBaseObject();
445 if (CUndo::IsRecording() && pObject)
446 CUndo::Record(new UndoTextureMapping(pObject, "Designer : SetSubMatID"));
448 ElementSet* pSelected = pSession->GetSelectedElements();
449 if (pSelected->IsEmpty())
450 pModel->SetSubMatID(i);
451 else
452 AssignMatIDToSelectedPolygons(i);
454 pSession->SetCurrentSubMatID(i);
456 else
457 pModel->SetSubMatID(i);
459 GetCompiler()->Compile(this, GetModel());
460 bAssignedSubmaterial = true;
461 break;
465 if (!bAssignedSubmaterial)
467 if (!pParentMat)
469 CBaseObject::SetMaterial(mtl);
471 else if (pParentMat != GetMaterial())
473 CBaseObject::SetMaterial(pParentMat);
474 SetMaterial(mtl);
478 UpdateEngineNode();
481 void DesignerObject::SetMaterial(const string& materialName)
483 CMaterial* pMaterial = NULL;
484 pMaterial = GetIEditor()->GetMaterialManager()->LoadMaterial(materialName);
485 if (!pMaterial || (pMaterial && pMaterial->IsDummy()))
487 IMaterial* pMatInfo = GetIEditor()->Get3DEngine()->GetMaterialManager()->LoadMaterial(materialName, false);
488 if (pMatInfo)
490 GetIEditor()->GetMaterialManager()->OnCreateMaterial(pMatInfo);
491 pMaterial = GetIEditor()->GetMaterialManager()->FromIMaterial(pMatInfo);
494 CBaseObject::SetMaterial(pMaterial);
496 const string materialNameWithoutExtension = PathUtil::RemoveExtension(materialName);
497 if (pMaterial->GetName() != materialNameWithoutExtension)
498 m_materialNameOverride = materialNameWithoutExtension;
499 else
500 m_materialNameOverride.Empty();
502 UpdateEngineNode();
505 string DesignerObject::GetMaterialName() const
507 if (!m_materialNameOverride.IsEmpty())
508 return m_materialNameOverride;
510 return CBaseObject::GetMaterialName();
513 void DesignerObject::SetMaterialLayersMask(uint32 nLayersMask)
515 CBaseObject::SetMaterialLayersMask(nLayersMask);
516 UpdateEngineNode();
519 void DesignerObject::SetMinSpec(uint32 nSpec, bool bSetChildren)
521 __super::SetMinSpec(nSpec, bSetChildren);
522 if (GetCompiler() && GetCompiler()->GetRenderNode())
523 GetCompiler()->GetRenderNode()->SetMinSpec(GetMinSpec());
526 bool DesignerObject::IsSimilarObject(CBaseObject* pObject) const
528 if (pObject->GetClassDesc() == GetClassDesc() && GetRuntimeClass() == pObject->GetRuntimeClass())
529 return true;
530 return false;
533 void DesignerObject::OnEvent(ObjectEvent event)
535 CBaseObject::OnEvent(event);
536 switch (event)
538 case EVENT_INGAME:
540 if (CheckFlags(OBJFLAG_SUBOBJ_EDITING))
541 EndSubObjectSelection();
542 DesignerEditor* pDesignerTool = GetDesigner();
543 if (pDesignerTool && !GetIEditor()->GetGameEngine()->GetSimulationMode())
544 pDesignerTool->LeaveCurrentTool();
546 break;
547 case EVENT_OUTOFGAME:
549 DesignerEditor* pDesignerTool = GetDesigner();
550 if (pDesignerTool)
551 pDesignerTool->EnterCurrentTool();
553 break;
557 void DesignerObject::WorldToLocalRay(Vec3& raySrc, Vec3& rayDir) const
559 raySrc = m_invertTM.TransformPoint(raySrc);
560 rayDir = m_invertTM.TransformVector(rayDir).GetNormalized();
563 void DesignerObject::InvalidateTM(int nWhyFlags)
565 CBaseObject::InvalidateTM(nWhyFlags);
566 UpdateEngineNode();
567 m_invertTM = GetWorldTM();
568 m_invertTM.Invert();
571 void DesignerObject::GenerateGameFilename(string& generatedFileName) const
573 generatedFileName.Format("%%level%%/Brush/designer_%d.%s", m_nBrushUniqFileId, CRY_GEOMETRY_FILE_EXT);
576 void DesignerObject::DrawDimensions(SDisplayContext& dc, AABB* pMergedBoundBox)
578 if (!HasMeasurementAxis() || GetDesigner() || !gDesignerSettings.bDisplayDimensionHelper)
579 return;
580 AABB localBoundBox;
581 GetLocalBounds(localBoundBox);
582 DrawDimensionsImpl(dc, localBoundBox, pMergedBoundBox);
585 IRenderNode* DesignerObject::GetEngineNode() const
587 if (!GetCompiler() || !GetCompiler()->GetRenderNode())
588 return NULL;
589 return GetCompiler()->GetRenderNode();
592 DesignerObjectFlags::DesignerObjectFlags() : m_pObj(NULL)
594 outdoor = false;
595 castShadows = true;
596 giMode = true;
597 supportSecVisArea = false;
598 rainOccluder = false;
599 hideable = false;
600 ratioViewDist = 100;
601 excludeFromTriangulation = false;
602 noDynWater = false;
603 noStaticDecals = false;
604 excludeCollision = false;
605 occluder = false;
606 ignoreTerrainLayerBlend = false;
607 ignoreDecalBlend = false;
610 void DesignerObjectFlags::Set()
612 ratioViewDist = m_pObj->GetCompiler()->GetViewDistRatio();
613 uint64 flags = m_pObj->GetCompiler()->GetRenderFlags();
614 int statobjFlags = m_pObj->GetCompiler()->GetStaticObjFlags();
615 outdoor = (flags & ERF_OUTDOORONLY) != 0;
616 rainOccluder = (flags & ERF_RAIN_OCCLUDER) != 0;
617 castShadows = (flags & ERF_CASTSHADOWMAPS) != 0;
618 giMode = (flags & ERF_GI_MODE_BIT0) != 0;
619 supportSecVisArea = (flags & ERF_REGISTER_BY_BBOX) != 0;
620 occluder = (flags & ERF_GOOD_OCCLUDER) != 0;
621 hideable = (flags & ERF_HIDABLE) != 0;
622 noDynWater = (flags & ERF_NODYNWATER) != 0;
623 noStaticDecals = (flags & ERF_NO_DECALNODE_DECALS) != 0;
624 excludeFromTriangulation = (flags & ERF_EXCLUDE_FROM_TRIANGULATION) != 0;
625 excludeCollision = (statobjFlags & STATIC_OBJECT_NO_PLAYER_COLLIDE) != 0;
626 ignoreTerrainLayerBlend = (flags & ERF_FOB_ALLOW_TERRAIN_LAYER_BLEND) == 0;
627 ignoreDecalBlend = (flags & ERF_FOB_ALLOW_DECAL_BLEND) == 0;
630 void DesignerObjectFlags::Serialize(Serialization::IArchive& ar)
632 ar(castShadows, "castShadows", "Cast Shadows");
633 ar(giMode, "globalIllumination", "Global Illumination");
634 ar(supportSecVisArea, "supportSecVisArea", "Support Second Visarea");
635 ar(outdoor, "outdoor", "Outdoor");
636 ar(rainOccluder, "rainOccluder", "Rain Occluder");
637 ar(ratioViewDist, "ratioViewDist", "View Distance Ratio");
638 ar(excludeFromTriangulation, "excludeFromTriangulation", "Exclude From Navigation");
639 ar(hideable, "hideable", "AI Hideable");
640 ar(noDynWater, "noDynWater", "No Dynamic Water");
641 ar(noStaticDecals, "noStaticDecals", "No Static Decal");
642 ar(excludeCollision, "excludeCollision", "Exclude Collision");
643 ar(occluder, "occluder", "Occluder");
644 ar(ignoreTerrainLayerBlend, "ignoreTerrainLayerBlend", "Ignore Terrain Layer Blending");
645 ar(ignoreDecalBlend, "ignoreDecalBlend", "Ignore Decal Blending");
646 if (ar.isInput())
647 Update();
650 template<typename T>
651 void ModifyFlag(T& nFlags, const T& flag, const T& clearFlag, bool var)
653 nFlags = (var) ? (nFlags | flag) : (nFlags & (~clearFlag));
655 template<typename T>
656 void ModifyFlag(T& nFlags, const T& flag, bool var)
658 ModifyFlag(nFlags, flag, flag, var);
661 void DesignerObjectFlags::Update()
663 const uint64 nOldFlags = m_pObj->GetCompiler()->GetRenderFlags();
664 uint64 nFlags = nOldFlags;
665 int statobjFlags = m_pObj->GetCompiler()->GetStaticObjFlags();
667 ModifyFlag<uint64>(nFlags, ERF_OUTDOORONLY, outdoor);
668 ModifyFlag<uint64>(nFlags, ERF_RAIN_OCCLUDER, rainOccluder);
669 ModifyFlag<uint64>(nFlags, ERF_CASTSHADOWMAPS | ERF_HAS_CASTSHADOWMAPS, ERF_CASTSHADOWMAPS, castShadows);
670 ModifyFlag<uint64>(nFlags, ERF_GI_MODE_BIT0, giMode);
671 ModifyFlag<uint64>(nFlags, ERF_REGISTER_BY_BBOX, supportSecVisArea);
672 ModifyFlag<uint64>(nFlags, ERF_HIDABLE, hideable);
673 ModifyFlag<uint64>(nFlags, ERF_EXCLUDE_FROM_TRIANGULATION, excludeFromTriangulation);
674 ModifyFlag<uint64>(nFlags, ERF_NODYNWATER, noDynWater);
675 ModifyFlag<uint64>(nFlags, ERF_NO_DECALNODE_DECALS, noStaticDecals);
676 ModifyFlag<uint64>(nFlags, ERF_GOOD_OCCLUDER, occluder);
677 ModifyFlag<uint64>(nFlags, ERF_FOB_ALLOW_TERRAIN_LAYER_BLEND, !ignoreTerrainLayerBlend);
678 ModifyFlag<uint64>(nFlags, ERF_FOB_ALLOW_DECAL_BLEND, !ignoreDecalBlend);
679 ModifyFlag<int>(statobjFlags, STATIC_OBJECT_NO_PLAYER_COLLIDE, excludeCollision);
681 m_pObj->GetCompiler()->SetViewDistRatio(ratioViewDist);
682 m_pObj->GetCompiler()->SetRenderFlags(nFlags);
683 m_pObj->GetCompiler()->SetStaticObjFlags(statobjFlags);
684 m_pObj->GetCompiler()->Compile(m_pObj, m_pObj->GetModel(), eShelf_Base, true);
685 ApplyPostProcess(m_pObj->GetMainContext(), ePostProcess_SyncPrefab);
687 if ((nOldFlags & ERF_EXCLUDE_FROM_TRIANGULATION) != (nFlags & ERF_EXCLUDE_FROM_TRIANGULATION))
689 AABB bbox;
690 m_pObj->GetBoundBox(bbox);
691 GetIEditor()->GetAIManager()->OnAreaModified(bbox);