339 lines
10 KiB
C++
339 lines
10 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/***********************************************************************************************
|
|
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
|
***********************************************************************************************
|
|
* *
|
|
* Project Name : LevelEdit *
|
|
* *
|
|
* $Archive:: /Commando/Code/Tools/LevelEdit/GrabHandles.cpp $*
|
|
* *
|
|
* Author:: Patrick Smith *
|
|
* *
|
|
* $Modtime:: 3/28/01 3:16p $*
|
|
* *
|
|
* $Revision:: 8 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "grabhandles.h"
|
|
#include "sceneeditor.h"
|
|
#include "node.h"
|
|
#include "hittestinfo.h"
|
|
#include "utils.h"
|
|
#include "mousemgr.h"
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GrabHandlesClass
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
GrabHandlesClass::GrabHandlesClass (void)
|
|
: m_bIsAddedToScene (false),
|
|
m_pNode (NULL)
|
|
{
|
|
Initialize ();
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GrabHandlesClass
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
GrabHandlesClass::GrabHandlesClass (const GrabHandlesClass &ref)
|
|
: m_bIsAddedToScene (false),
|
|
m_pNode (NULL)
|
|
{
|
|
*this = ref;
|
|
Initialize ();
|
|
return ;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ~GrabHandlesClass
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
GrabHandlesClass::~GrabHandlesClass (void)
|
|
{
|
|
// Loop through and destroy all the handles
|
|
for (int handle = 0; handle < 8; handle ++) {
|
|
MEMBER_RELEASE (m_pHandles[handle]);
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Initialize
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
void
|
|
GrabHandlesClass::Initialize (void)
|
|
{
|
|
// Create a default vertex material for the handles
|
|
VertexMaterialClass *vmat = new VertexMaterialClass;
|
|
vmat->Set_Emissive (1,1,1);
|
|
vmat->Set_Diffuse (0,0,0);
|
|
vmat->Set_Opacity (1.0F);
|
|
|
|
// Loop through and create all the handles
|
|
for (int handle = 0; handle < 8; handle ++) {
|
|
m_pHandles[handle] = new GrabHandlePhysClass (handle, this);
|
|
|
|
// Modify the color of this box to be solid black
|
|
Box3DClass *pbox = m_pHandles[handle]->Get_Box ();
|
|
pbox->Set_Shader (ShaderClass::_PresetOpaqueSolidShader);
|
|
pbox->Set_Vertex_Material (vmat);
|
|
pbox->Set_Color (Vector3 (0.0F, 0.0F, 0.0F));
|
|
pbox->Disable_Sort ();
|
|
pbox->Enable_Bounding_Sphere ();
|
|
pbox->Enable_Bounding_Box ();
|
|
}
|
|
|
|
MEMBER_RELEASE (vmat);
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// operator=
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
const GrabHandlesClass &
|
|
GrabHandlesClass::operator= (const GrabHandlesClass &ref)
|
|
{
|
|
m_pNode = ref.m_pNode;
|
|
|
|
// Return a reference to ourselves
|
|
return *this;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Remove_From_Scene
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
void
|
|
GrabHandlesClass::Remove_From_Scene (void)
|
|
{
|
|
if (m_bIsAddedToScene) {
|
|
|
|
// Get a pointer to the current scene
|
|
SceneEditorClass *pscene = ::Get_Scene_Editor ();
|
|
|
|
// Were we successful in getting the scene pointer?
|
|
ASSERT (pscene != NULL);
|
|
if (pscene != NULL) {
|
|
|
|
// Loop through and remove all the handles from the scene
|
|
for (int handle = 0; handle < 8; handle ++) {
|
|
if (m_pHandles[handle] != NULL) {
|
|
pscene->Remove_Object (m_pHandles[handle]);
|
|
}
|
|
}
|
|
|
|
// Success!
|
|
m_bIsAddedToScene = false;
|
|
}
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Hide
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
void
|
|
GrabHandlesClass::Hide (bool bhide)
|
|
{
|
|
// Loop through and hide all the handles
|
|
for (int handle = 0; handle < 8; handle ++) {
|
|
if (m_pHandles[handle] != NULL) {
|
|
m_pHandles[handle]->Peek_Model ()->Set_Hidden (bhide);
|
|
|
|
if (bhide == true) {
|
|
m_pHandles[handle]->Inc_Ignore_Counter();
|
|
} else if (m_pHandles[handle]->Is_Ignore_Me()) {
|
|
m_pHandles[handle]->Dec_Ignore_Counter();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Position_Around_Node
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
void
|
|
GrabHandlesClass::Position_Around_Node (NodeClass *node)
|
|
{
|
|
RenderObjClass *render_obj = node->Peek_Render_Obj ();
|
|
if (render_obj != NULL) {
|
|
|
|
//
|
|
// Get the object's bounding box so we know where to
|
|
// position the grab handles
|
|
//
|
|
AABoxClass bounding_box;
|
|
render_obj->Get_Obj_Space_Bounding_Box (bounding_box);
|
|
const Matrix3D &transform = render_obj->Get_Transform ();
|
|
|
|
// Alias the extent vector
|
|
Vector3 extent = bounding_box.Extent;
|
|
extent.X = ::fabs (extent.X);
|
|
extent.Y = ::fabs (extent.Y);
|
|
extent.Z = ::fabs (extent.Z);
|
|
|
|
//
|
|
// Determine the new size for each grab handle
|
|
//
|
|
float largest_dim = max (extent.X, extent.Y);
|
|
largest_dim = max (largest_dim, extent.Z);
|
|
float size = max (largest_dim / 25.0F, 0.1F);
|
|
|
|
// Calculate the positions of the eight verticies
|
|
Vector3 verticies[8];
|
|
verticies[0] = bounding_box.Center + Vector3 (-extent.X, extent.Y, -extent.Z);
|
|
verticies[1] = bounding_box.Center + Vector3 (-extent.X, -extent.Y, -extent.Z);
|
|
verticies[2] = bounding_box.Center + Vector3 (-extent.X, -extent.Y, extent.Z);
|
|
verticies[3] = bounding_box.Center + Vector3 (-extent.X, extent.Y, extent.Z);
|
|
|
|
verticies[4] = bounding_box.Center + Vector3 (extent.X, extent.Y, -extent.Z);
|
|
verticies[5] = bounding_box.Center + Vector3 (extent.X, -extent.Y, -extent.Z);
|
|
verticies[6] = bounding_box.Center + Vector3 (extent.X, -extent.Y, extent.Z);
|
|
verticies[7] = bounding_box.Center + Vector3 (extent.X, extent.Y, extent.Z);
|
|
|
|
// Now add 'handles' centered around each of the 8 verticies
|
|
for (int vertex = 0; vertex < 8; vertex ++) {
|
|
|
|
// Rotate these verticies using the item's current transform
|
|
verticies[vertex] = transform * verticies[vertex];
|
|
|
|
// Resize the box
|
|
Box3DClass *pbox = m_pHandles[vertex]->Get_Box ();
|
|
pbox->Set_Dimensions (Vector3 (size, size, size));
|
|
//pbox->Set_Dimensions (Vector3 (1, 1, 1));
|
|
|
|
// Reposition this handle so its centered around the vertex
|
|
Matrix3D handle_transform = m_pHandles[vertex]->Get_Transform ();
|
|
handle_transform.Set_Translation (verticies[vertex]);
|
|
m_pHandles[vertex]->Set_Transform (handle_transform);
|
|
}
|
|
|
|
if (m_bIsAddedToScene == false) {
|
|
|
|
// Get a pointer to the current scene
|
|
SceneEditorClass *pscene = ::Get_Scene_Editor ();
|
|
|
|
// Were we successful in getting the scene pointer?
|
|
ASSERT (pscene != NULL);
|
|
if (pscene != NULL) {
|
|
|
|
// Loop through all the handles and add them to the scene
|
|
for (int handle = 0; handle < 8; handle ++) {
|
|
pscene->Add_Dynamic_Object (m_pHandles[handle]);
|
|
}
|
|
|
|
// Success!
|
|
m_bIsAddedToScene = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_pNode = node;
|
|
return ;
|
|
}
|
|
|
|
|
|
//*********************************************************************************************//
|
|
//
|
|
// End of GrabHandlesClass
|
|
//
|
|
//*********************************************************************************************//
|
|
|
|
//*********************************************************************************************//
|
|
//
|
|
// Start of GrabHandlePhysClass
|
|
//
|
|
//*********************************************************************************************//
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// On_Click
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
void
|
|
GrabHandlePhysClass::On_Click (void)
|
|
{
|
|
if (m_pParent != NULL) {
|
|
|
|
// Switch to the 'grabhandle drag' mode
|
|
MouseMgrClass *mousemgr = ::Get_Mouse_Mgr ();
|
|
mousemgr->Set_Mouse_Mode (MouseMgrClass::MODE_GRABHANDLE_DRAG);
|
|
|
|
// Pass on the node/vertex information onto the mode mgr
|
|
MMGrabHandleDragClass *mode = (MMGrabHandleDragClass *)mousemgr->Get_Mode_Mgr ();
|
|
if (mode != NULL) {
|
|
mode->Set_Node_Info (m_pParent->Get_Node (), m_iVertex);
|
|
}
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Initialize
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
void
|
|
GrabHandlePhysClass::Initialize (void)
|
|
{
|
|
Peek_Model ()->Set_User_Data (&m_HitTestInfo, FALSE);
|
|
return ;
|
|
}
|
|
|
|
|
|
//*********************************************************************************************//
|
|
//
|
|
// End of GrabHandlePhysClass
|
|
//
|
|
//*********************************************************************************************//
|