// RenderViewport.cpp : implementation file // #include "stdafx.h" #include "ModelViewport.h" #include "Controls\AnimationToolBar.h" #include "ModelViewPanel.h" #include "ModelViewSubmeshPanel.h" #include "PropertiesPanel.h" #include "ICryAnimation.h" #include "ThumbnailGenerator.h" #include "GameEngine.h" #include "CryCharMorphParams.h" #include "CryCharAnimationParams.h" #include "FileTypeUtils.h" #include "CryCharFxTrailParams.h" ///#include //#include #include //#include #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNCREATE(CModelViewport,CRenderViewport) #define SKYBOX_NAME "InfoRedGal" namespace { int s_varsPanelId = 0; CPropertiesPanel* s_varsPanel = 0; } ///////////////////////////////////////////////////////////////////////////// // CModelViewport CModelViewport::CModelViewport() { m_camera.Init( 800,600,3.14f/4.0f ); m_camera.SetZMin( 0.01f ); m_camera.SetZMax( 10000 ); //m_camera.SetPos( Vec3d(1262,743,25) ); m_camera.SetPos( Vec3d(0,0,0) ); m_camera.SetAngle( Vec3d(0,0,0) ); m_bInRotateMode = false; m_bInMoveMode = false; m_camTarget(0,0,0); m_bNavigateBuilding = false; m_rollupIndex = 0; m_rollupIndex2 = 0; m_object = 0; m_character = 0; m_weaponModel = 0; m_attachedCharacter = 0; m_modelPanel = 0; m_modelSubmeshPanel = 0; m_camRadius = 10; m_moveSpeed = 0.1f; m_currTime = 0; m_objectAngles.Set(0,0,0); m_pRESky = 0; m_pSkyboxName = 0; m_pSkyBoxShader = NULL; m_attachBone = "weapon_bone"; m_viewerPos.Set(0,0,0); m_viewerAngles.Set(0,0,0); // Init variable. mv_lighting = true; mv_lightDiffuseColor = Vec3(1,1,1); mv_lightSpecularColor = Vec3(1,1,1); mv_objectAmbientColor = Vec3(0.5,0.5,0.5); mv_backgroundColor = Vec3(0.5,0.5,0.5); mv_fov = 90; m_currLightDiffuseColor.Set(1,1,1); m_currLightSpecularColor.Set(1,1,1); // Create first light. CDLight *l = new CDLight; l->m_Origin = Vec3(10,10,10); l->m_Color = m_currLightDiffuseColor; l->m_SpecColor = m_currLightSpecularColor; l->m_fRadius = 100; l->m_fStartRadius = 1; l->m_fEndRadius = 100; l->m_Flags |= DLF_POINT; m_lights.push_back( l ); // Register variables. m_vars.AddVariable( mv_wireframe,_T("Wireframe") ); m_vars.AddVariable( mv_showGrid,_T("Grid") ); m_vars.AddVariable( mv_lighting,_T("Lighting") ); m_vars.AddVariable( mv_animateLights,_T("AnimLights") ); m_vars.AddVariable( mv_2LightSources,"TwoLights",_T("2 Lights"),functor(*this,&CModelViewport::On2Lights) ); m_vars.AddVariable( mv_objectAmbientColor,_T("ObjectAmbient"),functor(*this,&CModelViewport::OnLightColor),IVariable::DT_COLOR ); m_vars.AddVariable( mv_lightDiffuseColor,_T("LightDiffuse"),functor(*this,&CModelViewport::OnLightColor),IVariable::DT_COLOR ); m_vars.AddVariable( mv_lightSpecularColor,_T("LightSpecular"),functor(*this,&CModelViewport::OnLightColor),IVariable::DT_COLOR ); m_vars.AddVariable( mv_backgroundColor,_T("BackgroundColor"),functor(*this,&CModelViewport::OnLightColor),IVariable::DT_COLOR ); m_vars.AddVariable( mv_showShaders,_T("ShowShaders"),functor(*this,&CModelViewport::OnShowShaders) ); m_vars.AddVariable( mv_showSkyBox,_T("ShowSkyBox") ); m_vars.AddVariable( mv_showNormals,_T("ShowNormals"),functor(*this,&CModelViewport::OnShowNormals) ); m_vars.AddVariable( mv_showTangents,_T("ShowTangents"),functor(*this,&CModelViewport::OnShowTangents) ); m_vars.AddVariable( mv_showShadowVolumes,_T("ShowShadowVolumes"),functor(*this,&CModelViewport::OnShowShadowVolumes) ); m_vars.AddVariable( mv_showTextureUsage,_T("ShowTextureUsage"),functor(*this,&CModelViewport::OnShowTextureUsage) ); m_vars.AddVariable( mv_showAllTextures,_T("ShowAllTextures"),functor(*this,&CModelViewport::OnShowAllTextures) ); m_vars.AddVariable( mv_disableLod,"NoLod",_T("No LOD") ); m_vars.AddVariable( mv_disableVisibility,_T("DisableVisibilty"),functor(*this,&CModelViewport::OnDisableVisibility) ); m_vars.AddVariable( mv_fov,_T("FOV") ); } CModelViewport::~CModelViewport() { for (int i = 0; i < m_lights.size(); i++) delete m_lights[i]; // Save values to registry. XmlNodeRef node = new CXmlNode("Vars"); m_vars.Serialize( node,false ); AfxGetApp()->WriteProfileString( "PreviewSettings","Vars",node->getXML() ); } BEGIN_MESSAGE_MAP(CModelViewport, CRenderViewport) ON_WM_CREATE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_MBUTTONDOWN() ON_WM_MBUTTONUP() ON_WM_MOUSEMOVE() ON_WM_RBUTTONDOWN() ON_WM_RBUTTONUP() ON_WM_MOUSEWHEEL() ON_COMMAND(ID_ANIM_BACK, OnAnimBack) ON_COMMAND(ID_ANIM_FAST_BACK, OnAnimFastBack) ON_COMMAND(ID_ANIM_FAST_FORWARD, OnAnimFastForward) ON_COMMAND(ID_ANIM_FRONT, OnAnimFront) ON_COMMAND(ID_ANIM_PLAY, OnAnimPlay) ON_WM_LBUTTONDBLCLK() ON_WM_KEYDOWN() ON_WM_DESTROY() END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CModelViewport message handlers int CModelViewport::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CRenderViewport::OnCreate(lpCreateStruct) == -1) return -1; GetIEditor()->GetGameEngine()->SetLevelLoaded( true ); if (m_renderer) { m_pRESky = (CRESky*)m_renderer->EF_CreateRE(eDATA_Sky); m_pRESky->m_fAlpha = 1.0f; m_pSkyboxName = GetIEditor()->GetSystem()->GetIConsole()->CreateVariable("ed_skyboxname","InfRedGal",0 ); m_pSkyBoxShader = m_renderer->EF_LoadShader(m_pSkyboxName->GetString(), eSH_World, EF_SYSTEM); } // Serialize variables from registry. CString xml = AfxGetApp()->GetProfileString( "PreviewSettings","Vars" ); if (!xml.IsEmpty()) { XmlParser parser; XmlNodeRef node = parser.parseBuffer( xml ); if (node) { m_vars.Serialize( node,true ); } } return 0; } ////////////////////////////////////////////////////////////////////////// void CModelViewport::ReleaseObject() { if (m_object) { m_engine->ReleaseObject( m_object ); m_object = 0; } if (m_character) { m_pAnimationSystem->RemoveCharacter( m_character ); m_character = 0; } if (m_weaponModel) { m_engine->ReleaseObject( m_weaponModel ); m_weaponModel = NULL; } if (m_attachedCharacter) { m_pAnimationSystem->RemoveCharacter(m_attachedCharacter); m_attachedCharacter = NULL; } } ////////////////////////////////////////////////////////////////////////// void CModelViewport::LoadObject( const CString &fileName,float scale ) { // Enable displaying of labels. GetIEditor()->SetConsoleVar( "r_DisplayInfo",1 ); m_bNavigateBuilding = false; // Load object. char dir[1024]; GetCurrentDirectory( 1024,dir ); CString file = fileName; CString fileLo = file; fileLo.MakeLower(); char *ldir = strlwr( dir ); if (fileLo.Find(ldir)==0) file.Delete( 0,strlen(dir)+1 ); bool reload = false; if (m_loadedFile == file) reload = true; m_loadedFile = file; SetName( CString("Model View - ") + file ); ReleaseObject(); // Do not reload textures. //if (m_renderer) //m_renderer->FreeResources(FRR_SHADERS|FRR_TEXTURES|FRR_RESTORE); if (!m_modelPanel) { m_modelPanel = new ModelViewPanel(this,this); m_rollupIndex = GetIEditor()->AddRollUpPage( ROLLUP_OBJECTS,"Model View",m_modelPanel ); } if (m_modelPanel) { m_modelPanel->SetFileName( fileName ); } if (!s_varsPanel) { // Regidet variable pannel. s_varsPanel = new CPropertiesPanel(this); s_varsPanel->AddVars( m_vars.GetVarBlock() ); s_varsPanelId = GetIEditor()->AddRollUpPage( ROLLUP_OBJECTS,"Properties",s_varsPanel ); } if (IsPreviewableFileType(file)) { // Try Load character. m_character = m_pAnimationSystem->MakeCharacter( file ); if (m_character) { if (m_character->NumSubmeshes()) { #if 1 int nBone = m_character->GetModel()->GetBoneByName("Bip01 L Hand"); m_character->NewFxTrail(0, CryCharFxTrailParams (nBone, m_renderer->LoadTexture("Textures\\guncloud.dds"), 0.3f, Vec3d(0,0,0), Vec3d(1,0,0), 500)); nBone = m_character->GetModel()->GetBoneByName("Bip01 R Hand"); m_character->NewFxTrail(1, CryCharFxTrailParams (nBone, m_renderer->LoadTexture("Textures\\haze_mask.dds"), 0.3f, Vec3d(0,0,0), Vec3d(1,0,0), 500)); #endif if (!m_modelSubmeshPanel) { m_modelSubmeshPanel = new ModelViewSubmeshPanel(this,this); m_rollupIndex2 = GetIEditor()->AddRollUpPage( ROLLUP_OBJECTS,"Body Parts",m_modelSubmeshPanel ); } else m_modelSubmeshPanel->ReinitSubmeshes(); } if (m_attachedCharacter) m_character->AttachObjectToBone(m_attachedCharacter, m_attachBone, false); if (m_weaponModel) m_character->AttachObjectToBone( m_weaponModel,m_attachBone,false ); // Generate thumbnail for this cgf. CThumbnailGenerator thumbGen; thumbGen.GenerateForFile( file ); if (m_modelPanel && m_character) { SetCharacterUIInfo(); } float radius = m_character->GetRadius(); Vec3d center = m_character->GetCenter(); if (!reload) m_camTarget = center; m_bboxMin = center-Vec3d(radius,radius,radius); m_bboxMax = center+Vec3d(radius,radius,radius); if (!reload) m_camRadius = center.z + radius; } else { LoadStaticObject( file ); } } else { MessageBox( "Preview of this file type not supported","Preview Error",MB_OK|MB_ICONEXCLAMATION ); return; } if (!reload) { m_objectAngles.Set(0,0,0); Vec3d v = m_bboxMax - m_bboxMin; float radius = v.Length()/2.0f; //m_camTarget = (m_bboxMax + m_bboxMin) * 0.5f; m_camTarget(0,0,0); //m_camTarget.x = m_camTarget.y = 0; //m_camTarget.Set( 0,0,2 ); m_camRadius = radius*2; m_camAngles(0,0,0); m_camera.SetPos( Vec3d(0,m_camRadius,0) ); m_camera.SetAngle( Vec3d(0,0,0) ); SetCamera( m_camera ); } GetIEditor()->SetConsoleVar( "r_DisplayInfo",1 ); } ////////////////////////////////////////////////////////////////////////// void CModelViewport::LoadStaticObject(const CString &file ) { // Load Static object. m_object = m_engine->MakeObject( file,NULL,evs_ShareAndSortForCache ); if(!m_object) { CLogFile::WriteLine( "Loading of object failed." ); return; } // Generate thumbnail for this cgf. CThumbnailGenerator thumbGen; thumbGen.GenerateForFile( file ); m_bboxMin = m_object->GetBoxMin(); m_bboxMax = m_object->GetBoxMax(); Vec3 pos; Matrix44 HelperMat; for (int i = 0; i < 1000; i++) { const char *helperName = m_object->GetHelperById( i,pos,&HelperMat ); if (!helperName) break; if (strnicmp(helperName,"camera",strlen("camera")) == 0) { // reload = true; Vec3d v = m_bboxMax - m_bboxMin; float radius = v.Length()/2.0f; m_camTarget(0,0,0); m_camera.SetPos( pos ); m_camRadius = pos.Length(); // rot.Normilize(); // m_camAngles = rot.GetEulerAngles(); //m_camAngles.x *= 180.0f/PI; //m_camAngles.y *= 180.0f/PI; //m_camAngles.z *= 180.0f/PI; assert(0); // not tested !!! AffineParts affineParts; affineParts.SpectralDecompose(HelperMat); m_camAngles = RAD2DEG(Ang3::GetAnglesXYZ(Matrix33(affineParts.rot))); /* Matrix m1; Matrix m2; m2.Identity(); rot.GetMatrix(m1); Vec3d angles=m_camAngles; m2.Rotate(angles); */ m_camera.SetAngle( m_camAngles ); SetCamera( m_camera ); } } } ////////////////////////////////////////////////////////////////////////// void CModelViewport::SetCharacterUIInfo() { int i; // Fill the combo box with the name of the animation sequences m_modelPanel->ClearAnims(); // [Sergiy] Add all animations to the animation list box/view IAnimationSet* pAnimations = m_character->GetModel()->GetAnimationSet(); if (!pAnimations) return; // mapping name->length of animation typedef std::map AnimMap; AnimMap mapAnims; int numAnimations = pAnimations->Count(); for (i = 0; i < numAnimations; ++i) { // the length of the animation is passed in seconds mapAnims.insert(AnimMap::value_type(pAnimations->GetName(i),pAnimations->GetLength(i))); } // now fill all the morph targets of subskins in for (i = 1; i < m_character->NumSubmeshes(); ++i) { ICryCharSubmesh* pSubmesh = m_character->GetSubmesh(i); if (!pSubmesh) continue; IAnimationSet* pAnimations = pSubmesh->GetModel()->GetAnimationSet(); if (!pAnimations) continue; for (unsigned j = 0; j < pAnimations->CountMorphTargets(); ++j) mapAnims.insert (AnimMap::value_type(pAnimations->GetNameMorphTarget(i), 0)); } for (AnimMap::const_iterator it = mapAnims.begin(); it != mapAnims.end(); ++it) m_modelPanel->AddAnimName (it->first, it->second); // Fill the bone list m_modelPanel->ClearBones(); ICryCharModel *pCharModel = m_character->GetModel(); int numBones = pCharModel->NumBones(); for (i = 0; i < numBones; i++) { const char *str = pCharModel->GetBoneName(i); if (str == NULL) break; if (strlen(str) > 0) m_modelPanel->AddBone(str); } m_modelPanel->SelectBone( m_attachBone ); } ////////////////////////////////////////////////////////////////////////// void CModelViewport::OnLButtonDown(UINT nFlags, CPoint point) { if (m_bNavigateBuilding) { CRenderViewport::OnLButtonDown(nFlags,point); return; } m_bInRotateMode = true; m_mousePos = point; if (!m_bInMoveMode) SetCapture(); } void CModelViewport::OnLButtonUp(UINT nFlags, CPoint point) { if (m_bNavigateBuilding) { CRenderViewport::OnLButtonUp(nFlags,point); return; } m_bInRotateMode = false; if (!m_bInMoveMode) ReleaseCapture(); } void CModelViewport::OnMButtonDown(UINT nFlags, CPoint point) { if (m_bNavigateBuilding) { CRenderViewport::OnMButtonDown(nFlags,point); return; } m_bInRotateMode = true; m_bInMoveMode = true; m_mousePos = point; //if (!m_bInMoveMode) SetCapture(); } void CModelViewport::OnMButtonUp(UINT nFlags, CPoint point) { if (m_bNavigateBuilding) { CRenderViewport::OnMButtonUp(nFlags,point); return; } m_bInRotateMode = false; m_bInMoveMode = false; ReleaseCapture(); } void CModelViewport::OnMouseMove(UINT nFlags, CPoint point) { if (m_bNavigateBuilding) { CRenderViewport::OnMouseMove(nFlags,point); return; } bool bCtrl = nFlags & MK_CONTROL; // TODO: Add your message handler code here and/or call default CViewport::OnMouseMove(nFlags, point); if (point == m_mousePos) return; if (m_bInRotateMode && m_bInMoveMode) { // Zoom. Matrix44 m = m_camera.GetVCMatrixD3D9(); //Vec3d xdir(m[0][0],m[1][0],m[2][0]); Vec3d xdir(0,0,0); //xdir.Normalize(); Vec3d zdir(m[0][2],m[1][2],m[2][2]); zdir.Normalize(); float step = 0.002f; float dx = (point.x-m_mousePos.x); float dy = (point.y-m_mousePos.y); // dx = pow(dx,1.05f ); //dy = pow(dy,1.05f ); //m_camera.SetPos( m_camera.GetPos() + ydir*(m_mousePos.y-point.y),xdir*(m_mousePos.x-point.x) ); m_camera.SetPos( m_camera.GetPos() + step*xdir*dx + step*zdir*dy ); SetCamera( m_camera ); CPoint pnt = m_mousePos; ClientToScreen( &pnt ); SetCursorPos( pnt.x,pnt.y ); } else if (m_bInRotateMode) { Vec3d angles( point.y-m_mousePos.y,0,-point.x+m_mousePos.x ); // Look if (bCtrl) { Vec3d angles( point.y-m_mousePos.y,0,-point.x+m_mousePos.x ); m_objectAngles += angles; } else { Vec3d angles( point.y-m_mousePos.y,0,-point.x+m_mousePos.x ); //m_camera.SetAngle( m_camera.GetAngles() + angles*0.2f ); m_camAngles += angles; SetOrbitAngles( m_camAngles ); } CPoint pnt = m_mousePos; ClientToScreen( &pnt ); SetCursorPos( pnt.x,pnt.y ); } else if (m_bInMoveMode) { // Slide. Matrix44 m = m_camera.GetVCMatrixD3D9(); Vec3d xdir(m[0][0],m[1][0],m[2][0]); Vec3d ydir(m[0][1],m[1][1],m[2][1]); xdir.Normalize(); ydir.Normalize(); float dist = (m_camera.GetPos() - m_camTarget).Length(); float step = 0.001f; float dx = (point.x-m_mousePos.x); float dy = (point.y-m_mousePos.y); //dx = pow( dx,1.2f ); //dy = pow( dy,1.2f ); //m_camera.SetPos( m_camera.GetPos() + ydir*(m_mousePos.y-point.y),xdir*(m_mousePos.x-point.x) ); m_camera.SetPos( m_camera.GetPos() - step*xdir*dx + step*ydir*dy ); SetCamera( m_camera ); // Calc camera target. Vec3d angles = m_camAngles; angles=ConvertToRad(angles); //Matrix tm; tm.Identity(); //tm.Rotate(angles); Matrix44 tm=ViewMatrix(angles); Vec3d v(0,0,dist); v = m_camera.GetPos() - tm*v; m_camTarget = v; m_mousePos = point; } } void CModelViewport::OnRButtonDown(UINT nFlags, CPoint point) { if (m_bNavigateBuilding) { CRenderViewport::OnRButtonDown(nFlags,point); return; } m_bInMoveMode = true; m_mousePos = point; if (!m_bInRotateMode) SetCapture(); } void CModelViewport::OnRButtonUp(UINT nFlags, CPoint point) { if (m_bNavigateBuilding) { CRenderViewport::OnRButtonUp(nFlags,point); return; } m_bInMoveMode = false; m_mousePos = point; if (!m_bInRotateMode) ReleaseCapture(); } BOOL CModelViewport::OnMouseWheel(UINT nFlags, short zDelta, CPoint point) { if (m_bNavigateBuilding) { return CRenderViewport::OnMouseWheel(nFlags,zDelta,point); } // TODO: Add your message handler code here and/or call default Matrix44 m = m_camera.GetVCMatrixD3D9(); Vec3d zdir(m[0][2],m[1][2],m[2][2]); zdir.Normalize(); //m_camera.SetPos( m_camera.GetPos() + ydir*(m_mousePos.y-point.y),xdir*(m_mousePos.x-point.x) ); m_camera.SetPos( m_camera.GetPos() + 0.002f*zdir*(zDelta) ); SetCamera( m_camera ); return TRUE; } void CModelViewport::OnRender() { ProcessKeys(); if (m_renderer) { m_camera.SetPos( GetViewerPos() ); m_camera.SetAngle( GetViewerAngles() ); m_camera.SetZMin( 0.0101f ); m_camera.SetZMax( 10000 ); int w = m_rcClient.right - m_rcClient.left; int h = m_rcClient.bottom - m_rcClient.top; float fAspectRatio = (float)h/(float)w; if (fAspectRatio > 1.6f) fAspectRatio = 1.6f; m_camera.Init( w,h,DEG2RAD(mv_fov),m_camera.GetZMax(),fAspectRatio ); m_camera.Update(); Vec3 clearColor = mv_backgroundColor; m_renderer->SetClearColor( clearColor ); m_renderer->SetCamera( m_camera ); m_renderer->ClearColorBuffer( clearColor ); m_renderer->ClearDepthBuffer(); m_renderer->ResetToDefault(); // Render object. //GetIEditor()->GetSystem()->GetIConsole()->GetCVar("r_ShowLines")->Set( 1.0f ); if (mv_wireframe) { m_renderer->SetPolygonMode(R_WIREFRAME_MODE); DrawModel(); } else { m_renderer->SetPolygonMode(R_SOLID_MODE); DrawModel(); } } if (!m_object && !m_character) { LoadObject( "Objects\\box.cgf",1 ); } } void CModelViewport::DrawModel() { m_renderer->EF_StartEf(); if (mv_showSkyBox) DrawSkyBox(); if (mv_showGrid) DrawGrid(); if (mv_animateLights) { m_currTime += GetIEditor()->GetSystem()->GetITimer()->GetFrameTime()*1.5f; float t = m_currTime; float orbit = 5; ///Vec3 lp( Vec3(sin(t)*orbit,cos(t*1.5f)*orbit,sin(t*0.2f)*orbit) ); //Vec3 lp( Vec3(sin(t)*orbit,cos(t)*orbit,sin(t*0.2f)*orbit) ); Vec3 lp = Vec3( Vec3(sin(t)*orbit,cos(t)*orbit,orbit) ); m_lights[0]->m_Origin = lp; //m_lights[1]->m_Origin = Vec3(cos(t*1.5)*orbit,-sin(t)*orbit,-cos(t*0.3f)*orbit); if (m_lights.size() > 1) { orbit = 100; lp = Vec3( Vec3(sin(t*0.9)*orbit,cos(t*0.7)*orbit,orbit) ); m_lights[1]->m_Origin = -lp; } } if (mv_lighting == true) { // Add lights. for (int i = 0; i < m_lights.size(); i++) { if (!m_lights[i]) continue; m_renderer->EF_ADDDlight( m_lights[i] ); m_renderer->SetMaterialColor( 1,1,0,1 ); } } if (m_object) { SRendParams rp; rp.vPos = Vec3(0,0,0); rp.vAngles = m_objectAngles; //changed by IVO //rp.vAmbientColor = mv_objectAmbientColor.; mv_objectAmbientColor.Get(rp.vAmbientColor); if (mv_lighting == true) rp.nDLightMask = 0xFFFF; else rp.nDLightMask = 0; //changed by IVO //rp.vAmbientColor = mv_objectAmbientColor; mv_objectAmbientColor.Get(rp.vAmbientColor); rp.dwFObjFlags = FOB_IGNOREMATERIALAMBIENT; rp.dwFObjFlags |= FOB_TRANS_MASK; // calculate LOD float fDistance = m_camera.GetPos().Length(); if (mv_disableLod) fDistance = 0; // int nLod = (int)(fDistance/(4*m_object->GetRadius())); int nLod = max(0,(int)(fDistance/(10.f*m_object->GetRadius()))); // enable rendering of all attached lsources as local lsources for(int i=0; m_object->GetLightSources(i); i++) ((CDLight*)m_object->GetLightSources(i))->m_Flags |= DLF_LOCAL; // render m_object->Render( rp, Vec3(zero), nLod ); } if (m_character) { float fDistance = m_camera.GetPos().Length(); if (mv_disableLod) fDistance = 0; m_character->Update(); SRendParams rp; rp.vPos.Set(0,0,0); rp.vAngles = m_objectAngles; rp.fDistance = fDistance; rp.nDLightMask = 0xFFFFFFFF; //changed by ivo IVO //rp.vAmbientColor = mv_objectAmbientColor; mv_objectAmbientColor.Get(rp.vAmbientColor); rp.dwFObjFlags = FOB_IGNOREMATERIALAMBIENT; rp.dwFObjFlags |= FOB_TRANS_MASK; // enable rendering of all attached lsources as local lsources for(int i=0; m_character->GetBoundLight(i); i++) ((CDLight*)m_character->GetBoundLight(i))->m_Flags |= DLF_LOCAL; m_character->Draw( rp,Vec3(zero) ); } m_renderer->EF_EndEf3D(SHDF_SORT); if(GetIEditor()->Get3DEngine()) { float nTextPosX=101-20, nTextPosY=-2, nTextStepY=3; GetIEditor()->Get3DEngine()->DisplayInfo(nTextPosX, nTextPosY, nTextStepY); } m_renderer->EF_ClearLightsList(); ////////////////////////////////////////////////////////////////////////// // Draw lights. ////////////////////////////////////////////////////////////////////////// if (mv_lighting == true) { for (int i = 0; i < m_lights.size(); i++) { if (!m_lights[i]) continue; m_renderer->SetMaterialColor( 1,1,0,1 ); m_renderer->DrawBall( m_lights[i]->m_Origin,0.2f ); } } } ////////////////////////////////////////////////////////////////////////// void CModelViewport::DrawSkyBox() { CCObject * pObj = m_renderer->EF_GetObject(true, -1); pObj->m_Matrix.SetTranslationMat(m_camera.GetPos()); if (m_pSkyboxName) { m_renderer->EF_AddEf(0, m_pRESky, m_pSkyBoxShader, NULL, pObj, 0, NULL,EFSLIST_PREPROCESS); } } ////////////////////////////////////////////////////////////////////////// void CModelViewport::DrawGrid() { if (!m_renderer) return; //m_renderer->SetBlendMode(); //m_renderer->EnableBlend( false ); m_renderer->SetState(GS_DEPTHWRITE); float XR = 5; float YR = 5; m_renderer->SetMaterialColor( 0.6f,0.6f,0.6f,0.3f ); // Draw grid. float step = 0.1f; for (float x = -XR; x < XR; x+=step) { if (fabs(x) > 0.01) m_renderer->DrawLine( Vec3d(x,-YR,0),Vec3d(x,YR,0) ); } for (float y = -YR; y < YR; y+=step) { if (fabs(y) > 0.01) m_renderer->DrawLine( Vec3d(-XR,y,0),Vec3d(XR,y,0) ); } // Draw axis. m_renderer->SetMaterialColor( 1,0,0,0.3f ); m_renderer->DrawLine( Vec3d(-XR,0,0),Vec3d(XR,0,0) ); m_renderer->SetMaterialColor( 0,1,0,0.3f ); m_renderer->DrawLine( Vec3d(0,-YR,0),Vec3d(0,YR,0) ); m_renderer->SetMaterialColor( 0,0,1,0.3f ); m_renderer->DrawLine( Vec3d(0,0,-YR),Vec3d(0,0,YR) ); //m_renderer->EnableBlend( false ); //m_renderer->DrawLine( Vec3d(-m_bboxMin.x,y,0),Vec3d(XR,y,0) ); } void CModelViewport::SetOrbitAngles( const Vec3d &ang ) { float dist = (m_camera.GetPos() - m_camTarget).Length(); Vec3d cangles = ang; Vec3d v(0,0,dist); cangles=ConvertToRad(cangles); // Matrix44 tm; tm.Identity(); // tm.Rotate(cangles); Matrix44 tm=ViewMatrix(cangles); v = tm*v; m_camera.SetPos( v + m_camTarget ); m_camera.SetAngle( m_camAngles ); SetCamera( m_camera ); } 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 if (m_modelPanel && m_character) { // the name of the currently selected animation CString strAnimName = m_modelPanel->GetCurrAnimName(); // the interface to the set of animations ICryAnimationSet* pAnimations = m_character->GetModel()->GetAnimationSet(); int numAnimations = pAnimations->Count(); // Find its animation data. for (int i=0; i < numAnimations; i++) { if (stricmp(strAnimName,pAnimations->GetName(i)) == 0) { pAnimations->SetLoop(i, m_modelPanel->GetLooped()); break; } } StartAnimation (strAnimName); } } void CModelViewport::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CRenderViewport::OnLButtonDblClk(nFlags, point); m_camTarget(0,0,0); SetOrbitAngles( m_camAngles ); } void CModelViewport::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { if (m_character) { int index = -1; if (nChar >= 0x30 && nChar <= 0x39) { if (nChar == 0x30) index = 10; else index = nChar - 0x31; } if (nChar >= VK_NUMPAD0 && nChar <= VK_NUMPAD9) { index = nChar - VK_NUMPAD0 + 10; if (nChar == VK_NUMPAD0) index = 20; } //if (nFlags& MK_CONTROL IAnimationSet* pAnimations = m_character->GetModel()->GetAnimationSet(); if (pAnimations) { int numAnimations = pAnimations->Count(); if (index >= 0 && index < numAnimations) { const char *animName = pAnimations->GetName(index); StartAnimation (animName); } } } CRenderViewport::OnKeyDown(nChar, nRepCnt, nFlags); } void CModelViewport::StartAnimation (const char*szName) { if (m_modelPanel) { int layer = m_modelPanel->GetLayer(); float fBlendInTime = m_modelPanel->GetBlendInTime(); float fBlendOutTime = m_modelPanel->GetBlendOutTime(); bool bSyncPhase = m_modelPanel->GetSynchronizePhase(); if (szName[0] == '#') { CryCharMorphParams Params(fBlendInTime, (fBlendInTime+fBlendOutTime)/2, fBlendOutTime); Params.nFlags |= Params.FLAGS_RECURSIVE; m_character->StartMorph (szName, Params); } else { CryCharAnimationParams Params (fBlendInTime, fBlendOutTime,layer ); if (bSyncPhase) Params.nFlags |= Params.FLAGS_SYNCHRONIZE_WITH_LAYER_0; Params.nFlags |= Params.FLAGS_RECURSIVE; m_character->StartAnimation ( szName,Params); } } else { // use the defaults in the interface instead of Editor's defaults m_character->StartAnimation(szName, CryCharAnimationParams()); } } ////////////////////////////////////////////////////////////////////////// void CModelViewport::On2Lights( IVariable *var ) { if (mv_2LightSources) { CDLight *l = new CDLight; l->m_Origin = Vec3(-100,-100,-100); l->m_Color = m_currLightDiffuseColor; //l->m_AmbColor.r = 0; l->m_AmbColor.g = 0; l->m_AmbColor.b = 0; l->m_AmbColor.a = 0; l->m_SpecColor = m_currLightSpecularColor; l->m_fRadius = 1000; l->m_fStartRadius = 1; l->m_fEndRadius = 1000; l->m_Flags |= DLF_POINT; m_lights.resize(2); m_lights[1] = l; } else { m_lights.resize(1); } } ////////////////////////////////////////////////////////////////////////// void CModelViewport::OnShowNormals( IVariable *var ) { bool enable = mv_showNormals; GetIEditor()->SetConsoleVar( "r_ShowNormals",(enable)?1:0 ); } ////////////////////////////////////////////////////////////////////////// void CModelViewport::OnShowTangents( IVariable *var ) { bool enable = mv_showTangents; GetIEditor()->SetConsoleVar( "r_ShowTangents",(enable)?1:0 ); } ////////////////////////////////////////////////////////////////////////// void CModelViewport::OnShowShadowVolumes( IVariable *var ) { bool enable = mv_showShadowVolumes; GetIEditor()->SetConsoleVar( "CV_ind_VisualizeShadowVolumes",(enable)?1:0 ); } ////////////////////////////////////////////////////////////////////////// void CModelViewport::OnShowTextureUsage( IVariable *var ) { bool enable = mv_showTextureUsage; GetIEditor()->SetConsoleVar( "r_LogUsedTextures",(enable)?2:0 ); } ////////////////////////////////////////////////////////////////////////// void CModelViewport::OnShowAllTextures( IVariable *var ) { bool enable = mv_showAllTextures; GetIEditor()->SetConsoleVar( "r_LogUsedTextures",(enable)?4:0 ); } bool CModelViewport::AddSubmesh (const CString& model) { ICryCharModel* pModel = m_pAnimationSystem->LoadModel(model); if (!pModel) { AfxMessageBox("Cannot open model " + model + "\nSee the log for details"); return false; } ICryCharSubmesh* pSubmesh = m_character->NewSubmesh (pModel, true); if (!pSubmesh) { AfxMessageBox("Cannot add body part " + model + "\nPlease check for skeleton compatibility\nSee the log for details"); return false; } return true; } bool CModelViewport::SetSubmesh (int nSlot, const CString& model) { ICryCharModel* pModel = m_pAnimationSystem->LoadModel(model); if (!pModel) { AfxMessageBox("Cannot open model " + model + "\nSee the log for details"); return false; } ICryCharSubmesh* pSubmesh = m_character->NewSubmesh (nSlot, pModel, true); if (!pSubmesh) { AfxMessageBox("Cannot add body part " + model + "\nPlease check for skeleton compatibility\nSee the log for details"); return false; } return true; } ////////////////////////////////////////////////////////////////////////// void CModelViewport::AttachObject( const CString &model,const CString &bone ) { if (!m_character) return; /* if (m_weaponModel) { m_engine->ReleaseObject( m_weaponModel ); m_weaponModel = NULL; } if (m_attachedCharacter) { m_engine->GetCryAnimationManager()->RemoveCharacter(m_attachedCharacter); m_attachedCharacter = NULL; } */ IBindable* pBindable = NULL; m_attachedCharacter = m_pAnimationSystem->MakeCharacter(model); if (m_attachedCharacter) pBindable = m_attachedCharacter; if (!m_attachedCharacter) { m_weaponModel = m_engine->MakeObject (model,NULL,evs_ShareAndSortForCache); if (m_weaponModel) pBindable = m_weaponModel; } m_attachBone = bone; if(!pBindable) { CString str; str.Format( "Loading of weapon model %s failed.",(const char*)model ); AfxMessageBox( str ); CLogFile::WriteLine( str ); return; } if (m_attachedCharacter) m_character->AttachToBone ( pBindable,m_character->GetModel()->GetBoneByName(bone)); else m_character->AttachObjectToBone(pBindable, bone, false); } void CModelViewport::StopAnimation(int nLayer) { if (!m_character) return; m_character->StopAnimation(nLayer); } void CModelViewport::OnLightColor( IVariable *var ) { Vec3 d = mv_lightDiffuseColor; Vec3 s = mv_lightSpecularColor; m_currLightDiffuseColor.Set( d.x,d.y,d.z ); m_currLightSpecularColor.Set( s.x,s.y,s.z ); for (int i=0;im_Color = m_currLightDiffuseColor; l->m_SpecColor = m_currLightSpecularColor; } } ////////////////////////////////////////////////////////////////////////// void CModelViewport::OnShowShaders( IVariable *var ) { bool bEnable = mv_showShaders; GetIEditor()->SetConsoleVar("r_ProfileShaders",bEnable); } ////////////////////////////////////////////////////////////////////////// void CModelViewport::OnDisableVisibility( IVariable *var ) { bool bDisableVisibility = mv_disableVisibility; // GetIEditor()->Get3DEngine()->GetBuildingManager()->EnableVisibility( !bDisableVisibility ); } void CModelViewport::OnDestroy() { ReleaseObject(); if (m_pRESky) m_pRESky->Release(); if (m_rollupIndex) { GetIEditor()->RemoveRollUpPage( ROLLUP_OBJECTS,m_rollupIndex ); m_rollupIndex = 0; } if (m_rollupIndex2) { GetIEditor()->RemoveRollUpPage( ROLLUP_OBJECTS,m_rollupIndex2 ); m_rollupIndex2 = 0; } if (s_varsPanelId) { GetIEditor()->RemoveRollUpPage( ROLLUP_OBJECTS,s_varsPanelId ); s_varsPanelId = 0; } m_modelPanel = 0; m_modelSubmeshPanel = 0; s_varsPanel = 0; CRenderViewport::OnDestroy(); } void CModelViewport::OnSubmeshSetChanged() { SetCharacterUIInfo(); } ////////////////////////////////////////////////////////////////////////// void CModelViewport::OnActivate() { } ////////////////////////////////////////////////////////////////////////// void CModelViewport::OnDeactivate() { } void CModelViewport::Update() { CRenderViewport::Update(); }