You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
962 lines
30 KiB
C++
962 lines
30 KiB
C++
|
|
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
#include "EditorDefs.h"
|
|
|
|
#include "ModelViewport.h"
|
|
|
|
// Qt
|
|
#include <QMessageBox>
|
|
#include <QSettings>
|
|
|
|
// CryCommon
|
|
#include <CryCommon/IViewSystem.h>
|
|
|
|
#include "CryPhysicsDeprecation.h"
|
|
|
|
|
|
// Editor
|
|
#include "ThumbnailGenerator.h" // for CThumbnailGenerator
|
|
#include "FileTypeUtils.h" // for IsPreviewableFileType
|
|
#include "ErrorRecorder.h"
|
|
|
|
|
|
|
|
|
|
|
|
uint32 g_ypos = 0;
|
|
|
|
#define SKYBOX_NAME "InfoRedGal"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CModelViewport
|
|
|
|
CModelViewport::CModelViewport(const char* settingsPath, QWidget* parent)
|
|
: CRenderViewport(tr("Model View"), parent)
|
|
{
|
|
m_settingsPath = QString::fromLatin1(settingsPath);
|
|
|
|
m_bPaused = false;
|
|
|
|
m_Camera.SetFrustum(800, 600, 3.14f / 4.0f, 0.02f, 10000);
|
|
|
|
m_bInRotateMode = false;
|
|
m_bInMoveMode = false;
|
|
|
|
m_object = 0;
|
|
|
|
|
|
m_weaponModel = 0;
|
|
|
|
m_camRadius = 10;
|
|
|
|
m_moveSpeed = 0.1f;
|
|
m_LightRotationRadian = 0.0f;
|
|
|
|
m_weaponIK = false;
|
|
|
|
m_pRESky = 0;
|
|
m_pSkyboxName = 0;
|
|
m_pSkyBoxShader = NULL;
|
|
|
|
m_attachBone = QStringLiteral("weapon_bone");
|
|
|
|
// Init variable.
|
|
mv_objectAmbientColor = Vec3(0.25f, 0.25f, 0.25f);
|
|
mv_backgroundColor = Vec3(0.25f, 0.25f, 0.25f);
|
|
|
|
mv_lightDiffuseColor = Vec3(0.70f, 0.70f, 0.70f);
|
|
mv_lightMultiplier = 3.0f;
|
|
mv_lightOrbit = 15.0f;
|
|
mv_lightRadius = 400.0f;
|
|
mv_lightSpecMultiplier = 1.0f;
|
|
|
|
mv_showPhysics = false;
|
|
|
|
m_GridOrigin = Vec3(ZERO);
|
|
m_arrAnimatedCharacterPath.resize(0x200, ZERO);
|
|
m_arrSmoothEntityPath.resize(0x200, ZERO);
|
|
|
|
m_arrRunStrafeSmoothing.resize(0x100);
|
|
SetPlayerPos();
|
|
|
|
// cache all the variable callbacks, must match order of enum defined in header
|
|
m_onSetCallbacksCache.push_back(AZStd::bind(&CModelViewport::OnCharPhysics, this, AZStd::placeholders::_1));
|
|
m_onSetCallbacksCache.push_back(AZStd::bind(&CModelViewport::OnLightColor, this, AZStd::placeholders::_1));
|
|
m_onSetCallbacksCache.push_back(AZStd::bind(&CModelViewport::OnLightMultiplier, this, AZStd::placeholders::_1));
|
|
m_onSetCallbacksCache.push_back(AZStd::bind(&CModelViewport::OnShowShaders, this, AZStd::placeholders::_1));
|
|
|
|
//--------------------------------------------------
|
|
// Register variables.
|
|
//--------------------------------------------------
|
|
m_vars.AddVariable(mv_showPhysics, "Display Physics");
|
|
m_vars.AddVariable(mv_useCharPhysics, "Use Character Physics", &m_onSetCallbacksCache[VariableCallbackIndex::OnCharPhysics]);
|
|
mv_useCharPhysics = true;
|
|
m_vars.AddVariable(mv_showGrid, "ShowGrid");
|
|
mv_showGrid = true;
|
|
m_vars.AddVariable(mv_showBase, "ShowBase");
|
|
mv_showBase = false;
|
|
m_vars.AddVariable(mv_showLocator, "ShowLocator");
|
|
mv_showLocator = 0;
|
|
m_vars.AddVariable(mv_InPlaceMovement, "InPlaceMovement");
|
|
mv_InPlaceMovement = false;
|
|
m_vars.AddVariable(mv_StrafingControl, "StrafingControl");
|
|
mv_StrafingControl = false;
|
|
|
|
m_vars.AddVariable(mv_lighting, "Lighting");
|
|
mv_lighting = true;
|
|
m_vars.AddVariable(mv_animateLights, "AnimLights");
|
|
|
|
m_vars.AddVariable(mv_backgroundColor, "BackgroundColor", &m_onSetCallbacksCache[VariableCallbackIndex::OnLightColor], IVariable::DT_COLOR);
|
|
m_vars.AddVariable(mv_objectAmbientColor, "ObjectAmbient", &m_onSetCallbacksCache[VariableCallbackIndex::OnLightColor], IVariable::DT_COLOR);
|
|
|
|
m_vars.AddVariable(mv_lightDiffuseColor, "LightDiffuse", &m_onSetCallbacksCache[VariableCallbackIndex::OnLightColor], IVariable::DT_COLOR);
|
|
m_vars.AddVariable(mv_lightMultiplier, "Light Multiplier", &m_onSetCallbacksCache[VariableCallbackIndex::OnLightMultiplier], IVariable::DT_SIMPLE);
|
|
m_vars.AddVariable(mv_lightSpecMultiplier, "Light Specular Multiplier", &m_onSetCallbacksCache[VariableCallbackIndex::OnLightMultiplier], IVariable::DT_SIMPLE);
|
|
m_vars.AddVariable(mv_lightRadius, "Light Radius", &m_onSetCallbacksCache[VariableCallbackIndex::OnLightMultiplier], IVariable::DT_SIMPLE);
|
|
m_vars.AddVariable(mv_lightOrbit, "Light Orbit", &m_onSetCallbacksCache[VariableCallbackIndex::OnLightMultiplier], IVariable::DT_SIMPLE);
|
|
|
|
m_vars.AddVariable(mv_showWireframe1, "ShowWireframe1");
|
|
m_vars.AddVariable(mv_showWireframe2, "ShowWireframe2");
|
|
m_vars.AddVariable(mv_showTangents, "ShowTangents");
|
|
m_vars.AddVariable(mv_showBinormals, "ShowBinormals");
|
|
m_vars.AddVariable(mv_showNormals, "ShowNormals");
|
|
|
|
m_vars.AddVariable(mv_showSkeleton, "ShowSkeleton");
|
|
m_vars.AddVariable(mv_showJointNames, "ShowJointNames");
|
|
m_vars.AddVariable(mv_showJointsValues, "ShowJointsValues");
|
|
m_vars.AddVariable(mv_showStartLocation, "ShowInvStartLocation");
|
|
m_vars.AddVariable(mv_showMotionParam, "ShowMotionParam");
|
|
m_vars.AddVariable(mv_printDebugText, "PrintDebugText");
|
|
|
|
m_vars.AddVariable(mv_UniformScaling, "UniformScaling");
|
|
mv_UniformScaling = 1.0f;
|
|
mv_UniformScaling.SetLimits(0.01f, 2.0f);
|
|
m_vars.AddVariable(mv_forceLODNum, "ForceLODNum");
|
|
mv_forceLODNum = 0;
|
|
mv_forceLODNum.SetLimits(0, 10);
|
|
m_vars.AddVariable(mv_showShaders, "ShowShaders", &m_onSetCallbacksCache[VariableCallbackIndex::OnShowShaders]);
|
|
m_vars.AddVariable(mv_AttachCamera, "AttachCamera");
|
|
|
|
m_vars.AddVariable(mv_fov, "FOV");
|
|
mv_fov = 60;
|
|
mv_fov.SetLimits(1, 120);
|
|
|
|
RestoreDebugOptions();
|
|
|
|
m_camRadius = 10;
|
|
|
|
//YPR_Angle = Ang3(0,-1.0f,0);
|
|
//SetViewTM( Matrix34(CCamera::CreateOrientationYPR(YPR_Angle), Vec3(0,-m_camRadius,0)) );
|
|
Vec3 camPos = Vec3(10, 10, 10);
|
|
Matrix34 tm = Matrix33::CreateRotationVDir((Vec3(0, 0, 0) - camPos).GetNormalized());
|
|
tm.SetTranslation(camPos);
|
|
SetViewTM(tm);
|
|
|
|
|
|
m_AABB.Reset();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::SaveDebugOptions() const
|
|
{
|
|
QSettings settings;
|
|
for (auto g : m_settingsPath.split('\\'))
|
|
settings.beginGroup(g);
|
|
|
|
CVarBlock* vb = GetVarObject()->GetVarBlock();
|
|
int32 vbCount = vb->GetNumVariables();
|
|
|
|
settings.setValue("iDebugOptionCount", vbCount);
|
|
|
|
char keyType[64], keyValue[64];
|
|
for (int32 i = 0; i < vbCount; ++i)
|
|
{
|
|
IVariable* var = vb->GetVariable(i);
|
|
IVariable::EType vType = var->GetType();
|
|
sprintf_s(keyType, "DebugOption_%s_type", var->GetName().toUtf8().data());
|
|
sprintf_s(keyValue, "DebugOption_%s_value", var->GetName().toUtf8().data());
|
|
switch (vType)
|
|
{
|
|
case IVariable::UNKNOWN:
|
|
{
|
|
break;
|
|
}
|
|
case IVariable::INT:
|
|
{
|
|
int32 value = 0;
|
|
var->Get(value);
|
|
settings.setValue(keyType, IVariable::INT);
|
|
settings.setValue(keyValue, value);
|
|
|
|
break;
|
|
}
|
|
case IVariable::BOOL:
|
|
{
|
|
bool value = 0;
|
|
var->Get(value);
|
|
settings.setValue(keyType, IVariable::BOOL);
|
|
settings.setValue(keyValue, value);
|
|
break;
|
|
}
|
|
case IVariable::FLOAT:
|
|
{
|
|
f32 value = 0;
|
|
var->Get(value);
|
|
settings.setValue(keyType, IVariable::FLOAT);
|
|
settings.setValue(keyValue, value);
|
|
break;
|
|
}
|
|
case IVariable::VECTOR:
|
|
{
|
|
Vec3 value;
|
|
var->Get(value);
|
|
f32 valueArray[3];
|
|
valueArray[0] = value.x;
|
|
valueArray[1] = value.y;
|
|
valueArray[2] = value.z;
|
|
settings.setValue(keyType, IVariable::VECTOR);
|
|
settings.setValue(keyValue, QByteArray(reinterpret_cast<const char*>(&value), 3 * sizeof(f32)));
|
|
|
|
break;
|
|
}
|
|
case IVariable::QUAT:
|
|
{
|
|
Quat value;
|
|
var->Get(value);
|
|
f32 valueArray[4];
|
|
valueArray[0] = value.w;
|
|
valueArray[1] = value.v.x;
|
|
valueArray[2] = value.v.y;
|
|
valueArray[3] = value.v.z;
|
|
|
|
settings.setValue(keyType, IVariable::QUAT);
|
|
settings.setValue(keyValue, QByteArray(reinterpret_cast<const char*>(&value), 4 * sizeof(f32)));
|
|
|
|
break;
|
|
}
|
|
case IVariable::STRING:
|
|
{
|
|
QString value;
|
|
var->Get(value);
|
|
settings.setValue(keyType, IVariable::STRING);
|
|
settings.setValue(keyValue, value);
|
|
|
|
break;
|
|
}
|
|
case IVariable::ARRAY:
|
|
{
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::RestoreDebugOptions()
|
|
{
|
|
QSettings settings;
|
|
for (auto g : m_settingsPath.split('\\'))
|
|
settings.beginGroup(g);
|
|
|
|
QString strRead = "";
|
|
int32 iRead = 0;
|
|
BOOL bRead = FALSE;
|
|
f32 fRead = .0f;
|
|
QByteArray pbtData;
|
|
|
|
CVarBlock* vb = m_vars.GetVarBlock();
|
|
int32 vbCount = vb->GetNumVariables();
|
|
|
|
char keyType[64], keyValue[64];
|
|
for (int32 i = 0; i < vbCount; ++i)
|
|
{
|
|
IVariable* var = vb->GetVariable(i);
|
|
sprintf_s(keyType, "DebugOption_%s_type", var->GetName().toUtf8().data());
|
|
|
|
int32 iType = settings.value(keyType, 0).toInt();
|
|
|
|
sprintf_s(keyValue, "DebugOption_%s_value", var->GetName().toUtf8().data());
|
|
switch (iType)
|
|
{
|
|
case IVariable::UNKNOWN:
|
|
{
|
|
break;
|
|
}
|
|
case IVariable::INT:
|
|
{
|
|
iRead = settings.value(keyValue, 0).toInt();
|
|
var->Set(iRead);
|
|
break;
|
|
}
|
|
case IVariable::BOOL:
|
|
{
|
|
bRead = settings.value(keyValue, FALSE).toBool();
|
|
var->Set(bRead);
|
|
break;
|
|
}
|
|
case IVariable::FLOAT:
|
|
{
|
|
fRead = settings.value(keyValue).toDouble();
|
|
var->Set(fRead);
|
|
break;
|
|
}
|
|
case IVariable::VECTOR:
|
|
{
|
|
pbtData = settings.value(keyValue).toByteArray();
|
|
assert(pbtData.count() == 3 * sizeof(f32));
|
|
f32* pfRead = reinterpret_cast<f32*>(pbtData.data());
|
|
|
|
Vec3 vecRead(pfRead[0], pfRead[1], pfRead[2]);
|
|
var->Set(vecRead);
|
|
break;
|
|
}
|
|
case IVariable::QUAT:
|
|
{
|
|
pbtData = settings.value(keyValue).toByteArray();
|
|
assert(pbtData.count() == 4 * sizeof(f32));
|
|
f32* pfRead = reinterpret_cast<f32*>(pbtData.data());
|
|
|
|
Quat valueRead(pfRead[0], pfRead[1], pfRead[2], pfRead[3]);
|
|
var->Set(valueRead);
|
|
break;
|
|
}
|
|
case IVariable::STRING:
|
|
{
|
|
strRead = settings.value(keyValue, "").toString();
|
|
var->Set(strRead);
|
|
break;
|
|
}
|
|
case IVariable::ARRAY:
|
|
{
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CModelViewport::~CModelViewport()
|
|
{
|
|
OnDestroy();
|
|
ReleaseObject();
|
|
|
|
GetIEditor()->FlushUndo();
|
|
|
|
SaveDebugOptions();
|
|
|
|
// helper offset??
|
|
CRY_PHYSICS_REPLACEMENT_ASSERT();
|
|
GetIEditor()->SetConsoleVar("ca_UsePhysics", 1);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CModelViewport message handlers
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::ReleaseObject()
|
|
{
|
|
if (m_object)
|
|
{
|
|
m_object->Release();
|
|
m_object = NULL;
|
|
}
|
|
|
|
if (m_weaponModel)
|
|
{
|
|
m_weaponModel->Release();
|
|
m_weaponModel = NULL;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::LoadObject(const QString& fileName, [[maybe_unused]] float scale)
|
|
{
|
|
m_bPaused = false;
|
|
|
|
// Load object.
|
|
QString file = Path::MakeGamePath(fileName);
|
|
|
|
bool reload = false;
|
|
if (m_loadedFile == file)
|
|
{
|
|
reload = true;
|
|
}
|
|
m_loadedFile = file;
|
|
|
|
SetName(tr("Model View - %1").arg(file));
|
|
|
|
ReleaseObject();
|
|
|
|
// Enables display of warning after model have been loaded.
|
|
CErrorsRecorder errRecorder;
|
|
|
|
if (IsPreviewableFileType(file.toUtf8().data()))
|
|
{
|
|
const QString fileExt = QFileInfo(file).completeSuffix();
|
|
// Try Load character.
|
|
const bool isSKEL = (0 == fileExt.compare(CRY_SKEL_FILE_EXT, Qt::CaseInsensitive));
|
|
const bool isSKIN = (0 == fileExt.compare(CRY_SKIN_FILE_EXT, Qt::CaseInsensitive));
|
|
const bool isCGA = (0 == fileExt.compare(CRY_ANIM_GEOMETRY_FILE_EXT, Qt::CaseInsensitive));
|
|
const bool isCDF = (0 == fileExt.compare(CRY_CHARACTER_DEFINITION_FILE_EXT, Qt::CaseInsensitive));
|
|
if (isSKEL || isSKIN || isCGA || isCDF)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
LoadStaticObject(file);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
QMessageBox::warning(this, tr("Preview Error"), tr("Preview of this file type not supported."));
|
|
return;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------
|
|
|
|
if (!reload)
|
|
{
|
|
Vec3 v = m_AABB.max - m_AABB.min;
|
|
float radius = v.GetLength() / 2.0f;
|
|
m_camRadius = radius * 2;
|
|
}
|
|
|
|
if (GetIEditor()->IsInPreviewMode())
|
|
{
|
|
Physicalize();
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::LoadStaticObject(const QString& file)
|
|
{
|
|
if (m_object)
|
|
{
|
|
m_object->Release();
|
|
}
|
|
|
|
// Load Static object.
|
|
m_object = m_engine->LoadStatObjUnsafeManualRef(file.toUtf8().data(), 0, 0, false);
|
|
|
|
if (!m_object)
|
|
{
|
|
CLogFile::WriteLine("Loading of object failed.");
|
|
return;
|
|
}
|
|
m_object->AddRef();
|
|
|
|
// Generate thumbnail for this cgf.
|
|
CThumbnailGenerator thumbGen;
|
|
thumbGen.GenerateForFile(file);
|
|
|
|
m_AABB.min = m_object->GetBoxMin();
|
|
m_AABB.max = m_object->GetBoxMax();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnRender()
|
|
{
|
|
FUNCTION_PROFILER(GetIEditor()->GetSystem(), PROFILE_EDITOR);
|
|
|
|
const QRect rc = contentsRect();
|
|
ProcessKeys();
|
|
if (m_renderer)
|
|
{
|
|
PreWidgetRendering();
|
|
|
|
m_Camera.SetFrustum(m_Camera.GetViewSurfaceX(), m_Camera.GetViewSurfaceZ(), m_Camera.GetFov(), 0.02f, 10000, m_Camera.GetPixelAspectRatio());
|
|
const int w = rc.width();
|
|
const int h = rc.height();
|
|
m_Camera.SetFrustum(w, h, DEG2RAD(mv_fov), 0.0101f, 10000.0f);
|
|
|
|
if (GetIEditor()->IsInPreviewMode())
|
|
{
|
|
GetISystem()->SetViewCamera(m_Camera);
|
|
}
|
|
|
|
Vec3 clearColor = mv_backgroundColor;
|
|
m_renderer->SetClearColor(clearColor);
|
|
m_renderer->SetCamera(m_Camera);
|
|
|
|
auto colorf = ColorF(clearColor, 1.0f);
|
|
m_renderer->ClearTargetsImmediately(FRT_CLEAR | FRT_CLEAR_IMMEDIATE, colorf);
|
|
m_renderer->ResetToDefault();
|
|
|
|
SRenderingPassInfo passInfo = SRenderingPassInfo::CreateGeneralPassRenderingInfo(m_Camera, SRenderingPassInfo::DEFAULT_FLAGS, true);
|
|
|
|
{
|
|
CScopedWireFrameMode scopedWireFrame(m_renderer, mv_showWireframe1 ? R_WIREFRAME_MODE : R_SOLID_MODE);
|
|
DrawModel(passInfo);
|
|
}
|
|
|
|
PostWidgetRendering();
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::DrawSkyBox(const SRenderingPassInfo& passInfo)
|
|
{
|
|
CRenderObject* pObj = m_renderer->EF_GetObject_Temp(passInfo.ThreadID());
|
|
pObj->m_II.m_Matrix.SetTranslationMat(GetViewTM().GetTranslation());
|
|
|
|
if (m_pSkyboxName)
|
|
{
|
|
SShaderItem skyBoxShaderItem(m_pSkyBoxShader);
|
|
m_renderer->EF_AddEf(m_pRESky, skyBoxShaderItem, pObj, passInfo, EFSLIST_GENERAL, 1, SRendItemSorter::CreateRendItemSorter(passInfo));
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnAnimBack()
|
|
{
|
|
// TODO: Add your command handler code here
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnAnimFastBack()
|
|
{
|
|
// TODO: Add your command handler code here
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnAnimFastForward()
|
|
{
|
|
// TODO: Add your command handler code here
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnAnimFront()
|
|
{
|
|
// TODO: Add your command handler code here
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnAnimPlay()
|
|
{
|
|
// TODO: Add your command handler code here
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::mouseDoubleClickEvent(QMouseEvent* event)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
|
|
CRenderViewport::mouseDoubleClickEvent(event);
|
|
if (event->button() != Qt::LeftButton)
|
|
{
|
|
return;
|
|
}
|
|
Matrix34 tm;
|
|
tm.SetIdentity();
|
|
SetViewTM(tm);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnLightColor([[maybe_unused]] IVariable* var)
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnShowNormals([[maybe_unused]] IVariable* var)
|
|
{
|
|
bool enable = mv_showNormals;
|
|
GetIEditor()->SetConsoleVar("r_ShowNormals", (enable) ? 1 : 0);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnShowTangents([[maybe_unused]] IVariable* var)
|
|
{
|
|
bool enable = mv_showTangents;
|
|
GetIEditor()->SetConsoleVar("r_ShowTangents", (enable) ? 1 : 0);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnCharPhysics([[maybe_unused]] IVariable* var)
|
|
{
|
|
bool enable = mv_useCharPhysics;
|
|
GetIEditor()->SetConsoleVar("ca_UsePhysics", enable);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnShowShaders([[maybe_unused]] IVariable* var)
|
|
{
|
|
bool bEnable = mv_showShaders;
|
|
GetIEditor()->SetConsoleVar("r_ProfileShaders", bEnable);
|
|
}
|
|
|
|
void CModelViewport::OnDestroy()
|
|
{
|
|
ReleaseObject();
|
|
if (m_pRESky)
|
|
{
|
|
m_pRESky->Release(false);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnActivate()
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnDeactivate()
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::Update()
|
|
{
|
|
FUNCTION_PROFILER(GetIEditor()->GetSystem(), PROFILE_EDITOR);
|
|
|
|
CRenderViewport::Update();
|
|
|
|
DrawInfo();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::DrawInfo() const
|
|
{
|
|
if (GetIEditor()->Get3DEngine())
|
|
{
|
|
ICVar* pDisplayInfo = gEnv->pConsole->GetCVar("r_DisplayInfo");
|
|
if (pDisplayInfo && pDisplayInfo->GetIVal() != 0)
|
|
{
|
|
const float fps = gEnv->pTimer->GetFrameRate();
|
|
const float x = (float)gEnv->pRenderer->GetWidth() - 5.0f;
|
|
|
|
gEnv->p3DEngine->DrawTextRightAligned(x, 1, "FPS: %.2f", fps);
|
|
|
|
int nPolygons, nShadowVolPolys;
|
|
gEnv->pRenderer->GetPolyCount(nPolygons, nShadowVolPolys);
|
|
int nDrawCalls = gEnv->pRenderer->GetCurrentNumberOfDrawCalls();
|
|
gEnv->p3DEngine->DrawTextRightAligned(x, 20, "Tris:%2d,%03d - DP:%d", nPolygons / 1000, nPolygons % 1000, nDrawCalls);
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CModelViewport::CanDrop([[maybe_unused]] const QPoint& point, IDataBaseItem* pItem)
|
|
{
|
|
if (!pItem)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::Drop([[maybe_unused]] const QPoint& point, [[maybe_unused]] IDataBaseItem* pItem)
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::Physicalize()
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::RePhysicalize()
|
|
{
|
|
Physicalize();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::SetPaused(bool bPaused)
|
|
{
|
|
//return;
|
|
if (m_bPaused != bPaused)
|
|
{
|
|
m_bPaused = bPaused;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::DrawModel(const SRenderingPassInfo& passInfo)
|
|
{
|
|
FUNCTION_PROFILER(GetIEditor()->GetSystem(), PROFILE_EDITOR);
|
|
|
|
m_vCamPos = GetCamera().GetPosition();
|
|
const QRect rc = contentsRect();
|
|
//GetISystem()->SetViewCamera( m_Camera );
|
|
IRenderAuxGeom* pAuxGeom = m_renderer->GetIRenderAuxGeom();
|
|
m_renderer->BeginSpawningGeneratingRendItemJobs(passInfo.ThreadID());
|
|
m_renderer->BeginSpawningShadowGeneratingRendItemJobs(passInfo.ThreadID());
|
|
m_renderer->EF_ClearSkinningDataPool();
|
|
m_renderer->EF_StartEf(passInfo);
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Draw lights.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
if (mv_lighting == true)
|
|
{
|
|
pAuxGeom->DrawSphere(m_VPLight.m_Origin, 0.2f, ColorB(255, 255, 0, 255));
|
|
}
|
|
|
|
gEnv->pConsole->GetCVar("ca_DrawWireframe")->Set(mv_showWireframe2);
|
|
gEnv->pConsole->GetCVar("ca_DrawTangents")->Set(mv_showTangents);
|
|
gEnv->pConsole->GetCVar("ca_DrawBinormals")->Set(mv_showBinormals);
|
|
gEnv->pConsole->GetCVar("ca_DrawNormals")->Set(mv_showNormals);
|
|
|
|
DrawLights(passInfo);
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//----- Render Static Object (handled by 3DEngine) ----
|
|
//-----------------------------------------------------------------------------
|
|
// calculate LOD
|
|
|
|
f32 fDistance = GetViewTM().GetTranslation().GetLength();
|
|
SRendParams rp;
|
|
rp.fDistance = fDistance;
|
|
|
|
Matrix34 tm;
|
|
tm.SetIdentity();
|
|
rp.pMatrix = &tm;
|
|
rp.pPrevMatrix = &tm;
|
|
|
|
Vec3 vAmbient;
|
|
mv_objectAmbientColor.Get(vAmbient);
|
|
|
|
rp.AmbientColor.r = vAmbient.x * mv_lightMultiplier;
|
|
rp.AmbientColor.g = vAmbient.y * mv_lightMultiplier;
|
|
rp.AmbientColor.b = vAmbient.z * mv_lightMultiplier;
|
|
rp.AmbientColor.a = 1;
|
|
|
|
rp.nDLightMask = 7;
|
|
if (mv_lighting == false)
|
|
{
|
|
rp.nDLightMask = 0;
|
|
}
|
|
|
|
rp.dwFObjFlags = 0;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//----- Render Static Object (handled by 3DEngine) ----
|
|
//-----------------------------------------------------------------------------
|
|
if (m_object)
|
|
{
|
|
m_object->Render(rp, passInfo);
|
|
if (mv_showGrid)
|
|
{
|
|
DrawFloorGrid(Quat(IDENTITY), Vec3(ZERO), Matrix33(IDENTITY));
|
|
}
|
|
|
|
if (mv_showBase)
|
|
{
|
|
DrawCoordSystem(IDENTITY, 10.0f);
|
|
}
|
|
}
|
|
|
|
m_renderer->EF_EndEf3D(SHDF_STREAM_SYNC, -1, -1, passInfo);
|
|
}
|
|
|
|
|
|
void CModelViewport::DrawLights(const SRenderingPassInfo& passInfo)
|
|
{
|
|
if (mv_animateLights)
|
|
{
|
|
m_LightRotationRadian += m_AverageFrameTime;
|
|
}
|
|
|
|
if (m_LightRotationRadian > gf_PI)
|
|
{
|
|
m_LightRotationRadian = -gf_PI;
|
|
}
|
|
|
|
Matrix33 LightRot33 = Matrix33::CreateRotationZ(m_LightRotationRadian);
|
|
|
|
Vec3 LPos0 = Vec3(-mv_lightOrbit, mv_lightOrbit, mv_lightOrbit);
|
|
m_VPLight.SetPosition(LightRot33 * LPos0 + m_PhysicalLocation.t);
|
|
Vec3 d = mv_lightDiffuseColor;
|
|
m_VPLight.SetLightColor(ColorF(d.x * mv_lightMultiplier, d.y * mv_lightMultiplier, d.z * mv_lightMultiplier, 0));
|
|
m_VPLight.SetSpecularMult(mv_lightSpecMultiplier);
|
|
m_VPLight.m_fRadius = mv_lightRadius;
|
|
m_VPLight.m_Flags = DLF_SUN | DLF_DIRECTIONAL;
|
|
|
|
if (mv_lighting == true)
|
|
{
|
|
m_renderer->EF_ADDDlight(&m_VPLight, passInfo);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::PlayAnimation([[maybe_unused]] const char* szName)
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::DrawFloorGrid(const Quat& m33, const Vec3& vPhysicalLocation, const Matrix33& rGridRot)
|
|
{
|
|
if (!m_renderer)
|
|
{
|
|
return;
|
|
}
|
|
|
|
float XR = 45;
|
|
float YR = 45;
|
|
|
|
|
|
|
|
|
|
|
|
IRenderAuxGeom* pAuxGeom = m_renderer->GetIRenderAuxGeom();
|
|
pAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags);
|
|
|
|
Vec3 axis = m33.GetColumn0();
|
|
|
|
Matrix33 SlopeMat33 = rGridRot;
|
|
uint32 GroundAlign = 1;
|
|
if (GroundAlign == 0)
|
|
{
|
|
SlopeMat33 = Matrix33::CreateRotationAA(m_absCurrentSlope, axis);
|
|
}
|
|
|
|
|
|
m_GridOrigin = Vec3(floorf(vPhysicalLocation.x), floorf(vPhysicalLocation.y), vPhysicalLocation.z);
|
|
|
|
|
|
Matrix33 ScaleMat33 = IDENTITY;
|
|
Vec3 rh = Matrix33::CreateRotationY(m_absCurrentSlope) * Vec3(1.0f, 0.0f, 0.0f);
|
|
if (rh.x)
|
|
{
|
|
Vec3 xback = SlopeMat33.GetRow(0);
|
|
Vec3 yback = SlopeMat33.GetRow(1);
|
|
f32 ratiox = 1.0f / Vec3(xback.x, xback.y, 0.0f).GetLength();
|
|
f32 ratioy = 1.0f / Vec3(yback.x, yback.y, 0.0f).GetLength();
|
|
|
|
f32 ratio = 1.0f / rh.x;
|
|
// Vec3 h=Vec3((m_GridOrigin.x-vPhysicalLocation.x)*ratiox,(m_GridOrigin.y-vPhysicalLocation.y)*ratioy,0.0f);
|
|
Vec3 h = Vec3(m_GridOrigin.x - vPhysicalLocation.x, m_GridOrigin.y - vPhysicalLocation.y, 0.0f);
|
|
Vec3 nh = SlopeMat33 * h;
|
|
m_GridOrigin.z += nh.z * ratio;
|
|
|
|
ScaleMat33 = Matrix33::CreateScale(Vec3(ratiox, ratioy, 0.0f));
|
|
|
|
// float color1[4] = {0,1,0,1};
|
|
// m_renderer->Draw2dLabel(12,g_ypos,1.6f,color1,false,"h: %f %f %f h.z: %f ratio: %f ratiox: %f ratioy: %f",h.x,h.y,h.z, nh.z,ratio,ratiox,ratioy);
|
|
// g_ypos+=18;
|
|
}
|
|
|
|
Matrix33 _m33;
|
|
_m33.SetIdentity();
|
|
AABB aabb1 = AABB(Vec3(-0.03f, -YR, -0.001f), Vec3(0.03f, YR, 0.001f));
|
|
OBB _obb1 = OBB::CreateOBBfromAABB(SlopeMat33, aabb1);
|
|
AABB aabb2 = AABB(Vec3(-XR, -0.03f, -0.001f), Vec3(XR, 0.03f, 0.001f));
|
|
OBB _obb2 = OBB::CreateOBBfromAABB(SlopeMat33, aabb2);
|
|
|
|
SlopeMat33 = SlopeMat33 * ScaleMat33;
|
|
// Draw grid.
|
|
float step = 0.25f;
|
|
for (float x = -XR; x < XR; x += step)
|
|
{
|
|
Vec3 p0 = Vec3(x, -YR, 0);
|
|
Vec3 p1 = Vec3(x, YR, 0);
|
|
//pAuxGeom->DrawLine( SlopeMat33*p0,RGBA8(0x7f,0x7f,0x7f,0x00), SlopeMat33*p1,RGBA8(0x7f,0x7f,0x7f,0x00) );
|
|
int32 intx = int32(x);
|
|
if (fabsf(intx - x) < 0.001f)
|
|
{
|
|
pAuxGeom->DrawOBB(_obb1, SlopeMat33 * Vec3(x, 0.0f, 0.0f) + m_GridOrigin, 1, RGBA8(0x9f, 0x9f, 0x9f, 0x00), eBBD_Faceted);
|
|
}
|
|
else
|
|
{
|
|
pAuxGeom->DrawLine(SlopeMat33 * p0 + m_GridOrigin, RGBA8(0x7f, 0x7f, 0x7f, 0x00), SlopeMat33 * p1 + m_GridOrigin, RGBA8(0x7f, 0x7f, 0x7f, 0x00));
|
|
}
|
|
}
|
|
|
|
for (float y = -YR; y < YR; y += step)
|
|
{
|
|
Vec3 p0 = Vec3(-XR, y, 0);
|
|
Vec3 p1 = Vec3(XR, y, 0);
|
|
// pAuxGeom->DrawLine( SlopeMat33*p0,RGBA8(0x7f,0x7f,0x7f,0x00), SlopeMat33*p1,RGBA8(0x7f,0x7f,0x7f,0x00) );
|
|
int32 inty = int32(y);
|
|
if (fabsf(inty - y) < 0.001f)
|
|
{
|
|
pAuxGeom->DrawOBB(_obb2, SlopeMat33 * Vec3(0.0f, y, 0.0f) + m_GridOrigin, 1, RGBA8(0x9f, 0x9f, 0x9f, 0x00), eBBD_Faceted);
|
|
}
|
|
else
|
|
{
|
|
pAuxGeom->DrawLine(SlopeMat33 * p0 + m_GridOrigin, RGBA8(0x7f, 0x7f, 0x7f, 0x00), SlopeMat33 * p1 + m_GridOrigin, RGBA8(0x7f, 0x7f, 0x7f, 0x00));
|
|
}
|
|
}
|
|
|
|
// TODO - the grid should probably be an IRenderNode at some point
|
|
// flushing grid geometry now so it will not override transparent
|
|
// objects later in the render pipeline.
|
|
pAuxGeom->Commit();
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
//--------------------------------------------------------------------------------------
|
|
//--------------------------------------------------------------------------------------
|
|
void CModelViewport::DrawCoordSystem(const QuatT& location, f32 length)
|
|
{
|
|
IRenderAuxGeom* pAuxGeom = m_renderer->GetIRenderAuxGeom();
|
|
SAuxGeomRenderFlags renderFlags(e_Def3DPublicRenderflags);
|
|
pAuxGeom->SetRenderFlags(renderFlags);
|
|
|
|
Vec3 absAxisX = location.q.GetColumn0();
|
|
Vec3 absAxisY = location.q.GetColumn1();
|
|
Vec3 absAxisZ = location.q.GetColumn2();
|
|
|
|
const f32 scale = 3.0f;
|
|
const f32 size = 0.009f;
|
|
AABB xaabb = AABB(Vec3(-length * scale, -size * scale, -size * scale), Vec3(length * scale, size * scale, size * scale));
|
|
AABB yaabb = AABB(Vec3(-size * scale, -length * scale, -size * scale), Vec3(size * scale, length * scale, size * scale));
|
|
AABB zaabb = AABB(Vec3(-size * scale, -size * scale, -length * scale), Vec3(size * scale, size * scale, length * scale));
|
|
|
|
OBB obb;
|
|
obb = OBB::CreateOBBfromAABB(Matrix33(location.q), xaabb);
|
|
pAuxGeom->DrawOBB(obb, location.t, 1, RGBA8(0xff, 0x00, 0x00, 0xff), eBBD_Extremes_Color_Encoded);
|
|
pAuxGeom->DrawCone(location.t + absAxisX * length * scale, absAxisX, 0.03f * scale, 0.15f * scale, RGBA8(0xff, 0x00, 0x00, 0xff));
|
|
|
|
obb = OBB::CreateOBBfromAABB(Matrix33(location.q), yaabb);
|
|
pAuxGeom->DrawOBB(obb, location.t, 1, RGBA8(0x00, 0xff, 0x00, 0xff), eBBD_Extremes_Color_Encoded);
|
|
pAuxGeom->DrawCone(location.t + absAxisY * length * scale, absAxisY, 0.03f * scale, 0.15f * scale, RGBA8(0x00, 0xff, 0x00, 0xff));
|
|
|
|
obb = OBB::CreateOBBfromAABB(Matrix33(location.q), zaabb);
|
|
pAuxGeom->DrawOBB(obb, location.t, 1, RGBA8(0x00, 0x00, 0xff, 0xff), eBBD_Extremes_Color_Encoded);
|
|
pAuxGeom->DrawCone(location.t + absAxisZ * length * scale, absAxisZ, 0.03f * scale, 0.15f * scale, RGBA8(0x00, 0x00, 0xff, 0xff));
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::OnLightMultiplier([[maybe_unused]] IVariable* var)
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CModelViewport::SetSelected(bool const bSelect)
|
|
{
|
|
// If a modelviewport gets activated, and listeners will be activated, disable the main viewport listener and re-enable when you lose focus.
|
|
if (gEnv->pSystem)
|
|
{
|
|
IViewSystem* const pIViewSystem = gEnv->pSystem->GetIViewSystem();
|
|
|
|
if (pIViewSystem)
|
|
{
|
|
pIViewSystem->SetControlAudioListeners(!bSelect);
|
|
}
|
|
}
|
|
}
|
|
|
|
#include <moc_ModelViewport.cpp>
|