⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 entity.cpp

📁 3D游戏场景编辑器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************************/
/*  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 + -