Files
2025-03-05 08:37:43 +01:00

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();
}
}