📄 entity.cpp
字号:
/****************************************************************************************/
/* Entity.cpp */
/* */
/* Author: Jim Mischel, Ken Baird, Jeff Lomax, Bruce Cooner */
/* Description: Entity code */
/* */
/* The contents of this file are subject to the Genesis3D Public License */
/* Version 1.01 (the "License"); you may not use this file except in */
/* compliance with the License. You may obtain a copy of the License at */
/* http://www.genesis3d.com */
/* */
/* Software distributed under the License is distributed on an "AS IS" */
/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */
/* the License for the specific language governing rights and limitations */
/* under the License. */
/* */
/* The Original Code is Genesis3D, released March 25, 1999. */
/*Genesis3D Version 1.1 released November 15, 1999 */
/* Copyright (C) 1999 WildTangent, Inc. All Rights Reserved */
/* */
/* Prepared for GenEdit-Classic ver. 0.5, Dec. 15, 2000 */
/****************************************************************************************/
#include "stdafx.h"
#include "Entity.h"
#include <stdio.h>
#include "typeio.h"
#include <assert.h>
#include "units.h"
#include "util.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define CLASSNAME "classname"
void CEntity::Move(geVec3d const *v)
{
assert (v != NULL);
if(EntityStyle!=ENTITY_S_ORIGIN)
return;
geVec3d_Add (&mOrigin, v, &mOrigin);
}
void CEntity::Rotate
(
geXForm3d const *pXfmRotate,
geVec3d const *pCenter,
const EntityTable *pEntityDefs
)
// Rotate the entity about the given point
{
geVec3d NewPos;
assert (pXfmRotate != NULL);
assert (pCenter != NULL);
geVec3d_Subtract (&mOrigin, pCenter, &NewPos);
geXForm3d_Rotate (pXfmRotate, &NewPos, &NewPos);
geVec3d_Add (&NewPos, pCenter, &NewPos);
SetOrigin (NewPos.X, NewPos.Y, NewPos.Z, pEntityDefs);
}
void CEntity::Scale(geFloat ScaleFactor, const EntityTable *pEntityDefs)
{
char temp[255];
geVec3d NewPos;
assert(ScaleFactor > 0.0f);
geVec3d_Scale(&mOrigin, ScaleFactor, &NewPos);
SetOrigin(NewPos.X, NewPos.Y, NewPos.Z, pEntityDefs);
if(GetKeyValue("light", temp))
{
int lval =atoi(temp);
itoa((int)(((float)lval)*ScaleFactor), temp, 10);
SetKeyValue("light", temp);
}
}
CEntity::CEntity()
{
// start of with new pairs but room for 10.
mKeyArray.SetSize(0, 10);
mValueArray.SetSize(0, 10);
// default is an origin entity
EntityStyle = ENTITY_S_ORIGIN;
// start off active
mFlags = 0;
// start off with no group
mGroup = 0;
}
CEntity::~CEntity ()
{
mKeyArray.RemoveAll ();
mValueArray.RemoveAll ();
}
geBoolean CEntity::IsCamera( void ) const
{
return GetClassname().Compare( "Camera" ) == 0 ;
}
// sets selected state of entity
void CEntity::Select()
{
mFlags |= ENTITY_SELECTED;
}
// clears selected flag of entity
void CEntity::DeSelect()
{
mFlags &= ~ENTITY_SELECTED;
}
// returns selected state of entity
int CEntity::IsSelected() const
{
return mFlags & ENTITY_SELECTED;
}
CString CEntity::GetClassname
(
void
) const
{
CString MyClassname = "";
this->GetKeyValue (CLASSNAME, MyClassname);
return MyClassname;
}
CString CEntity::GetName
(
void
) const
{
CString MyName = "";
this->GetKeyValue ("%name%", MyName);
return MyName;
}
CEntity& CEntity::operator=( CEntity& Entity )
{
EntityStyle = Entity.EntityStyle;
mFlags = Entity.mFlags;
mGroup = Entity.mGroup;
mOrigin = Entity.mOrigin;
mKeyArray.RemoveAll();
mValueArray.RemoveAll();
// copy the key/value entries
CString Key, Value;
for( int Current = 0; Current < Entity.GetNumKeyValuePairs (); Current++ )
{
if (Entity.GetKeyValuePair (Current, Key, Value))
{
this->SetKeyValue (Key, Value);
}
}
return *this;
}
// Key/value string manipulation
int CEntity::GetKeyIndex (const char *Key) const
{
int CurrentString;
int NumberOfStrings = mKeyArray.GetSize();
// go through the array of entities
for( CurrentString = 0; CurrentString < NumberOfStrings; CurrentString++ ) {
if( !mKeyArray[CurrentString].CompareNoCase(Key) )
return CurrentString;
}
return -1;
}
void CEntity::SetKeyValue (const char *Key, const char *Value)
{
int KeyNo;
ASSERT (Key != NULL);
ASSERT (*Key != '\0'); // no empty key strings
ASSERT (Value != NULL);
KeyNo = this->GetKeyIndex (Key);
if (KeyNo == -1)
{
// doesn't exist, add it...
// the arrays must be the same size...
ASSERT (this->mKeyArray.GetSize () == this->mValueArray.GetSize ());
this->mKeyArray.Add (Key);
this->mValueArray.Add (Value);
}
else
{
this->mValueArray[KeyNo] = Value;
}
}
BOOL CEntity::GetKeyValue (const char *Key, char *Value) const
{
CString ValueString;
if (this->GetKeyValue (Key, ValueString))
{
strcpy (Value, ValueString);
return TRUE;
}
return FALSE;
}
BOOL CEntity::GetKeyValue (const char *Key, CString &Value) const
{
int KeyNo;
KeyNo = this->GetKeyIndex (Key);
if (KeyNo == -1)
{
return FALSE;
}
Value = this->mValueArray[KeyNo];
return TRUE;
}
int CEntity::GetNumKeyValuePairs
(
void
) const
{
return this->mKeyArray.GetSize ();
}
BOOL CEntity::GetKeyValuePair
(
int Index,
CString &Key,
CString &Value
) const
{
if (Index < this->GetNumKeyValuePairs ())
{
Key = mKeyArray[Index];
Value = mValueArray[Index];
return TRUE;
}
return FALSE;
}
// update our origin
void CEntity::UpdateOrigin (const EntityTable *pEntityDefs)
{
// find our origin
CString OriginStr;
// if we empty leave
if (!GetOriginString (OriginStr, pEntityDefs))
{
EntityStyle = ENTITY_S_BRUSH;
return;
}
else {
EntityStyle = ENTITY_S_ORIGIN;
}
// get our x y z
int x, y, z;
sscanf(OriginStr, "%d %d %d", &x, &y, &z);
// assign them
geVec3d_Set (&mOrigin, (geFloat)x, (geFloat)y, (geFloat)z);
}
BOOL CEntity::GetOriginFieldName
(
CString &FieldName,
const EntityTable *pEntityDefs
) const
{
CString Classname;
if (!this->GetKeyValue (CLASSNAME, Classname))
{
return FALSE;
}
return EntityTable_GetEntityOriginFieldName (pEntityDefs, Classname, FieldName);
}
BOOL CEntity::SetOrigin
(
geFloat x,
geFloat y,
geFloat z,
const EntityTable *pEntityDefs
)
{
CString OriginFieldName;
geVec3d_Set (&mOrigin, x, y, z);
if (GetOriginFieldName (OriginFieldName, pEntityDefs))
{
CString NewOriginString;
NewOriginString.Format ("%d %d %d", (int)x, (int)y, (int)z);
// update the origin string
SetKeyValue (OriginFieldName, NewOriginString);
}
return TRUE;
}
BOOL CEntity::GetOriginString
(
CString &OriginStr,
const EntityTable *pEntityDefs
) const
{
CString OriginFieldName;
if (!GetOriginFieldName (OriginFieldName, pEntityDefs) || OriginFieldName.IsEmpty ())
{
return FALSE;
}
return this->GetKeyValue (OriginFieldName, OriginStr);
}
BOOL CEntity::GetSpecialField
(
EntityTable_GetFieldFunc Callback,
CString &FieldValue,
const EntityTable *pEntityDefs
) const
{
CString Classname;
if (GetKeyValue (CLASSNAME, Classname))
{
CString FieldName;
if (Callback (pEntityDefs, Classname, FieldName))
{
return GetKeyValue (FieldName, FieldValue);
}
}
return FALSE;
}
BOOL CEntity::SetSpecialField
(
EntityTable_GetFieldFunc Callback,
CString const FieldValue,
const EntityTable *pEntityDefs
)
{
CString Classname;
if (GetKeyValue (CLASSNAME, Classname))
{
CString FieldName;
if (Callback (pEntityDefs, Classname, FieldName))
{
SetKeyValue (FieldName, FieldValue);
return TRUE;
}
}
return FALSE;
}
// Angles are stored here in degrees, but reported in radians
BOOL CEntity::GetAngles (geVec3d *pDir, const EntityTable *pEntityDefs) const
{
CString FieldValue;
if (GetSpecialField (EntityTable_GetEntityAnglesFieldName, FieldValue, pEntityDefs))
{
geVec3d Degrees;
sscanf (FieldValue, "%f %f %f", &Degrees.X, &Degrees.Y, &Degrees.Z);
geVec3d_Set (pDir, Units_DegreesToRadians (Degrees.X),Units_DegreesToRadians (Degrees.Y),Units_DegreesToRadians (Degrees.Z));
return TRUE;
}
return FALSE;
}
BOOL CEntity::SetAngles (const geVec3d *pDir, const EntityTable *pEntityDefs)
{
CString FieldValue;
geVec3d Degrees;
geVec3d_Set (&Degrees, Units_RadiansToDegrees (pDir->X), Units_RadiansToDegrees (pDir->Y), Units_RadiansToDegrees (pDir->Z)) ;
FieldValue.Format ("%f %f %f", Degrees.X, Degrees.Y, Degrees.Z);
return SetSpecialField (EntityTable_GetEntityAnglesFieldName, FieldValue, pEntityDefs);
}
/*
The arc value is stored as an integer degrees, and returned as a float radians.
*/
BOOL CEntity::GetArc (geFloat *pArc, const EntityTable *pEntityDefs) const
{
CString FieldValue;
if (GetSpecialField (EntityTable_GetEntityArcFieldName, FieldValue, pEntityDefs))
{
int ArcDegrees;
sscanf (FieldValue, "%d", &ArcDegrees);
*pArc = Units_DegreesToRadians (ArcDegrees);
return TRUE;
}
return FALSE;
}
// SetArc takes a floating point radians value but stores the arc as an integer
// number of degrees.
BOOL CEntity::SetArc (geFloat Arc, const EntityTable *pEntityDefs)
{
CString FieldValue;
int ArcDegrees;
ArcDegrees = Units_Round (Units_RadiansToDegrees (Arc));
if( ArcDegrees > 359 )
ArcDegrees = 359 ;
if( ArcDegrees < 0 )
ArcDegrees = 0 ;
FieldValue.Format ("%d", ArcDegrees);
return SetSpecialField (EntityTable_GetEntityArcFieldName, FieldValue, pEntityDefs);
}
BOOL CEntity::GetRadius (geFloat *pRadius, const EntityTable *pEntityDefs) const
{
CString FieldValue;
if (GetSpecialField (EntityTable_GetEntityRadiusFieldName, FieldValue, pEntityDefs))
{
sscanf (FieldValue, "%f", pRadius);
return TRUE;
}
return FALSE;
}
BOOL CEntity::SetRadius (geFloat Radius, const EntityTable *pEntityDefs)
{
CString FieldValue;
FieldValue.Format ("%f", Radius);
return SetSpecialField (EntityTable_GetEntityRadiusFieldName, FieldValue, pEntityDefs);
}
void CEntity::Export(FILE *OutFile)
{
int i;
fprintf( OutFile, "{\n");
for(i = 0; i < this->GetNumKeyValuePairs (); i++)
{
CString KeyS, ValueS;
if (this->GetKeyValuePair (i, KeyS, ValueS))
{
fprintf (OutFile, "\"%s\" \"%s\"\n", (LPCSTR)KeyS, (LPCSTR)ValueS);
}
}
}
float CEntity::DistanceFrom (geVec3d const *pPoint)
{
return geVec3d_DistanceBetween (pPoint, &mOrigin);
}
float CEntity::RayDistance(CPoint point, ViewVars *v)
{
if(EntityStyle!=ENTITY_S_ORIGIN)
return 0;
//first check the entity bounds to see if the click is inside
geVec3d box[8], wPoint;
CPoint min, max, pnt;
min.x=min.y=9999;
max.x=max.y=-9999;
float xPlus8 = (float)(mOrigin.X + 8.0);
float xMinus8 = (float)(mOrigin.X - 8.0);
float yPlus8 = (float)(mOrigin.Y + 8.0);
float yMinus8 = (float)(mOrigin.Y - 8.0);
float zPlus8 = (float)(mOrigin.Z + 8.0);
float zMinus8 = (float)(mOrigin.Z - 8.0);
geVec3d_Set (&box[0], xPlus8, yPlus8, zPlus8);
geVec3d_Set (&box[1], xMinus8, yPlus8, zPlus8);
geVec3d_Set (&box[2], xMinus8, yMinus8, zPlus8);
geVec3d_Set (&box[3], xPlus8, yMinus8, zPlus8);
geVec3d_Set (&box[4], xPlus8, yPlus8, zMinus8);
geVec3d_Set (&box[5], xMinus8, yPlus8, zMinus8);
geVec3d_Set (&box[6], xMinus8, yMinus8, zMinus8);
geVec3d_Set (&box[7], xPlus8, yMinus8, zMinus8);
// BOOL anyIn=false;
for(int i=0;i<8;i++)
{
wPoint =Render_XFormVert(v, &box[i]);
pnt.x = (long)(wPoint.X);
pnt.y = (long)(wPoint.Y);
//anyIn=(anyIn || PtInRect(Camera.mClip, pnt));
if(pnt.x < min.x) min.x=pnt.x;
if(pnt.x > max.x) max.x=pnt.x;
if(pnt.y < min.y) min.y=pnt.y;
if(pnt.y > max.y) max.y=pnt.y;
}
if((point.x > min.x && point.x < max.x)
&&(point.y > min.y && point.y < max.y))
{
Render_GetCameraPos(v, &wPoint);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -