git mv Code\Sandbox\Editor Code/Editor
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,643 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : CSelectionGroup implementation.
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "SelectionGroup.h"
|
||||
|
||||
// Editor
|
||||
#include "ViewManager.h"
|
||||
#include "Include/IObjectManager.h"
|
||||
|
||||
#include <IStatObj.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CSelectionGroup::CSelectionGroup()
|
||||
: m_ref(1)
|
||||
, m_bVertexSnapped(false)
|
||||
{
|
||||
m_LastestMoveSelectionFlag = eMS_None;
|
||||
m_LastestMovedObjectRot.SetIdentity();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::AddObject(CBaseObject* obj)
|
||||
{
|
||||
if (!IsContainObject(obj))
|
||||
{
|
||||
m_objects.push_back(obj);
|
||||
m_objectsSet.insert(obj);
|
||||
m_filtered.clear();
|
||||
|
||||
if (obj->GetType() != OBJTYPE_AZENTITY)
|
||||
{
|
||||
m_legacyObjectsSet.insert(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::RemoveObject(CBaseObject* obj)
|
||||
{
|
||||
for (Objects::iterator it = m_objects.begin(); it != m_objects.end(); ++it)
|
||||
{
|
||||
if (*it == obj)
|
||||
{
|
||||
m_objects.erase(it);
|
||||
m_objectsSet.erase(obj);
|
||||
m_legacyObjectsSet.erase(obj);
|
||||
m_filtered.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::RemoveAll()
|
||||
{
|
||||
m_objects.clear();
|
||||
m_objectsSet.clear();
|
||||
m_filtered.clear();
|
||||
m_legacyObjectsSet.clear();
|
||||
}
|
||||
|
||||
void CSelectionGroup::RemoveAllExceptLegacySet()
|
||||
{
|
||||
m_objects.clear();
|
||||
m_objectsSet.clear();
|
||||
m_filtered.clear();
|
||||
}
|
||||
|
||||
bool CSelectionGroup::IsContainObject(CBaseObject* obj)
|
||||
{
|
||||
return (m_objectsSet.find(obj) != m_objectsSet.end());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CSelectionGroup::IsEmpty() const
|
||||
{
|
||||
return m_objects.empty();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CSelectionGroup::SameObjectType()
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
CBaseObjectPtr pFirst = (*(m_objects.begin()));
|
||||
for (Objects::iterator it = m_objects.begin(); it != m_objects.end(); ++it)
|
||||
{
|
||||
if ((*it)->metaObject() != pFirst->metaObject())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CSelectionGroup::GetCount() const
|
||||
{
|
||||
return m_objects.size();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CBaseObject* CSelectionGroup::GetObject(int index) const
|
||||
{
|
||||
assert(index >= 0 && index < m_objects.size());
|
||||
return m_objects[index];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CBaseObject* CSelectionGroup::GetObjectByGuid(REFGUID guid) const
|
||||
{
|
||||
for (size_t i = 0, count(m_objects.size()); i < count; ++i)
|
||||
{
|
||||
if (m_objects[i]->GetId() == guid)
|
||||
{
|
||||
return m_objects[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
std::set<CBaseObjectPtr>& CSelectionGroup::GetLegacyObjects()
|
||||
{
|
||||
return m_legacyObjectsSet;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Copy(const CSelectionGroup& from)
|
||||
{
|
||||
m_name = from.m_name;
|
||||
m_objects = from.m_objects;
|
||||
m_objectsSet = from.m_objectsSet;
|
||||
m_filtered = from.m_filtered;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
Vec3 CSelectionGroup::GetCenter() const
|
||||
{
|
||||
Vec3 c(0, 0, 0);
|
||||
for (int i = 0; i < GetCount(); i++)
|
||||
{
|
||||
c += GetObject(i)->GetWorldPos();
|
||||
}
|
||||
if (GetCount() > 0)
|
||||
{
|
||||
c /= GetCount();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
AABB CSelectionGroup::GetBounds() const
|
||||
{
|
||||
AABB b;
|
||||
AABB box;
|
||||
box.Reset();
|
||||
for (int i = 0; i < GetCount(); i++)
|
||||
{
|
||||
GetObject(i)->GetBoundBox(b);
|
||||
box.Add(b.min);
|
||||
box.Add(b.max);
|
||||
}
|
||||
return box;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::FilterParents()
|
||||
{
|
||||
if (!m_filtered.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_filtered.reserve(m_objects.size());
|
||||
for (int i = 0; i < m_objects.size(); i++)
|
||||
{
|
||||
CBaseObject* obj = m_objects[i];
|
||||
CBaseObject* parent = obj->GetParent();
|
||||
bool bParentInSet = false;
|
||||
while (parent)
|
||||
{
|
||||
if (m_objectsSet.find(parent) != m_objectsSet.end())
|
||||
{
|
||||
bParentInSet = true;
|
||||
break;
|
||||
}
|
||||
parent = parent->GetParent();
|
||||
}
|
||||
if (!bParentInSet)
|
||||
{
|
||||
m_filtered.push_back(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Move(const Vec3& offset, EMoveSelectionFlag moveFlag, [[maybe_unused]] int referenceCoordSys, const QPoint& point)
|
||||
{
|
||||
// [MichaelS - 17/3/2005] Removed this code from the three edit functions (move,
|
||||
// rotate and scale). This was causing a bug where the render node of objects
|
||||
// was not being updated when objects were dragged away from their position
|
||||
// and then back again, since movement is re-calculated from the initial position
|
||||
// each mouse message (ie first the previous movement is undone and then the
|
||||
// movement is applied). This meant that when moving back to the start position
|
||||
// it appeared like no movement was applied, although it was still necessary to
|
||||
// update the graphics resources. The object transform is explicitly reset
|
||||
// below.
|
||||
|
||||
//if (offset.x == 0 && offset.y == 0 && offset.z == 0)
|
||||
// return;
|
||||
|
||||
m_bVertexSnapped = false;
|
||||
FilterParents();
|
||||
Vec3 newPos;
|
||||
|
||||
bool bValidFollowGeometryMode(true);
|
||||
if (point.x() == -1 || point.y() == -1)
|
||||
{
|
||||
bValidFollowGeometryMode = false;
|
||||
}
|
||||
|
||||
SRayHitInfo pickedInfo;
|
||||
|
||||
if (moveFlag == eMS_FollowGeometryPosNorm)
|
||||
{
|
||||
if (m_LastestMoveSelectionFlag != eMS_FollowGeometryPosNorm)
|
||||
{
|
||||
if (GetFilteredCount() > 0)
|
||||
{
|
||||
CBaseObject* pObj = GetFilteredObject(0);
|
||||
m_LastestMovedObjectRot = pObj->GetRotation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_LastestMoveSelectionFlag = moveFlag;
|
||||
|
||||
for (int i = 0; i < GetFilteredCount(); i++)
|
||||
{
|
||||
CBaseObject* obj = GetFilteredObject(i);
|
||||
|
||||
if(obj->IsFrozen())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == 0 && moveFlag == eMS_FollowGeometryPosNorm && bValidFollowGeometryMode)
|
||||
{
|
||||
Vec3 zaxis = m_LastestMovedObjectRot * Vec3(0, 0, 1);
|
||||
zaxis.Normalize();
|
||||
Quat nq;
|
||||
nq.SetRotationV0V1(zaxis, pickedInfo.vHitNormal);
|
||||
obj->SetPos(pickedInfo.vHitPos);
|
||||
obj->SetRotation(nq * m_LastestMovedObjectRot);
|
||||
continue;
|
||||
}
|
||||
|
||||
Matrix34 wtm = obj->GetWorldTM();
|
||||
Vec3 wp = wtm.GetTranslation();
|
||||
|
||||
newPos = wp + offset;
|
||||
if (moveFlag == eMS_FollowTerrain)
|
||||
{
|
||||
// Make sure object keeps it height.
|
||||
float height = wp.z - GetIEditor()->GetTerrainElevation(wp.x, wp.y);
|
||||
newPos.z = GetIEditor()->GetTerrainElevation(newPos.x, newPos.y) + height;
|
||||
}
|
||||
|
||||
obj->SetWorldPos(newPos, eObjectUpdateFlags_UserInput | eObjectUpdateFlags_PositionChanged | eObjectUpdateFlags_MoveTool);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::MoveTo(const Vec3& pos, EMoveSelectionFlag moveFlag, int referenceCoordSys, const QPoint& point)
|
||||
{
|
||||
FilterParents();
|
||||
if (GetFilteredCount() < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CBaseObject* refObj = GetFilteredObject(0);
|
||||
CSelectionGroup::Move(pos - refObj->GetWorldTM().GetTranslation(), moveFlag, referenceCoordSys, point);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Rotate(const Quat& qRot, int referenceCoordSys)
|
||||
{
|
||||
Matrix34 rotateTM;
|
||||
rotateTM.SetIdentity();
|
||||
rotateTM = Matrix33(qRot) * rotateTM;
|
||||
|
||||
Rotate(rotateTM, referenceCoordSys);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Rotate(const Ang3& angles, int referenceCoordSys)
|
||||
{
|
||||
//if (angles.x == 0 && angles.y == 0 && angles.z == 0)
|
||||
// return;
|
||||
|
||||
// Rotate selection about selection center.
|
||||
Vec3 center = GetCenter();
|
||||
|
||||
Matrix34 rotateTM = Matrix34::CreateRotationXYZ(DEG2RAD(angles));
|
||||
Rotate(rotateTM, referenceCoordSys);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Rotate(const Matrix34& rotateTM, int referenceCoordSys)
|
||||
{
|
||||
// Rotate selection about selection center.
|
||||
Vec3 center = GetCenter();
|
||||
|
||||
Matrix34 ToOrigin = Matrix34::CreateIdentity();
|
||||
Matrix34 FromOrigin = Matrix34::CreateIdentity();
|
||||
|
||||
if (referenceCoordSys != COORDS_LOCAL)
|
||||
{
|
||||
ToOrigin.SetTranslation(-center);
|
||||
FromOrigin.SetTranslation(center);
|
||||
|
||||
if (referenceCoordSys == COORDS_USERDEFINED)
|
||||
{
|
||||
Matrix34 userTM;
|
||||
userTM.SetIdentity();
|
||||
Matrix34 invUserTM = userTM.GetInvertedFast();
|
||||
|
||||
ToOrigin = invUserTM * ToOrigin;
|
||||
FromOrigin = FromOrigin * userTM;
|
||||
}
|
||||
}
|
||||
|
||||
FilterParents();
|
||||
|
||||
for (int i = 0; i < GetFilteredCount(); i++)
|
||||
{
|
||||
CBaseObject* obj = GetFilteredObject(i);
|
||||
|
||||
Matrix34 objectTransform = obj->GetWorldTM();
|
||||
if (referenceCoordSys != COORDS_LOCAL)
|
||||
{
|
||||
if (referenceCoordSys == COORDS_PARENT && obj->GetParent())
|
||||
{
|
||||
Matrix34 parentTM = obj->GetParent()->GetWorldTM();
|
||||
parentTM.OrthonormalizeFast();
|
||||
parentTM.SetTranslation(Vec3(0, 0, 0));
|
||||
Matrix34 invParentTM = parentTM.GetInvertedFast();
|
||||
|
||||
objectTransform = FromOrigin * parentTM * rotateTM * invParentTM * ToOrigin * objectTransform;
|
||||
}
|
||||
else
|
||||
{
|
||||
objectTransform = FromOrigin * rotateTM * ToOrigin * objectTransform;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Decompose the matrix and reconstruct it to ensure no scaling artifacts are introduced
|
||||
AffineParts affineParts;
|
||||
affineParts.SpectralDecompose(objectTransform);
|
||||
|
||||
Matrix33 rotationMatrix(affineParts.rot);
|
||||
Matrix34 translationMatrix = Matrix34::CreateTranslationMat(affineParts.pos);
|
||||
Matrix33 scaleMatrix = Matrix33::CreateScale(affineParts.scale);
|
||||
|
||||
objectTransform = translationMatrix * rotationMatrix * rotateTM * scaleMatrix;
|
||||
}
|
||||
|
||||
obj->SetWorldTM(objectTransform, eObjectUpdateFlags_UserInput);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Scale(const Vec3& scale, int referenceCoordSys)
|
||||
{
|
||||
//if (scale.x == 1 && scale.y == 1 && scale.z == 1)
|
||||
// return;
|
||||
|
||||
Vec3 scl = scale;
|
||||
if (scl.x == 0)
|
||||
{
|
||||
scl.x = 0.01f;
|
||||
}
|
||||
if (scl.y == 0)
|
||||
{
|
||||
scl.y = 0.01f;
|
||||
}
|
||||
if (scl.z == 0)
|
||||
{
|
||||
scl.z = 0.01f;
|
||||
}
|
||||
|
||||
// Scale selection relative to selection center.
|
||||
Vec3 center = GetCenter();
|
||||
|
||||
Matrix34 scaleTM;
|
||||
scaleTM.SetIdentity();
|
||||
scaleTM = Matrix33::CreateScale(Vec3(scl.x, scl.y, scl.z)) * scaleTM;
|
||||
|
||||
Matrix34 ToOrigin;
|
||||
Matrix34 FromOrigin;
|
||||
|
||||
ToOrigin.SetIdentity();
|
||||
FromOrigin.SetIdentity();
|
||||
|
||||
if (referenceCoordSys != COORDS_LOCAL)
|
||||
{
|
||||
ToOrigin.SetTranslation(-center);
|
||||
FromOrigin.SetTranslation(center);
|
||||
}
|
||||
|
||||
FilterParents();
|
||||
|
||||
for (int i = 0; i < GetFilteredCount(); i++)
|
||||
{
|
||||
CBaseObject* obj = GetFilteredObject(i);
|
||||
Matrix34 m = obj->GetWorldTM();
|
||||
|
||||
if (referenceCoordSys != COORDS_LOCAL)
|
||||
{
|
||||
// Apply new scale
|
||||
m = FromOrigin * scaleTM * ToOrigin * m;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply new scale
|
||||
m = m * scaleTM;
|
||||
}
|
||||
|
||||
obj->SetWorldTM(m, eObjectUpdateFlags_UserInput | eObjectUpdateFlags_ScaleTool);
|
||||
obj->InvalidateTM(eObjectUpdateFlags_UserInput | eObjectUpdateFlags_ScaleTool);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSelectionGroup::SetScale(const Vec3& scale, int referenceCoordSys)
|
||||
{
|
||||
Vec3 relScale = scale;
|
||||
|
||||
if (GetCount() > 0 && GetObject(0))
|
||||
{
|
||||
Vec3 objScale = GetObject(0)->GetScale();
|
||||
if (relScale == objScale && (objScale.x == 0.0f || objScale.y == 0.0f || objScale.z == 0.0f))
|
||||
{
|
||||
return;
|
||||
}
|
||||
relScale = relScale / objScale;
|
||||
}
|
||||
|
||||
Scale(relScale, referenceCoordSys);
|
||||
}
|
||||
|
||||
|
||||
void CSelectionGroup::StartScaling()
|
||||
{
|
||||
for (int i = 0; i < GetFilteredCount(); i++)
|
||||
{
|
||||
CBaseObject* obj = GetFilteredObject(i);
|
||||
obj->StartScaling();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Align()
|
||||
{
|
||||
for (int i = 0; i < GetFilteredCount(); ++i)
|
||||
{
|
||||
bool terrain = false;
|
||||
CBaseObject* obj = GetFilteredObject(i);
|
||||
Vec3 pos = obj->GetPos();
|
||||
Quat rot = obj->GetRotation();
|
||||
QPoint point = GetIEditor()->GetActiveView()->WorldToView(pos);
|
||||
Vec3 normal = GetIEditor()->GetActiveView()->ViewToWorldNormal(point, false, true);
|
||||
pos = GetIEditor()->GetActiveView()->ViewToWorld(point, &terrain, false, false, true);
|
||||
Vec3 zaxis = rot * Vec3(0, 0, 1);
|
||||
normal.Normalize();
|
||||
zaxis.Normalize();
|
||||
Quat nq;
|
||||
nq.SetRotationV0V1(zaxis, normal);
|
||||
obj->SetRotation(nq * rot);
|
||||
obj->SetPos(pos);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Transform(const Vec3& offset, EMoveSelectionFlag moveFlag, const Ang3& angles, const Vec3& scale, int referenceCoordSys)
|
||||
{
|
||||
if (offset != Vec3(0))
|
||||
{
|
||||
Move(offset, moveFlag, referenceCoordSys);
|
||||
}
|
||||
|
||||
if (!(angles == Ang3(ZERO)))
|
||||
{
|
||||
Rotate(angles, referenceCoordSys);
|
||||
}
|
||||
|
||||
if (scale != Vec3(0))
|
||||
{
|
||||
Scale(scale, referenceCoordSys);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::ResetTransformation()
|
||||
{
|
||||
FilterParents();
|
||||
Quat qIdentity;
|
||||
qIdentity.SetIdentity();
|
||||
Vec3 vScale(1.0f, 1.0f, 1.0f);
|
||||
|
||||
for (int i = 0, n = GetFilteredCount(); i < n; ++i)
|
||||
{
|
||||
CBaseObject* pObj = GetFilteredObject(i);
|
||||
pObj->SetRotation(qIdentity);
|
||||
pObj->SetScale(vScale);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::Clone(CSelectionGroup& newGroup)
|
||||
{
|
||||
IObjectManager* pObjMan = GetIEditor()->GetObjectManager();
|
||||
assert(pObjMan);
|
||||
|
||||
int i;
|
||||
CObjectCloneContext cloneContext;
|
||||
|
||||
FilterParents();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Clone every object.
|
||||
for (i = 0; i < GetFilteredCount(); i++)
|
||||
{
|
||||
CBaseObject* pFromObject = GetFilteredObject(i);
|
||||
CBaseObject* newObj = pObjMan->CloneObject(pFromObject);
|
||||
if (!newObj) // can be null, e.g. sequence can't be cloned
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cloneContext.AddClone(pFromObject, newObj);
|
||||
newGroup.AddObject(newObj);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Only after everything was cloned, call PostClone on all cloned objects.
|
||||
for (i = 0; i < newGroup.GetCount(); ++i)
|
||||
{
|
||||
CBaseObject* pFromObject = GetFilteredObject(i);
|
||||
CBaseObject* pClonedObject = newGroup.GetObject(i);
|
||||
if (pClonedObject)
|
||||
{
|
||||
pClonedObject->PostClone(pFromObject, cloneContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::SendEvent(ObjectEvent event)
|
||||
{
|
||||
for (int i = 0; i < m_objects.size(); i++)
|
||||
{
|
||||
CBaseObject* obj = m_objects[i];
|
||||
obj->OnEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ULONG STDMETHODCALLTYPE CSelectionGroup::AddRef()
|
||||
{
|
||||
return ++m_ref;
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ULONG STDMETHODCALLTYPE CSelectionGroup::Release()
|
||||
{
|
||||
if ((--m_ref) == 0)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_ref;
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::IndicateSnappingVertex(DisplayContext& dc) const
|
||||
{
|
||||
if (m_bVertexSnapped == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dc.DepthTestOff();
|
||||
|
||||
ColorB green(0, 255, 0, 255);
|
||||
|
||||
dc.SetColor(green);
|
||||
float fScale = dc.view->GetScreenScaleFactor(m_snapVertex) * 0.005f;
|
||||
Vec3 sz(fScale, fScale, fScale);
|
||||
dc.DrawWireBox(m_snapVertex - sz, m_snapVertex + sz);
|
||||
|
||||
dc.DepthTestOn();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSelectionGroup::FinishChanges()
|
||||
{
|
||||
Objects selectedObjects(m_objects);
|
||||
int iObjectSize(selectedObjects.size());
|
||||
for (int i = 0; i < iObjectSize; ++i)
|
||||
{
|
||||
CBaseObject* pObject = selectedObjects[i];
|
||||
if (pObject == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user