245 lines
6.7 KiB
C
245 lines
6.7 KiB
C
/*
|
|
* PVVMUD a 3D MUD
|
|
* Copyright (C) 1998-1999 Programvareverkstedet (pvv@pvv.org)
|
|
*
|
|
* 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 2 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, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
#include "pvvmud.H"
|
|
#include "worldobject.H"
|
|
#include "worldworld.H"
|
|
#include "waupdateposition.H"
|
|
#include "waupdatedirection.H"
|
|
#include "warotate.H"
|
|
|
|
CWorldObject::CWorldObject(DWORD objectId, CWorldHierarchy * parent, DWORD geometryId, const CPosition & position, const CDirection & direction):CWorldHierarchy(objectId,parent){
|
|
m_geometryId = geometryId;
|
|
m_bBox = NULL;
|
|
m_BSDTree = NULL;
|
|
m_collidable = 0;
|
|
m_cellPVS = NULL;
|
|
_updatePosition(position);
|
|
_updateDirection(direction);
|
|
}
|
|
|
|
CWorldObject::~CWorldObject(){
|
|
if (m_bBox != NULL) delete m_bBox;
|
|
if (m_BSDTree != NULL) delete m_BSDTree;
|
|
if (m_cellPVS != NULL) delete m_cellPVS;
|
|
}
|
|
|
|
DWORD CWorldObject::getGeometryId(){
|
|
return m_geometryId;
|
|
}
|
|
|
|
CPosition & CWorldObject::getPosition(){
|
|
return m_position;
|
|
}
|
|
|
|
CDirection & CWorldObject::getDirection(){
|
|
return m_direction;
|
|
}
|
|
|
|
char * CWorldObject::getObjectType(){
|
|
return "object";
|
|
}
|
|
|
|
CWorldObject * CWorldObject::getMasterCell(){
|
|
|
|
if (getParentId() == ID_UNKNOWN) return this;
|
|
|
|
CWorldObject * parent = (CWorldObject*)getParent();
|
|
|
|
if (parent != NULL) return parent->getMasterCell();
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CGeometry * CWorldObject::getGeometry(){
|
|
cdebug << "CWorldObject::getGeometry: Not overloaded!\n";
|
|
return NULL;
|
|
}
|
|
|
|
|
|
CPVCell* CWorldObject::addPVCell(DWORD PVCellId, const CPosition & position){
|
|
if (m_cellPVS == NULL) m_cellPVS = new CCellPVS(getWorld());
|
|
return m_cellPVS->addPVCell(PVCellId,position);
|
|
}
|
|
|
|
CCellPVS* CWorldObject::getPVS(){
|
|
return m_cellPVS;
|
|
}
|
|
|
|
|
|
void CWorldObject::updatePosition( const CPosition & position ){
|
|
// cdebug << "CWorldObject::updatePosition " << position << " on object " << getObjectId() << "\n";
|
|
|
|
CWorldWorld * world = getWorld();
|
|
world->addAnimation(new CWAUpdatePosition(getObjectId(),position), this );
|
|
}
|
|
|
|
void CWorldObject::updateDirection( const CDirection & direction ){
|
|
// cdebug << "CWorldObject::updateDirection " << direction << " on object " << getObjectId() << "\n";
|
|
|
|
CWorldWorld * world = getWorld();
|
|
world->addAnimation(new CWAUpdateDirection(getObjectId(),direction), this );
|
|
}
|
|
|
|
void CWorldObject::rotate( const CDirection & angleSpeed ){
|
|
// cdebug << "CWorldObject::rotate " << angleSpeed << " on object " << getObjectId() << "\n";
|
|
|
|
CWorldWorld * world = getWorld();
|
|
world->addAnimation(new CWARotate(getObjectId(),angleSpeed), this );
|
|
}
|
|
|
|
void CWorldObject::_updateDirection( const CDirection & direction ){
|
|
// cdebug << "CWorldObject::_updateDirection " << direction << " on object " << getObjectId() << "\n";
|
|
m_direction = direction;
|
|
}
|
|
|
|
void CWorldObject::_updatePosition( const CPosition & position ){
|
|
// cdebug << "CWorldObject::_updatePosition " << position << " on object " << getObjectId() << "\n";
|
|
m_position = position;
|
|
}
|
|
|
|
void CWorldObject::setBBox( CBBox * bBox ){
|
|
m_bBox = bBox;
|
|
}
|
|
|
|
CBBox * CWorldObject::getBBox( ){
|
|
return m_bBox;
|
|
}
|
|
|
|
void CWorldObject::setCollidable(BYTE coll){
|
|
m_collidable =coll;
|
|
}
|
|
|
|
BYTE CWorldObject::getCollidable(){
|
|
return m_collidable ;
|
|
}
|
|
|
|
void CWorldObject::setBSDTree( CBSDTree * BSDTree ){
|
|
m_BSDTree = BSDTree;
|
|
}
|
|
|
|
CBSDTree * CWorldObject::getBSDTree( ){
|
|
return m_BSDTree;
|
|
}
|
|
|
|
CWorldObject * CWorldObject::createObject( char * objectName, DWORD objectId,
|
|
DWORD geometryId, const CPosition & position, const CDirection & direction ){
|
|
|
|
CWorldObject * object =
|
|
getWorld()->newObject(objectName, objectId,this,geometryId,position,direction);
|
|
addObject( object );
|
|
return object;
|
|
}
|
|
|
|
int CWorldObject::checkPosition(const CPosition & position){
|
|
if (m_BSDTree != NULL) return m_BSDTree->inside( position );
|
|
else if (getBBox() != NULL) return getBBox()->inside( position );
|
|
else return FALSE;
|
|
}
|
|
|
|
int CWorldObject::moveTo( CWorldObject * parent ){
|
|
|
|
setParent( parent );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CWorldObject::getGlobalTransform( CMatrix & transform ){
|
|
getTransform( transform );
|
|
|
|
if (getParentId() != ID_UNKNOWN){
|
|
CWorldObject * parent = (CWorldObject*)getParent();
|
|
if (parent != NULL) parent->getGlobalTransform( transform );
|
|
}
|
|
}
|
|
|
|
void CWorldObject::getTransform( CMatrix & transform ){
|
|
transform.translate( getPosition() );
|
|
transform.rotate( getDirection() );
|
|
}
|
|
|
|
void CWorldObject::getInvGlobalTransform( CMatrix & transform ){
|
|
getInvTransform( transform );
|
|
if (getParentId() != ID_UNKNOWN){
|
|
CWorldObject * parent = (CWorldObject*)getParent();
|
|
if (parent != NULL) parent->getInvGlobalTransform( transform );
|
|
}
|
|
}
|
|
|
|
void CWorldObject::getInvTransform( CMatrix & transform ){
|
|
transform.rotate( -getDirection() );
|
|
transform.translate( -getPosition() );
|
|
}
|
|
|
|
void CWorldObject::distances(CDoubleArray & distArray, const CBeam & beam,
|
|
double min, double max){
|
|
|
|
if (m_collidable ) return;
|
|
|
|
CGeometry * geometry = getGeometry();
|
|
|
|
CMatrix transform;
|
|
getInvTransform(transform);
|
|
|
|
CBeam objBeam = beam;
|
|
objBeam.transform(transform);
|
|
|
|
if (geometry != NULL){
|
|
if ( objBeam.intersect(geometry->calculateBBox())){
|
|
cdebug << "CWorldObject( " << getName()
|
|
<< " )::distances: Beam " << objBeam << "\n";
|
|
geometry->distances(distArray,objBeam,min,max);
|
|
|
|
// Test sub objects
|
|
CObjectListItem * item = getFirst();
|
|
while (item != NULL){
|
|
CWorldObject * obj = (CWorldObject*)item->getObject();
|
|
|
|
obj->distances(distArray,objBeam,min,max);
|
|
|
|
item = item->getNext();
|
|
}
|
|
} else {
|
|
cdebug << "CWorldObject( " << getName()
|
|
<< " )::distances: Don't intersect!\n";
|
|
}
|
|
} else {
|
|
cdebug << "CWorldObject( " << getName()
|
|
<< " )::distances: Don't have geometry!\n";
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void CWorldObject::dump(int tab){
|
|
int ii;
|
|
for (ii = 0; ii < tab; ii++) cdebug << "\t";
|
|
cdebug << "Object: Id: " << getObjectId() << " Geo: " << getGeometryId() << " Pos: " << getPosition() << " Dir: " << getDirection() << "\n";
|
|
|
|
CObjectListItem * item = getFirst();
|
|
while (item != NULL){
|
|
CWorldObject * object = (CWorldObject*)item->getObject();
|
|
object->dump(tab+1);
|
|
item = item->getNext();
|
|
}
|
|
|
|
}
|
|
|
|
|