mirror of
https://github.com/dhewm/dhewm3.git
synced 2024-11-30 16:11:11 +00:00
1355 lines
41 KiB
C++
1355 lines
41 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
Doom 3 GPL Source Code
|
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
|
|
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
|
|
|
Doom 3 Source Code 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.
|
|
|
|
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#include "tools/edit_gui_common.h"
|
|
|
|
|
|
#include "../../sys/win32/rc/AFEditor_resource.h"
|
|
|
|
#include "DialogAF.h"
|
|
#include "DialogAFName.h"
|
|
#include "DialogAFConstraint.h"
|
|
#include "DialogAFBody.h"
|
|
|
|
typedef struct {
|
|
traceModel_t type;
|
|
const char *name;
|
|
} cm_type_t;
|
|
|
|
cm_type_t modelTypes[] = {
|
|
{ TRM_INVALID, "invalid" },
|
|
{ TRM_BOX, "box" },
|
|
{ TRM_OCTAHEDRON, "octahedron" },
|
|
{ TRM_DODECAHEDRON, "dodecahedron" },
|
|
{ TRM_CYLINDER, "cylinder" },
|
|
{ TRM_CONE, "cone" },
|
|
{ TRM_BONE, "bone" },
|
|
{ TRM_CUSTOM, "custom" },
|
|
{ TRM_INVALID, NULL }
|
|
};
|
|
|
|
const char *ModelTypeToString( int type ) {
|
|
for ( int i = 0; modelTypes[i].name; i++ ) {
|
|
if ( modelTypes[i].type == type ) {
|
|
return modelTypes[i].name;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
traceModel_t StringToModelType( const char *str ) {
|
|
for ( int i = 0; modelTypes[i].name; i++ ) {
|
|
if ( idStr::Icmp( modelTypes[i].name, str ) == 0 ) {
|
|
return modelTypes[i].type;
|
|
}
|
|
}
|
|
return TRM_INVALID;
|
|
}
|
|
|
|
// DialogAFBody dialog
|
|
|
|
toolTip_t DialogAFBody::toolTips[] = {
|
|
{ IDC_COMBO_BODIES, "select body for editing" },
|
|
{ IDC_BUTTON_NEWBODY, "create a new body" },
|
|
{ IDC_BUTTON_RENAMEBODY, "rename the selected body" },
|
|
{ IDC_BUTTON_DELETEBODY, "delete the selected body" },
|
|
{ IDC_COMBO_CM_TYPE, "collision model type" },
|
|
{ IDC_EDIT_CM_NAME, "custom collision model" },
|
|
{ IDC_BUTTON_CM_BROWSE, "browse custom collision model" },
|
|
{ IDC_COMBO_BONE_JOINT1, "first joint of bone collision model" },
|
|
{ IDC_COMBO_BONE_JOINT2, "second joint of bone collision model" },
|
|
{ IDC_EDIT_CM_HEIGHT, "hieght of the collision model" },
|
|
{ IDC_EDIT_CM_WIDTH, "width of the collision model" },
|
|
{ IDC_EDIT_CM_LENGTH, "length of the collision model" },
|
|
{ IDC_EDIT_CM_NUMSIDES, "number of sides of the collision model" },
|
|
{ IDC_EDIT_CM_DENSITY, "collision model density" },
|
|
{ IDC_EDIT_CM_INERTIASCALE, "inertia tensor scale" },
|
|
{ IDC_RADIO_ORIGIN_COORDINATES, "use absolute coordinates for the body origin" },
|
|
{ IDC_RADIO_ORIGIN_BONECENTER, "use the center of a bone for the body origin" },
|
|
{ IDC_RADIO_ORIGIN_JOINT, "use the position of a joint for the body origin" },
|
|
{ IDC_EDIT_AF_VECTOR_X, "x-coordinate" },
|
|
{ IDC_EDIT_AF_VECTOR_Y, "y-coordinate" },
|
|
{ IDC_EDIT_AF_VECTOR_Z, "z-coordinate" },
|
|
{ IDC_COMBO_ORIGIN_BONECENTER_JOINT1, "bone start joint" },
|
|
{ IDC_COMBO_ORIGIN_BONECENTER_JOINT2, "bone end joint" },
|
|
{ IDC_COMBO_ORIGIN_JOINT, "joint name" },
|
|
{ IDC_EDIT_ANGLES_PITCH, "pitch angle of body" },
|
|
{ IDC_EDIT_ANGLES_YAW, "yaw angle of body" },
|
|
{ IDC_EDIT_ANGLES_ROLL, "roll angle of body" },
|
|
{ IDC_EDIT_LINEARFRICTION, "translational friction" },
|
|
{ IDC_EDIT_ANGULARFRICTION, "rotational friction" },
|
|
{ IDC_EDIT_CONTACTFRICTION, "friction with contact surfaces" },
|
|
{ IDC_CHECK_SELFCOLLISION, "collide with other bodies of this articulated figure" },
|
|
{ IDC_EDIT_CONTENTS, "content of body" },
|
|
{ IDC_EDIT_CLIPMASK, "collide with these content types" },
|
|
{ IDC_EDIT_FRICTIONDIRECTION, "single friction direction relative to body" },
|
|
{ IDC_EDIT_CONTACTMOTORDIRECTION, "contact motor direction" },
|
|
{ IDC_COMBO_MODIFIEDJOINT, "the joint modified by the relative rotation of the body" },
|
|
{ IDC_RADIO_MODIFY_ORIENTATION, "modify the joint orientation" },
|
|
{ IDC_RADIO_MODIFY_POSITION, "modify the joint position" },
|
|
{ IDC_RADIO_MODIFY_BOTH, "modify the joint orientation and position" },
|
|
{ IDC_EDIT_CONTAINEDJOINTS, "all the joints contained by this body" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
IMPLEMENT_DYNAMIC(DialogAFBody, CDialog)
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::DialogAFBody
|
|
================
|
|
*/
|
|
DialogAFBody::DialogAFBody( CWnd* pParent /*=NULL*/ )
|
|
: CDialog(DialogAFBody::IDD, pParent)
|
|
, constraintDlg(NULL)
|
|
, numJoints(0)
|
|
, cm_length(0)
|
|
, cm_height(0)
|
|
, cm_width(0)
|
|
, cm_density(0)
|
|
, cm_numSides(3)
|
|
, cm_origin_x(0)
|
|
, cm_origin_y(0)
|
|
, cm_origin_z(0)
|
|
, cm_angles_pitch(0)
|
|
, cm_angles_yaw(0)
|
|
, cm_angles_roll(0)
|
|
, m_selfCollision(false)
|
|
, m_linearFriction(0)
|
|
, m_angularFriction(0)
|
|
, m_contactFriction(0)
|
|
, file(NULL)
|
|
, body(NULL)
|
|
{
|
|
Create( IDD_DIALOG_AF_BODY, pParent );
|
|
EnableToolTips( TRUE );
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::~DialogAFBody
|
|
================
|
|
*/
|
|
DialogAFBody::~DialogAFBody() {
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::DoDataExchange
|
|
================
|
|
*/
|
|
void DialogAFBody::DoDataExchange( CDataExchange* pDX ) {
|
|
CDialog::DoDataExchange( pDX );
|
|
//{{AFX_DATA_MAP(DialogAFBody)
|
|
DDX_Control(pDX, IDC_COMBO_BODIES, bodyList);
|
|
DDX_Control(pDX, IDC_COMBO_CM_TYPE, cm_comboType);
|
|
DDX_Text(pDX, IDC_EDIT_CM_LENGTH, cm_length);
|
|
DDX_Text(pDX, IDC_EDIT_CM_HEIGHT, cm_height);
|
|
DDX_Text(pDX, IDC_EDIT_CM_WIDTH, cm_width);
|
|
DDX_Text(pDX, IDC_EDIT_CM_NUMSIDES, cm_numSides);
|
|
DDX_Control(pDX, IDC_COMBO_BONE_JOINT1, cm_comboBoneJoint1 );
|
|
DDX_Control(pDX, IDC_COMBO_BONE_JOINT2, cm_comboBoneJoint2 );
|
|
DDX_Text(pDX, IDC_EDIT_CM_DENSITY, cm_density);
|
|
DDX_Control(pDX, IDC_EDIT_CM_INERTIASCALE, cm_inertiaScale);
|
|
DDX_Text(pDX, IDC_EDIT_AF_VECTOR_X, cm_origin_x);
|
|
DDX_Text(pDX, IDC_EDIT_AF_VECTOR_Y, cm_origin_y);
|
|
DDX_Text(pDX, IDC_EDIT_AF_VECTOR_Z, cm_origin_z);
|
|
DDX_Control(pDX, IDC_COMBO_ORIGIN_BONECENTER_JOINT1, cm_originBoneCenterJoint1);
|
|
DDX_Control(pDX, IDC_COMBO_ORIGIN_BONECENTER_JOINT2, cm_originBoneCenterJoint2);
|
|
DDX_Control(pDX, IDC_COMBO_ORIGIN_JOINT, cm_originJoint);
|
|
DDX_Text(pDX, IDC_EDIT_ANGLES_PITCH, cm_angles_pitch);
|
|
DDX_Text(pDX, IDC_EDIT_ANGLES_YAW, cm_angles_yaw);
|
|
DDX_Text(pDX, IDC_EDIT_ANGLES_ROLL, cm_angles_roll);
|
|
DDX_Check(pDX, IDC_CHECK_SELFCOLLISION, m_selfCollision);
|
|
DDX_Control(pDX, IDC_EDIT_CONTENTS, m_editContents);
|
|
DDX_Control(pDX, IDC_EDIT_CLIPMASK, m_editClipMask);
|
|
DDX_Text(pDX, IDC_EDIT_LINEARFRICTION, m_linearFriction);
|
|
DDX_Text(pDX, IDC_EDIT_ANGULARFRICTION, m_angularFriction);
|
|
DDX_Text(pDX, IDC_EDIT_CONTACTFRICTION, m_contactFriction);
|
|
DDX_Control(pDX, IDC_EDIT_FRICTIONDIRECTION, m_frictionDirection);
|
|
DDX_Control(pDX, IDC_EDIT_CONTACTMOTORDIRECTION, m_contactMotorDirection);
|
|
DDX_Control(pDX, IDC_COMBO_MODIFIEDJOINT, m_comboModifiedJoint);
|
|
DDX_Control(pDX, IDC_EDIT_CONTAINEDJOINTS, m_editContainedJoints);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::InitBodyList
|
|
================
|
|
*/
|
|
void DialogAFBody::InitBodyList( void ) {
|
|
CString str;
|
|
|
|
bodyList.ResetContent();
|
|
if ( !file ) {
|
|
return;
|
|
}
|
|
for ( int i = 0; i < file->bodies.Num(); i++ ) {
|
|
bodyList.AddString( file->bodies[i]->name.c_str() );
|
|
}
|
|
if ( bodyList.GetCount() != 0 ) {
|
|
bodyList.SetCurSel( 0 );
|
|
bodyList.GetLBText( 0, str );
|
|
LoadBody( str );
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::InitJointLists
|
|
|
|
initialize the joint lists for bone collision models
|
|
================
|
|
*/
|
|
void DialogAFBody::InitJointLists( void ) {
|
|
idStrList joints;
|
|
|
|
cm_comboBoneJoint1.ResetContent();
|
|
cm_comboBoneJoint2.ResetContent();
|
|
cm_originBoneCenterJoint1.ResetContent();
|
|
cm_originBoneCenterJoint2.ResetContent();
|
|
cm_originJoint.ResetContent();
|
|
numJoints = 0;
|
|
|
|
if ( !file ) {
|
|
return;
|
|
}
|
|
|
|
const idRenderModel *model = gameEdit->ANIM_GetModelFromName( file->model );
|
|
if ( !model ) {
|
|
return;
|
|
}
|
|
|
|
numJoints = model->NumJoints();
|
|
for ( int i = 0; i < numJoints; i++ ) {
|
|
const char *jointName = model->GetJointName( (jointHandle_t) i );
|
|
cm_comboBoneJoint1.AddString( jointName );
|
|
cm_comboBoneJoint2.AddString( jointName );
|
|
cm_originBoneCenterJoint1.AddString( jointName );
|
|
cm_originBoneCenterJoint2.AddString( jointName );
|
|
cm_originJoint.AddString( jointName );
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::InitCollisionModelType
|
|
================
|
|
*/
|
|
void DialogAFBody::InitCollisionModelType( void ) {
|
|
int showBone, showOther;
|
|
bool enableOther;
|
|
CString str;
|
|
|
|
UpdateData( TRUE );
|
|
cm_comboType.GetLBText( cm_comboType.GetCurSel(), str );
|
|
traceModel_t type = StringToModelType( str );
|
|
if ( type == TRM_BONE ) {
|
|
showBone = SW_SHOW;
|
|
showOther = SW_HIDE;
|
|
enableOther = false;
|
|
GetDlgItem( IDC_STATIC_CM_LENGTH )->SetWindowText( "Joint 1" );
|
|
GetDlgItem( IDC_STATIC_CM_HEIGHT )->SetWindowText( "Joint 2" );
|
|
CheckRadioButton( IDC_RADIO_ORIGIN_COORDINATES,
|
|
IDC_RADIO_ORIGIN_JOINT,
|
|
IDC_RADIO_ORIGIN_BONECENTER );
|
|
}
|
|
else {
|
|
showBone = SW_HIDE;
|
|
showOther = SW_SHOW;
|
|
enableOther = true;
|
|
GetDlgItem( IDC_STATIC_CM_LENGTH )->SetWindowText( "Length" );
|
|
GetDlgItem( IDC_STATIC_CM_HEIGHT )->SetWindowText( "Height" );
|
|
}
|
|
GetDlgItem( IDC_COMBO_BONE_JOINT1 )->ShowWindow( showBone );
|
|
GetDlgItem( IDC_COMBO_BONE_JOINT2 )->ShowWindow( showBone );
|
|
GetDlgItem( IDC_EDIT_CM_LENGTH )->ShowWindow( showOther );
|
|
GetDlgItem( IDC_SPIN_CM_LENGTH )->ShowWindow( showOther );
|
|
GetDlgItem( IDC_EDIT_CM_HEIGHT )->ShowWindow( showOther );
|
|
GetDlgItem( IDC_SPIN_CM_HEIGHT )->ShowWindow( showOther );
|
|
|
|
// enable/disable origin controls
|
|
GetDlgItem( IDC_EDIT_AF_VECTOR_X )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_SPIN_AF_VECTOR_X )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_EDIT_AF_VECTOR_Y )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_SPIN_AF_VECTOR_Y )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_EDIT_AF_VECTOR_Z )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_SPIN_AF_VECTOR_Z )->EnableWindow( enableOther );
|
|
|
|
// enable/disable joint controls
|
|
GetDlgItem( IDC_COMBO_ORIGIN_BONECENTER_JOINT1 )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_COMBO_ORIGIN_BONECENTER_JOINT2 )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_COMBO_ORIGIN_JOINT )->EnableWindow( enableOther );
|
|
|
|
// enable/disable angles controls
|
|
GetDlgItem( IDC_STATIC_ANGLES_PITCH )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_EDIT_ANGLES_PITCH )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_SPIN_ANGLES_PITCH )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_STATIC_ANGLES_YAW )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_EDIT_ANGLES_YAW )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_SPIN_ANGLES_YAW )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_STATIC_ANGLES_ROLL )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_EDIT_ANGLES_ROLL )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_SPIN_ANGLES_ROLL )->EnableWindow( enableOther );
|
|
|
|
GetDlgItem( IDC_RADIO_ORIGIN_COORDINATES )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_RADIO_ORIGIN_BONECENTER )->EnableWindow( enableOther );
|
|
GetDlgItem( IDC_RADIO_ORIGIN_JOINT )->EnableWindow( enableOther );
|
|
|
|
if ( type == TRM_CONE || type == TRM_CYLINDER ) {
|
|
GetDlgItem( IDC_EDIT_CM_NUMSIDES )->EnableWindow( true );
|
|
GetDlgItem( IDC_SPIN_CM_NUMSIDES )->EnableWindow( true );
|
|
}
|
|
else {
|
|
GetDlgItem( IDC_EDIT_CM_NUMSIDES )->EnableWindow( false );
|
|
GetDlgItem( IDC_SPIN_CM_NUMSIDES )->EnableWindow( false );
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::InitModifiedJointList
|
|
================
|
|
*/
|
|
void DialogAFBody::InitModifiedJointList( void ) {
|
|
int i, j, numJoints;
|
|
CString str;
|
|
|
|
m_comboModifiedJoint.ResetContent();
|
|
|
|
if ( !file ) {
|
|
return;
|
|
}
|
|
|
|
const idRenderModel *model = gameEdit->ANIM_GetModelFromName( file->model );
|
|
if ( !model ) {
|
|
return;
|
|
}
|
|
|
|
numJoints = model->NumJoints();
|
|
for ( i = 0; i < numJoints; i++ ) {
|
|
const char *jointName = model->GetJointName( (jointHandle_t) i );
|
|
for ( j = 0; j < file->bodies.Num(); j++ ) {
|
|
if ( file->bodies[j] == body ) {
|
|
continue;
|
|
}
|
|
if ( file->bodies[j]->jointName.Icmp( jointName ) == 0 ) {
|
|
break;
|
|
}
|
|
}
|
|
if ( j < file->bodies.Num() ) {
|
|
continue;
|
|
}
|
|
m_comboModifiedJoint.AddString( jointName );
|
|
}
|
|
|
|
if ( body ) {
|
|
if ( body->jointName.Length() == 0 ) {
|
|
m_comboModifiedJoint.GetLBText( 0, str );
|
|
body->jointName = str;
|
|
}
|
|
SetSafeComboBoxSelection( &m_comboModifiedJoint, body->jointName, -1 );
|
|
// cannot change the body which modifies the origin joint
|
|
if ( body->jointName.Icmp( "origin" ) == 0 ) {
|
|
// check if there is another body which modifies the "origin" joint
|
|
for ( i = 0; i < file->bodies.Num(); i++ ) {
|
|
if ( file->bodies[i] == body ) {
|
|
continue;
|
|
}
|
|
if ( file->bodies[i]->jointName.Icmp( "origin" ) == 0 ) {
|
|
break;
|
|
}
|
|
}
|
|
// if there is another body which modifies the "origin" joint
|
|
if ( i < file->bodies.Num() ) {
|
|
GetDlgItem( IDC_COMBO_MODIFIEDJOINT )->EnableWindow( true );
|
|
}
|
|
else {
|
|
GetDlgItem( IDC_COMBO_MODIFIEDJOINT )->EnableWindow( false );
|
|
}
|
|
}
|
|
else {
|
|
GetDlgItem( IDC_COMBO_MODIFIEDJOINT )->EnableWindow( true );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::InitNewRenameDeleteButtons
|
|
================
|
|
*/
|
|
void DialogAFBody::InitNewRenameDeleteButtons( void ) {
|
|
if ( file && numJoints > file->bodies.Num() ) {
|
|
GetDlgItem( IDC_BUTTON_NEWBODY )->EnableWindow( true );
|
|
}
|
|
else {
|
|
GetDlgItem( IDC_BUTTON_NEWBODY )->EnableWindow( false );
|
|
}
|
|
|
|
if ( file && bodyList.GetCount() >= 1 ) {
|
|
GetDlgItem( IDC_BUTTON_RENAMEBODY )->EnableWindow( true );
|
|
GetDlgItem( IDC_BUTTON_DELETEBODY )->EnableWindow( true );
|
|
}
|
|
else {
|
|
GetDlgItem( IDC_BUTTON_RENAMEBODY )->EnableWindow( false );
|
|
GetDlgItem( IDC_BUTTON_DELETEBODY )->EnableWindow( false );
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::LoadFile
|
|
================
|
|
*/
|
|
void DialogAFBody::LoadFile( idDeclAF *af ) {
|
|
file = af;
|
|
body = NULL;
|
|
InitJointLists();
|
|
InitBodyList();
|
|
InitNewRenameDeleteButtons();
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::SaveFile
|
|
================
|
|
*/
|
|
void DialogAFBody::SaveFile( void ) {
|
|
SaveBody();
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::LoadBody
|
|
================
|
|
*/
|
|
void DialogAFBody::LoadBody( const char *name ) {
|
|
int i, s1, s2;
|
|
idStr str;
|
|
|
|
if ( !file ) {
|
|
return;
|
|
}
|
|
for ( i = 0; i < file->bodies.Num(); i++ ) {
|
|
if ( file->bodies[i]->name.Icmp( name ) == 0 ) {
|
|
break;
|
|
}
|
|
}
|
|
if ( i >= file->bodies.Num() ) {
|
|
return;
|
|
}
|
|
body = file->bodies[i];
|
|
|
|
// load collision model from the current idDeclAF_Body
|
|
SetSafeComboBoxSelection( &cm_comboType, ModelTypeToString( body->modelType ), -1 );
|
|
if ( body->modelType == TRM_BONE ) {
|
|
s1 = SetSafeComboBoxSelection( &cm_comboBoneJoint1, body->v1.joint1.c_str(), -1 );
|
|
s2 = SetSafeComboBoxSelection( &cm_comboBoneJoint2, body->v2.joint1.c_str(), s1 );
|
|
cm_width = body->width;
|
|
cm_length = cm_height = 20.0f;
|
|
s1 = SetSafeComboBoxSelection( &cm_originBoneCenterJoint1, body->v1.joint1.c_str(), -1 );
|
|
s2 = SetSafeComboBoxSelection( &cm_originBoneCenterJoint2, body->v2.joint1.c_str(), s1 );
|
|
}
|
|
else {
|
|
cm_length = body->v2.ToVec3().x - body->v1.ToVec3().x;
|
|
cm_height = body->v2.ToVec3().z - body->v1.ToVec3().z;
|
|
cm_width = body->v2.ToVec3().y - body->v1.ToVec3().y;
|
|
cm_origin_x = body->origin.ToVec3().x;
|
|
cm_origin_y = body->origin.ToVec3().y;
|
|
cm_origin_z = body->origin.ToVec3().z;
|
|
s1 = SetSafeComboBoxSelection( &cm_originBoneCenterJoint1, body->origin.joint1.c_str(), -1 );
|
|
s2 = SetSafeComboBoxSelection( &cm_originBoneCenterJoint2, body->origin.joint2.c_str(), s1 );
|
|
s1 = SetSafeComboBoxSelection( &cm_originJoint, body->origin.joint1.c_str(), -1 );
|
|
cm_angles_pitch = body->angles.pitch;
|
|
cm_angles_yaw = body->angles.yaw;
|
|
cm_angles_roll = body->angles.roll;
|
|
if ( body->origin.type == idAFVector::VEC_BONECENTER ) {
|
|
i = IDC_RADIO_ORIGIN_BONECENTER;
|
|
}
|
|
else if ( body->origin.type == idAFVector::VEC_JOINT ) {
|
|
i = IDC_RADIO_ORIGIN_JOINT;
|
|
}
|
|
else {
|
|
i = IDC_RADIO_ORIGIN_COORDINATES;
|
|
}
|
|
CheckRadioButton( IDC_RADIO_ORIGIN_COORDINATES, IDC_RADIO_ORIGIN_JOINT, i );
|
|
}
|
|
cm_numSides = body->numSides;
|
|
cm_density = body->density;
|
|
if ( body->inertiaScale == mat3_identity ) {
|
|
cm_inertiaScale.SetWindowText( "none" );
|
|
}
|
|
else {
|
|
cm_inertiaScale.SetWindowText( body->inertiaScale.ToString( 1 ) );
|
|
}
|
|
|
|
// load collision detection settings from the current idDeclAF_Body
|
|
m_selfCollision = body->selfCollision;
|
|
idDeclAF::ContentsToString( body->contents, str );
|
|
m_editContents.SetWindowText( str );
|
|
idDeclAF::ContentsToString( body->clipMask, str );
|
|
m_editClipMask.SetWindowText( str );
|
|
|
|
// load friction settings from the current idDeclAF_Body
|
|
m_linearFriction = body->linearFriction;
|
|
m_angularFriction = body->angularFriction;
|
|
m_contactFriction = body->contactFriction;
|
|
|
|
// friction direction and contact motor direction
|
|
if ( body->frictionDirection.ToVec3() != vec3_origin ) {
|
|
idFile_Memory file( "frictionDirection" );
|
|
file.WriteFloatString( "%f %f %f", body->frictionDirection.ToVec3().x, body->frictionDirection.ToVec3().y, body->frictionDirection.ToVec3().z );
|
|
m_frictionDirection.SetWindowText( file.GetDataPtr() );
|
|
} else {
|
|
m_frictionDirection.SetWindowText( "" );
|
|
}
|
|
if ( body->contactMotorDirection.ToVec3() != vec3_origin ) {
|
|
idFile_Memory file( "contactMotorDirection" );
|
|
file.WriteFloatString( "%f %f %f", body->contactMotorDirection.ToVec3().x, body->contactMotorDirection.ToVec3().y, body->contactMotorDirection.ToVec3().z );
|
|
m_contactMotorDirection.SetWindowText( file.GetDataPtr() );
|
|
} else {
|
|
m_contactMotorDirection.SetWindowText( "" );
|
|
}
|
|
|
|
// load joint settings from the current idDeclAF_Body
|
|
InitModifiedJointList();
|
|
if ( body->jointMod == DECLAF_JOINTMOD_AXIS ) {
|
|
i = IDC_RADIO_MODIFY_ORIENTATION;
|
|
} else if ( body->jointMod == DECLAF_JOINTMOD_ORIGIN ) {
|
|
i = IDC_RADIO_MODIFY_POSITION;
|
|
} else if ( body->jointMod == DECLAF_JOINTMOD_BOTH ) {
|
|
i = IDC_RADIO_MODIFY_BOTH;
|
|
} else {
|
|
i = IDC_RADIO_MODIFY_ORIENTATION;
|
|
}
|
|
CheckRadioButton( IDC_RADIO_MODIFY_ORIENTATION, IDC_RADIO_MODIFY_BOTH, i );
|
|
m_editContainedJoints.SetWindowText( body->containedJoints.c_str() );
|
|
|
|
// update displayed values
|
|
UpdateData( FALSE );
|
|
|
|
InitCollisionModelType(); // CComboBox::SetCurSel doesn't call this
|
|
|
|
if ( GetStyle() & WS_VISIBLE ) {
|
|
// highlight the current body ingame
|
|
cvarSystem->SetCVarString( "af_highlightBody", name );
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::SaveBody
|
|
================
|
|
*/
|
|
void DialogAFBody::SaveBody( void ) {
|
|
int s1, s2;
|
|
CString str;
|
|
|
|
if ( !file || !body ) {
|
|
return;
|
|
}
|
|
UpdateData( TRUE );
|
|
|
|
// save the collision model to the current idDeclAF_Body
|
|
cm_comboType.GetLBText( cm_comboType.GetCurSel(), str );
|
|
body->modelType = StringToModelType( str );
|
|
if ( body->modelType == TRM_BONE ) {
|
|
body->origin.type = idAFVector::VEC_BONECENTER;
|
|
s1 = GetSafeComboBoxSelection( &cm_comboBoneJoint1, str, -1 );
|
|
body->v1.type = idAFVector::VEC_JOINT;
|
|
body->v1.joint1 = str;
|
|
body->origin.joint1 = str;
|
|
s2 = GetSafeComboBoxSelection( &cm_comboBoneJoint2, str, s1 );
|
|
body->v2.type = idAFVector::VEC_JOINT;
|
|
body->v2.joint1 = str;
|
|
body->origin.joint2 = str;
|
|
body->width = cm_width;
|
|
body->angles.Zero();
|
|
} else {
|
|
body->v1.type = idAFVector::VEC_COORDS;
|
|
body->v1.ToVec3().x = -0.5f * cm_length;
|
|
body->v1.ToVec3().y = -0.5f * cm_width;
|
|
body->v1.ToVec3().z = -0.5f * cm_height;
|
|
body->v2.type = idAFVector::VEC_COORDS;
|
|
body->v2.ToVec3().x = 0.5f * cm_length;
|
|
body->v2.ToVec3().y = 0.5f * cm_width;
|
|
body->v2.ToVec3().z = 0.5f * cm_height;
|
|
body->origin.ToVec3().x = cm_origin_x;
|
|
body->origin.ToVec3().y = cm_origin_y;
|
|
body->origin.ToVec3().z = cm_origin_z;
|
|
body->angles.pitch = cm_angles_pitch;
|
|
body->angles.yaw = cm_angles_yaw;
|
|
body->angles.roll = cm_angles_roll;
|
|
if ( body->origin.type == idAFVector::VEC_JOINT ) {
|
|
s1 = GetSafeComboBoxSelection( &cm_originJoint, str, -1 );
|
|
body->origin.joint1 = str;
|
|
}
|
|
else {
|
|
s1 = GetSafeComboBoxSelection( &cm_originBoneCenterJoint1, str, -1 );
|
|
body->origin.joint1 = str;
|
|
}
|
|
s2 = GetSafeComboBoxSelection( &cm_originBoneCenterJoint2, str, s1 );
|
|
body->origin.joint2 = str;
|
|
}
|
|
body->numSides = cm_numSides;
|
|
body->density = cm_density;
|
|
cm_inertiaScale.GetWindowText( str );
|
|
if ( idStr::Icmp( str, "none" ) == 0 ) {
|
|
body->inertiaScale.Identity();
|
|
} else {
|
|
idLexer src( str, str.GetLength(), "inertiaScale" );
|
|
src.SetFlags( LEXFL_NOERRORS | LEXFL_NOWARNINGS );
|
|
for ( int i = 0; i < 3; i++ ) {
|
|
for ( int j = 0; j < 3; j++ ) {
|
|
body->inertiaScale[i][j] = src.ParseFloat();
|
|
}
|
|
}
|
|
}
|
|
|
|
// save the collision detection settings to the current idDeclAF_Body
|
|
body->selfCollision = ( m_selfCollision != FALSE );
|
|
m_editContents.GetWindowText( str );
|
|
body->contents = idDeclAF::ContentsFromString( str );
|
|
m_editClipMask.GetWindowText( str );
|
|
body->clipMask = idDeclAF::ContentsFromString( str );
|
|
|
|
// save friction settings to the current idDeclAF_Body
|
|
body->linearFriction = m_linearFriction;
|
|
body->angularFriction = m_angularFriction;
|
|
body->contactFriction = m_contactFriction;
|
|
|
|
// friction direction and contact motor direction
|
|
m_frictionDirection.GetWindowText( str );
|
|
if ( str.GetLength() != 0 ) {
|
|
body->frictionDirection.ToVec3().Zero();
|
|
sscanf( str, "%f %f %f", &body->frictionDirection.ToVec3().x, &body->frictionDirection.ToVec3().y, &body->frictionDirection.ToVec3().z );
|
|
}
|
|
m_contactMotorDirection.GetWindowText( str );
|
|
if ( str.GetLength() != 0 ) {
|
|
body->contactMotorDirection.ToVec3().Zero();
|
|
sscanf( str, "%f %f %f", &body->contactMotorDirection.ToVec3().x, &body->contactMotorDirection.ToVec3().y, &body->contactMotorDirection.ToVec3().z );
|
|
}
|
|
|
|
// save joint settings to the current idDeclAF_Body
|
|
GetSafeComboBoxSelection( &m_comboModifiedJoint, str, -1 );
|
|
body->jointName = str;
|
|
m_editContainedJoints.GetWindowText( str );
|
|
body->containedJoints = str;
|
|
|
|
AFDialogSetFileModified();
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::UpdateFile
|
|
================
|
|
*/
|
|
void DialogAFBody::UpdateFile( void ) {
|
|
SaveBody();
|
|
if ( file ) {
|
|
gameEdit->AF_UpdateEntities( file->GetName() );
|
|
}
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::OnInitDialog
|
|
================
|
|
*/
|
|
BOOL DialogAFBody::OnInitDialog() {
|
|
|
|
CDialog::OnInitDialog();
|
|
|
|
// initialize the collision model types
|
|
cm_comboType.ResetContent();
|
|
for ( int i = 0; modelTypes[i].name; i++ ) {
|
|
if ( modelTypes[i].type == TRM_INVALID || modelTypes[i].type == TRM_CUSTOM ) {
|
|
continue;
|
|
}
|
|
cm_comboType.AddString( modelTypes[i].name );
|
|
}
|
|
|
|
InitNewRenameDeleteButtons();
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
/*
|
|
================
|
|
DialogAFBody::OnToolHitTest
|
|
================
|
|
*/
|
|
INT_PTR DialogAFBody::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const {
|
|
CDialog::OnToolHitTest( point, pTI );
|
|
return DefaultOnToolHitTest( toolTips, this, point, pTI );
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(DialogAFBody, CDialog)
|
|
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify)
|
|
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)
|
|
ON_WM_SHOWWINDOW()
|
|
ON_CBN_SELCHANGE(IDC_COMBO_BODIES, OnCbnSelchangeComboBodies)
|
|
ON_BN_CLICKED(IDC_BUTTON_NEWBODY, OnBnClickedButtonNewbody)
|
|
ON_BN_CLICKED(IDC_BUTTON_RENAMEBODY, OnBnClickedButtonRenamebody)
|
|
ON_BN_CLICKED(IDC_BUTTON_DELETEBODY, OnBnClickedButtonDeletebody)
|
|
ON_CBN_SELCHANGE(IDC_COMBO_CM_TYPE, OnCbnSelchangeComboCmType)
|
|
ON_EN_CHANGE(IDC_EDIT_CM_LENGTH, OnEnChangeEditCmLength)
|
|
ON_EN_CHANGE(IDC_EDIT_CM_HEIGHT, OnEnChangeEditCmHeight)
|
|
ON_EN_CHANGE(IDC_EDIT_CM_WIDTH, OnEnChangeEditCmWidth)
|
|
ON_EN_CHANGE(IDC_EDIT_CM_NUMSIDES, OnEnChangeEditCmNumsides)
|
|
ON_CBN_SELCHANGE(IDC_COMBO_BONE_JOINT1, OnCbnSelchangeComboBoneJoint1)
|
|
ON_CBN_SELCHANGE(IDC_COMBO_BONE_JOINT2, OnCbnSelchangeComboBoneJoint2)
|
|
ON_EN_CHANGE(IDC_EDIT_CM_DENSITY, OnEnChangeEditCmDensity)
|
|
ON_EN_CHANGE(IDC_EDIT_CM_INERTIASCALE, OnEnChangeEditCmInertiascale)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CM_LENGTH, OnDeltaposSpinCmLength)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CM_HEIGHT, OnDeltaposSpinCmHeight)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CM_WIDTH, OnDeltaposSpinCmWidth)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CM_NUMSIDES, OnDeltaposSpinCmNumsides)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CM_DENSITY, OnDeltaposSpinCmDensity)
|
|
ON_BN_CLICKED(IDC_RADIO_ORIGIN_COORDINATES, OnBnClickedRadioOriginCoordinates)
|
|
ON_BN_CLICKED(IDC_RADIO_ORIGIN_BONECENTER, OnBnClickedRadioOriginBonecenter)
|
|
ON_BN_CLICKED(IDC_RADIO_ORIGIN_JOINT, OnBnClickedRadioOriginJoint)
|
|
ON_EN_CHANGE(IDC_EDIT_AF_VECTOR_X, OnEnChangeEditAfVectorX)
|
|
ON_EN_CHANGE(IDC_EDIT_AF_VECTOR_Y, OnEnChangeEditAfVectorY)
|
|
ON_EN_CHANGE(IDC_EDIT_AF_VECTOR_Z, OnEnChangeEditAfVectorZ)
|
|
ON_CBN_SELCHANGE(IDC_COMBO_ORIGIN_BONECENTER_JOINT1, OnOnCbnSelchangeComboOriginBoneCenterJoint1)
|
|
ON_CBN_SELCHANGE(IDC_COMBO_ORIGIN_BONECENTER_JOINT2, OnOnCbnSelchangeComboOriginBoneCenterJoint2)
|
|
ON_CBN_SELCHANGE(IDC_COMBO_ORIGIN_JOINT, OnOnCbnSelchangeComboOriginJoint)
|
|
ON_EN_CHANGE(IDC_EDIT_ANGLES_PITCH, OnEnChangeEditAnglesPitch)
|
|
ON_EN_CHANGE(IDC_EDIT_ANGLES_YAW, OnEnChangeEditAnglesYaw)
|
|
ON_EN_CHANGE(IDC_EDIT_ANGLES_ROLL, OnEnChangeEditAnglesRoll)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_AF_VECTOR_X, OnDeltaposSpinAfVectorX)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_AF_VECTOR_Y, OnDeltaposSpinAfVectorY)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_AF_VECTOR_Z, OnDeltaposSpinAfVectorZ)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANGLES_PITCH, OnDeltaposSpinAnglesPitch)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANGLES_YAW, OnDeltaposSpinAnglesYaw)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANGLES_ROLL, OnDeltaposSpinAnglesRoll)
|
|
ON_BN_CLICKED(IDC_CHECK_SELFCOLLISION, OnBnClickedCheckSelfcollision)
|
|
ON_EN_CHANGE(IDC_EDIT_CONTENTS, OnEnChangeEditContents)
|
|
ON_EN_CHANGE(IDC_EDIT_CLIPMASK, OnEnChangeEditClipmask)
|
|
ON_EN_CHANGE(IDC_EDIT_LINEARFRICTION, OnEnChangeEditLinearfriction)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_LINEARFRICTION, OnDeltaposSpinLinearfriction)
|
|
ON_EN_CHANGE(IDC_EDIT_ANGULARFRICTION, OnEnChangeEditAngularfriction)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ANGULARFRICTION, OnDeltaposSpinAngularfriction)
|
|
ON_EN_CHANGE(IDC_EDIT_CONTACTFRICTION, OnEnChangeEditContactfriction)
|
|
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CONTACTFRICTION, OnDeltaposSpinContactfriction)
|
|
ON_EN_CHANGE(IDC_EDIT_FRICTIONDIRECTION, OnEnChangeEditFrictionDirection)
|
|
ON_EN_CHANGE(IDC_EDIT_CONTACTMOTORDIRECTION, OnEnChangeEditContactMotorDirection)
|
|
ON_CBN_SELCHANGE(IDC_COMBO_MODIFIEDJOINT, OnCbnSelchangeComboModifiedjoint)
|
|
ON_BN_CLICKED(IDC_RADIO_MODIFY_ORIENTATION, OnBnClickedRadioModifyOrientation)
|
|
ON_BN_CLICKED(IDC_RADIO_MODIFY_POSITION, OnBnClickedRadioModifyPosition)
|
|
ON_BN_CLICKED(IDC_RADIO_MODIFY_BOTH, OnBnClickedRadioModifyBoth)
|
|
ON_EN_CHANGE(IDC_EDIT_CONTAINEDJOINTS, OnEnChangeEditContainedjoints)
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
// DialogAFBody message handlers
|
|
|
|
BOOL DialogAFBody::OnToolTipNotify( UINT id, NMHDR *pNMHDR, LRESULT *pResult ) {
|
|
return DefaultOnToolTipNotify( toolTips, id, pNMHDR, pResult );
|
|
}
|
|
|
|
void DialogAFBody::OnShowWindow( BOOL bShow, UINT nStatus ) {
|
|
if ( bShow && body ) {
|
|
cvarSystem->SetCVarString( "af_highlightBody", body->name.c_str() );
|
|
} else {
|
|
cvarSystem->SetCVarString( "af_highlightBody", "" );
|
|
}
|
|
CDialog::OnShowWindow( bShow, nStatus );
|
|
}
|
|
|
|
void DialogAFBody::OnCbnSelchangeComboBodies() {
|
|
CString str;
|
|
|
|
GetSafeComboBoxSelection( &bodyList, str, -1 );
|
|
LoadBody( str );
|
|
}
|
|
|
|
void DialogAFBody::OnBnClickedButtonNewbody() {
|
|
DialogAFName nameDlg;
|
|
CString str;
|
|
INT_PTR res;
|
|
|
|
// the names 'origin' and 'world' are reserved for constraints bound to the world
|
|
bodyList.AddString( "origin" );
|
|
bodyList.AddString( "world" );
|
|
|
|
nameDlg.SetComboBox( &bodyList );
|
|
res = nameDlg.DoModal();
|
|
|
|
bodyList.DeleteString( bodyList.FindString( -1, "origin" ) );
|
|
bodyList.DeleteString( bodyList.FindString( -1, "world" ) );
|
|
|
|
if ( res == IDOK ) {
|
|
nameDlg.GetName( str );
|
|
// create new body
|
|
file->NewBody( str );
|
|
bodyList.SetCurSel( bodyList.AddString( str ) );
|
|
LoadBody( str );
|
|
constraintDlg->LoadFile( file );
|
|
gameEdit->AF_UpdateEntities( file->GetName() );
|
|
AFDialogSetFileModified();
|
|
}
|
|
InitNewRenameDeleteButtons();
|
|
}
|
|
|
|
void DialogAFBody::OnBnClickedButtonRenamebody() {
|
|
int i;
|
|
CString name, newName;
|
|
DialogAFName nameDlg;
|
|
|
|
if ( !file || !body ) {
|
|
return;
|
|
}
|
|
|
|
i = bodyList.GetCurSel();
|
|
if ( i != CB_ERR ) {
|
|
bodyList.GetLBText( i, name );
|
|
nameDlg.SetName( name );
|
|
nameDlg.SetComboBox( &bodyList );
|
|
if ( nameDlg.DoModal() == IDOK ) {
|
|
nameDlg.GetName( newName );
|
|
// rename body
|
|
file->RenameBody( name, newName );
|
|
bodyList.DeleteString( i );
|
|
bodyList.SetCurSel( bodyList.AddString( newName ) );
|
|
LoadBody( newName );
|
|
constraintDlg->LoadFile( file );
|
|
gameEdit->AF_UpdateEntities( file->GetName() );
|
|
AFDialogSetFileModified();
|
|
}
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnBnClickedButtonDeletebody() {
|
|
int i;
|
|
CString str;
|
|
|
|
if ( !file || !body ) {
|
|
return;
|
|
}
|
|
|
|
i = bodyList.GetCurSel();
|
|
if ( i != CB_ERR ) {
|
|
if ( MessageBox( "Are you sure you want to delete this body and all attached constraints ?", "Delete Body", MB_YESNO | MB_ICONQUESTION ) == IDYES ) {
|
|
bodyList.GetLBText( i, str );
|
|
// delete currently selected body
|
|
file->DeleteBody( str );
|
|
bodyList.DeleteString( i );
|
|
body = NULL;
|
|
OnCbnSelchangeComboBodies();
|
|
constraintDlg->LoadFile( file );
|
|
gameEdit->AF_UpdateEntities( file->GetName() );
|
|
AFDialogSetFileModified();
|
|
}
|
|
}
|
|
InitNewRenameDeleteButtons();
|
|
}
|
|
|
|
void DialogAFBody::OnCbnSelchangeComboCmType() {
|
|
InitCollisionModelType();
|
|
UpdateFile();
|
|
}
|
|
|
|
void DialogAFBody::ValidateCollisionModelLength( bool update ) {
|
|
if ( cm_length < 1.0f ) {
|
|
cm_length = 1.0f;
|
|
update = true;
|
|
}
|
|
if ( update ) {
|
|
UpdateData( FALSE );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditCmLength() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CM_LENGTH ) ) ) {
|
|
ValidateCollisionModelLength( false );
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
cm_length = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CM_LENGTH ), false );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinCmLength(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
if ( pNMUpDown->iDelta < 0 ) {
|
|
cm_length += 1.0f;
|
|
}
|
|
else if ( cm_length >= 2.0f ) {
|
|
cm_length -= 1.0f;
|
|
}
|
|
ValidateCollisionModelLength( true );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::ValidateCollisionModelHeight( bool update ) {
|
|
if ( cm_height < 1.0f ) {
|
|
cm_height = 1.0f;
|
|
update = true;
|
|
}
|
|
if ( update ) {
|
|
UpdateData( FALSE );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditCmHeight() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CM_HEIGHT ) ) ) {
|
|
ValidateCollisionModelHeight( false );
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
cm_height = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CM_HEIGHT ), false );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinCmHeight(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
if ( pNMUpDown->iDelta < 0 ) {
|
|
cm_height += 1.0f;
|
|
}
|
|
else if ( cm_height >= 2.0f ) {
|
|
cm_height -= 1.0f;
|
|
}
|
|
ValidateCollisionModelHeight( true );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::ValidateCollisionModelWidth( bool update ) {
|
|
if ( cm_width < 1.0f ) {
|
|
cm_width = 1.0f;
|
|
update = true;
|
|
}
|
|
if ( update ) {
|
|
UpdateData( FALSE );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditCmWidth() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CM_WIDTH ) ) ) {
|
|
ValidateCollisionModelWidth( false );
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
cm_width = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CM_WIDTH ), false );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinCmWidth(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
if ( pNMUpDown->iDelta < 0 ) {
|
|
cm_width += 1.0f;
|
|
}
|
|
else if ( cm_width >= 2.0f ) {
|
|
cm_width -= 1.0f;
|
|
}
|
|
ValidateCollisionModelWidth( true );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::ValidateCollisionModelNumSides( bool update ) {
|
|
cm_numSides = (int) cm_numSides;
|
|
if ( cm_numSides < 3 ) {
|
|
cm_numSides = 3;
|
|
update = true;
|
|
}
|
|
else if ( cm_numSides > 10 ) {
|
|
cm_numSides = 10;
|
|
update = true;
|
|
}
|
|
if ( update ) {
|
|
UpdateData( FALSE );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditCmNumsides() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CM_NUMSIDES ) ) ) {
|
|
ValidateCollisionModelNumSides( false );
|
|
UpdateFile();
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinCmNumsides(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
if ( pNMUpDown->iDelta < 0 ) {
|
|
cm_numSides += 1;
|
|
}
|
|
else if ( cm_numSides > 3 ) {
|
|
cm_numSides -= 1;
|
|
}
|
|
ValidateCollisionModelNumSides( true );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::OnCbnSelchangeComboBoneJoint1() {
|
|
CString str;
|
|
GetSafeComboBoxSelection( &cm_comboBoneJoint1, str, -1 );
|
|
UnsetSafeComboBoxSelection( &cm_comboBoneJoint2, str );
|
|
UpdateFile();
|
|
}
|
|
|
|
void DialogAFBody::OnCbnSelchangeComboBoneJoint2() {
|
|
CString str;
|
|
GetSafeComboBoxSelection( &cm_comboBoneJoint2, str, -1 );
|
|
UnsetSafeComboBoxSelection( &cm_comboBoneJoint1, str );
|
|
UpdateFile();
|
|
}
|
|
|
|
void DialogAFBody::ValidateCollisionModelDensity( bool update ) {
|
|
if ( cm_density < 1e-6f ) {
|
|
cm_density = 1e-6f;
|
|
update = true;
|
|
}
|
|
if ( update ) {
|
|
UpdateData( FALSE );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditCmDensity() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CM_DENSITY ) ) ) {
|
|
ValidateCollisionModelDensity( false );
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
cm_density = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CM_DENSITY ), false );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinCmDensity(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
cm_density = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_CM_DENSITY ), pNMUpDown->iDelta < 0 );
|
|
ValidateCollisionModelDensity( false );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditCmInertiascale() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CM_INERTIASCALE ) ) ) {
|
|
UpdateFile();
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnBnClickedRadioOriginCoordinates() {
|
|
if ( IsDlgButtonChecked( IDC_RADIO_ORIGIN_COORDINATES ) ) {
|
|
if ( body ) {
|
|
body->origin.type = idAFVector::VEC_COORDS;
|
|
UpdateFile();
|
|
}
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnBnClickedRadioOriginBonecenter() {
|
|
if ( IsDlgButtonChecked( IDC_RADIO_ORIGIN_BONECENTER ) ) {
|
|
if ( body ) {
|
|
body->origin.type = idAFVector::VEC_BONECENTER;
|
|
UpdateFile();
|
|
}
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnBnClickedRadioOriginJoint() {
|
|
if ( IsDlgButtonChecked( IDC_RADIO_ORIGIN_JOINT ) ) {
|
|
if ( body ) {
|
|
body->origin.type = idAFVector::VEC_JOINT;
|
|
UpdateFile();
|
|
}
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditAfVectorX() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_AF_VECTOR_X ) ) ) {
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
cm_origin_x = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_AF_VECTOR_X ) );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinAfVectorX(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
if ( pNMUpDown->iDelta < 0 ) {
|
|
cm_origin_x += 1;
|
|
}
|
|
else {
|
|
cm_origin_x -= 1;
|
|
}
|
|
UpdateData( FALSE );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditAfVectorY() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_AF_VECTOR_Y ) ) ) {
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
cm_origin_y = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_AF_VECTOR_Y ) );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinAfVectorY(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
if ( pNMUpDown->iDelta < 0 ) {
|
|
cm_origin_y += 1;
|
|
}
|
|
else {
|
|
cm_origin_y -= 1;
|
|
}
|
|
UpdateData( FALSE );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditAfVectorZ() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_AF_VECTOR_Z ) ) ) {
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
cm_origin_z = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_AF_VECTOR_Z ) );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinAfVectorZ(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
if ( pNMUpDown->iDelta < 0 ) {
|
|
cm_origin_z += 1;
|
|
}
|
|
else {
|
|
cm_origin_z -= 1;
|
|
}
|
|
UpdateData( FALSE );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::OnOnCbnSelchangeComboOriginBoneCenterJoint1() {
|
|
CString str;
|
|
GetSafeComboBoxSelection( &cm_originBoneCenterJoint1, str, -1 );
|
|
UnsetSafeComboBoxSelection( &cm_originBoneCenterJoint2, str );
|
|
UpdateFile();
|
|
}
|
|
|
|
void DialogAFBody::OnOnCbnSelchangeComboOriginBoneCenterJoint2() {
|
|
CString str;
|
|
GetSafeComboBoxSelection( &cm_originBoneCenterJoint2, str, -1 );
|
|
UnsetSafeComboBoxSelection( &cm_originBoneCenterJoint1, str );
|
|
UpdateFile();
|
|
}
|
|
|
|
void DialogAFBody::OnOnCbnSelchangeComboOriginJoint() {
|
|
UpdateFile();
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditAnglesPitch() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANGLES_PITCH ) ) ) {
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
cm_angles_pitch = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANGLES_PITCH ) );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinAnglesPitch(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
if ( pNMUpDown->iDelta < 0 ) {
|
|
cm_angles_pitch += 1;
|
|
}
|
|
else {
|
|
cm_angles_pitch -= 1;
|
|
}
|
|
cm_angles_pitch = idMath::AngleNormalize360( cm_angles_pitch );
|
|
UpdateData( FALSE );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditAnglesYaw() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANGLES_YAW ) ) ) {
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
cm_angles_yaw = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANGLES_YAW ) );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinAnglesYaw(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
if ( pNMUpDown->iDelta < 0 ) {
|
|
cm_angles_yaw += 1;
|
|
}
|
|
else {
|
|
cm_angles_yaw -= 1;
|
|
}
|
|
cm_angles_yaw = idMath::AngleNormalize360( cm_angles_yaw );
|
|
UpdateData( FALSE );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditAnglesRoll() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANGLES_ROLL ) ) ) {
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
cm_angles_roll = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANGLES_ROLL ) );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinAnglesRoll(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
if ( pNMUpDown->iDelta < 0 ) {
|
|
cm_angles_roll += 1;
|
|
}
|
|
else {
|
|
cm_angles_roll -= 1;
|
|
}
|
|
cm_angles_roll = idMath::AngleNormalize360( cm_angles_roll );
|
|
UpdateData( FALSE );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::OnBnClickedCheckSelfcollision() {
|
|
UpdateFile();
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditContents() {
|
|
if ( EditControlEnterHit( &m_editContents ) ) {
|
|
UpdateFile();
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditClipmask() {
|
|
if ( EditControlEnterHit( &m_editClipMask ) ) {
|
|
UpdateFile();
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditLinearfriction() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_LINEARFRICTION ) ) ) {
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
m_linearFriction = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_LINEARFRICTION ), false );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinLinearfriction(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
m_linearFriction = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_LINEARFRICTION ), pNMUpDown->iDelta < 0 );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditAngularfriction() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_ANGULARFRICTION ) ) ) {
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
m_angularFriction = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_ANGULARFRICTION ), false );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinAngularfriction(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
m_angularFriction = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_ANGULARFRICTION ), pNMUpDown->iDelta < 0 );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditContactfriction() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CONTACTFRICTION ) ) ) {
|
|
UpdateFile();
|
|
}
|
|
else {
|
|
m_contactFriction = EditVerifyFloat( (CEdit *) GetDlgItem( IDC_EDIT_CONTACTFRICTION ), false );
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnDeltaposSpinContactfriction(NMHDR *pNMHDR, LRESULT *pResult) {
|
|
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
|
|
m_contactFriction = EditSpinFloat( (CEdit *)GetDlgItem( IDC_EDIT_CONTACTFRICTION ), pNMUpDown->iDelta < 0 );
|
|
UpdateFile();
|
|
*pResult = 0;
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditFrictionDirection() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_FRICTIONDIRECTION ) ) ) {
|
|
UpdateFile();
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditContactMotorDirection() {
|
|
if ( EditControlEnterHit( (CEdit *) GetDlgItem( IDC_EDIT_CONTACTMOTORDIRECTION ) ) ) {
|
|
UpdateFile();
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnCbnSelchangeComboModifiedjoint() {
|
|
UpdateFile();
|
|
}
|
|
|
|
void DialogAFBody::OnBnClickedRadioModifyOrientation() {
|
|
if ( IsDlgButtonChecked( IDC_RADIO_MODIFY_ORIENTATION ) ) {
|
|
if ( body ) {
|
|
body->jointMod = DECLAF_JOINTMOD_AXIS;
|
|
UpdateFile();
|
|
}
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnBnClickedRadioModifyPosition() {
|
|
if ( IsDlgButtonChecked( IDC_RADIO_MODIFY_POSITION ) ) {
|
|
if ( body ) {
|
|
body->jointMod = DECLAF_JOINTMOD_ORIGIN;
|
|
UpdateFile();
|
|
}
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnBnClickedRadioModifyBoth() {
|
|
if ( IsDlgButtonChecked( IDC_RADIO_MODIFY_BOTH ) ) {
|
|
if ( body ) {
|
|
body->jointMod = DECLAF_JOINTMOD_BOTH;
|
|
UpdateFile();
|
|
}
|
|
}
|
|
}
|
|
|
|
void DialogAFBody::OnEnChangeEditContainedjoints() {
|
|
if ( EditControlEnterHit( &m_editContainedJoints ) ) {
|
|
UpdateFile();
|
|
}
|
|
}
|