123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- //----------------------------------------------------------------------------
- //
- // Link.cpp -
- //
- //---------------------------------------------------------------------------//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- #include "mclib.h"
- #include "BuildingLink.h"
- #include "EditorObjectMgr.h"
- #include <algorithm>
- #include "celine.h"
- BuildingLink::BuildingLink( const EditorObject* pParent )
- {
- gosASSERT( pParent );
-
- parent.m_ID = pParent->getID();
- parent.pos = pParent->getPosition();
- }
- BuildingLink::BuildingLink( const Stuff::Vector3D& pos )
- {
- parent.pos = pos;
- parent.m_ID = -1;
- }
- BuildingLink::BuildingLink( const BuildingLink& Src )
- {
- CopyData( Src );
- }
- BuildingLink& BuildingLink::operator=( const BuildingLink& Src )
- {
- if ( &Src != this )
- {
- CopyData( Src );
- }
- return *this;
- }
- void BuildingLink::CopyData( const BuildingLink& Src )
- {
- parent = Src.parent;
- children.Clear();
- for ( EList< Info, const Info& >::EConstIterator iter = Src.children.Begin();
- !iter.IsDone(); iter++ )
- {
- children.Append( *iter );
- }
- }
- bool BuildingLink::AddChild( const EditorObject* pObject )
- {
- int ID = pObject->getID();
-
- for( EList< Info, const Info& >::EIterator iter = children.Begin();
- !iter.IsDone(); iter++ )
- {
- if ( (*iter).pos == pObject->getPosition() &&
- (*iter).m_ID == ID )
- {
- SPEW( (0, "Link::AddChild, not adding an object because it is"
- "already there\n" ) );
- return false;
- }
- }
- Info tmp;
- tmp.pos = pObject->getPosition();
- tmp.m_ID = ID;
- children.Append( tmp );
- return true;
- }
- int BuildingLink::GetLinkCount( ) const
- {
- return children.Count();
- }
- const Stuff::Vector3D& BuildingLink::GetParentPosition() const
- {
- return parent.pos;
- }
- bool BuildingLink::HasChild( const EditorObject* pObject ) const
- {
- int ID = pObject->getID();
- pObject->getPosition();
-
- for( EList< Info, const Info& >::EConstIterator iter = children.Begin();
- !iter.IsDone(); iter++ )
- {
- if ( (*iter).pos == pObject->getPosition() )
- {
- if ( (*iter).m_ID == ID )
- return true;
- }
- }
- return false;
- }
- bool BuildingLink::HasParent( const EditorObject* pObject ) const
- {
- int ID = pObject->getID();
- // ignore damage bit and rotation
- if ( parent.pos == pObject->getPosition() && parent.m_ID == ID )
- return true;
- return false;
- }
- bool BuildingLink::TypeCanBeParent( const EditorObject* pObject )
- {
- int Type = pObject->getSpecialType();
- switch (Type)
- {
- case EditorObjectMgr::TURRET_CONTROL:
- case EditorObjectMgr::GATE_CONTROL:
- case EditorObjectMgr::POWER_STATION:
- case EditorObjectMgr::SENSOR_CONTROL:
- case EditorObjectMgr::TURRET_GENERATOR:
- case EditorObjectMgr::BRIDGE_CONTROL:
- case EditorObjectMgr::SPOTLIGHT_CONTROL:
- return true;
- break;
- default:
- break;
- };
- return false;
- }
- bool BuildingLink::CanLink( const EditorObject* pParent, const EditorObject* pChild )
- {
- int ParentType = pParent->getSpecialType();
- int ChildType = pChild->getSpecialType();
-
- switch (ParentType)
- {
- case EditorObjectMgr::TURRET_CONTROL:
- return (ChildType == EditorObjectMgr::EDITOR_TURRET
- || ChildType == EditorObjectMgr::LOOKOUT ) ? true : false;
- break;
- case EditorObjectMgr::GATE_CONTROL:
- return ChildType == EditorObjectMgr::EDITOR_GATE ? true : false;
- break;
- case EditorObjectMgr::POWER_STATION:
- return (ChildType == EditorObjectMgr::BRIDGE_CONTROL
- || ChildType == EditorObjectMgr::GATE_CONTROL
- || ChildType == EditorObjectMgr::SPOTLIGHT_CONTROL ) ? true : false;
- break;
- case EditorObjectMgr::SENSOR_CONTROL:
- return ChildType == EditorObjectMgr::SENSOR_TOWER ? true : false;
- break;
- case EditorObjectMgr::TURRET_GENERATOR:
- return ChildType == EditorObjectMgr::TURRET_CONTROL ? true : false;
- break;
- case EditorObjectMgr::SPOTLIGHT_CONTROL:
- return ChildType == EditorObjectMgr::SPOTLIGHT ? true : false;
- break;
- case EditorObjectMgr::BRIDGE_CONTROL:
- return ChildType == EditorObjectMgr::EDITOR_BRIDGE ? true : false;
- break;
- default:
- break;
- };
- return false;
- }
- bool BuildingLink::RemoveObject( const EditorObject* pObject )
- {
- if ( HasParent( pObject ) )
- {
- SPEW(( 0, "BuildingLink::RemoveObject could not remove a parent object\n") );
- return false;
- }
- Stuff::Vector3D pos = pObject->getPosition( );
- long ID = pObject->getID();
-
- for ( EList< Info, const Info& >::EIterator iter = children.Begin();
- !iter.IsDone(); iter++ )
- {
- if ( ID == (*iter).m_ID && pos == (*iter).pos )
- {
- children.Delete( iter );
- return true;
- }
- }
- SPEW(( 0, "BuildingLInk::RemoveObject failed because it didn't have the object\n") );
- return false;
- }
- int BuildingLink::GetChildrenPositions( Stuff::Vector3D* pos, int Count ) const
- {
- if ( children.Count() > (unsigned long)Count )
- return children.Count();
- int i = 0;
- for ( EList< Info, const Info& >::EConstIterator iter = children.Begin();
- !iter.IsDone(); iter++ )
- {
- pos[i++] = (*iter).pos;
- }
- return i;
- }
- static bool isInView(const Point3D &position)
- {
- /* the code in this function was largely swiped from "bool BldgAppearance::recalcBounds (void)" on 4/24/00 */
- bool inView = false;
- if (eye)
- {
- //--------------------------------------------------
- // First, if we are using perspective, figure out
- // if object too far from camera. Far Clip Plane.
- if (eye->usePerspective)
- {
- Stuff::Point3D Distance;
- Stuff::Point3D eyePosition(eye->getPosition());
- Stuff::Point3D objPosition(position);
-
- Distance.Subtract(objPosition,eyePosition);
- float eyeDistance = Distance.GetApproximateLength();
- if (eyeDistance > Camera::MaxClipDistance)
- {
- //hazeFactor = 1.0f;
- inView = false;
- }
- else if (eyeDistance > Camera::MinHazeDistance)
- {
- Camera::HazeFactor = (eyeDistance - Camera::MinHazeDistance) * Camera::DistanceFactor;
- inView = true;
- }
- else
- {
- Camera::HazeFactor = 0.0f;
- inView = true;
- }
-
- //-----------------------------------------------------------------
- // If inside farClip plane, check if behind camera.
- // Find angle between lookVector of Camera and vector from camPos
- // to Target. If angle is less then halfFOV, object is visible.
- if (inView)
- {
- Stuff::Vector3D Distance;
- Stuff::Point3D objPosition;
- Stuff::Point3D eyePosition(eye->getCameraOrigin());
- objPosition.x = -position.x;
- objPosition.y = position.z;
- objPosition.z = position.y;
-
- Distance.Subtract(objPosition,eyePosition);
- Distance.Normalize(Distance);
-
- float cosine = Distance * eye->getLookVector();
- if (cosine > eye->cosHalfFOV)
- inView = true;
- else
- inView = false;
- }
- }
- else
- {
- Camera::HazeFactor = 0.0f;
- inView = true;
- }
- }
-
- return(inView);
- }
- void BuildingLink::render()
- {
- Stuff::Vector4D parentScreen;
- eye->projectZ( parent.pos, parentScreen );
- Stuff::Vector4D childScreen;
-
- for ( EList< Info, const Info& >::EConstIterator iter = children.Begin();
- !iter.IsDone(); iter++ )
- {
- /* Rather than doing true clipping, the link lines are broken into "typical object"
- sized pieces and rendered using course culling and relying on guard band clipping
- in the fashion that buildings are rendered. */
- Stuff::Vector3D diffVect;
- diffVect.Subtract((*iter).pos, parent.pos);
- float lineLength = diffVect.GetLength();
- const float lengthOfATypicalLargeObject = 150.0/*arbitrary*/;
- int numSegments = lineLength / lengthOfATypicalLargeObject;
- if (1 > numSegments)
- {
- numSegments = 1;
- }
- float segmentLength = lineLength / numSegments;
- Stuff::Vector3D segVect = diffVect;
- segVect.Normalize(segVect);
- segVect *= segmentLength;
- Stuff::Point3D p1(parent.pos.x, parent.pos.y, parent.pos.z);
- bool p1IsInView = isInView(p1);
- int i;
- for (i = 0 ; i < numSegments; i += 1)
- {
- Stuff::Point3D p2 = p1;
- p2 += segVect;
- bool p2IsInView = isInView(p2);
- if (p1IsInView || p2IsInView)
- {
- Stuff::Vector4D screenPos1;
- eye->projectZ( p1, screenPos1 );
- Stuff::Vector4D screenPos2;
- eye->projectZ( p2, screenPos2 );
- Stuff::Vector4D vertices[2];
- vertices[0].x = screenPos1.x;
- vertices[0].y = screenPos1.y;
- vertices[1].x = screenPos2.x;
- vertices[1].y = screenPos2.y;
- vertices[0].z = vertices[1].z = 0.1f;
- vertices[0].w = vertices[1].w = 0.9999f;
- LineElement elem( vertices[0], vertices[1], 0xffff0000, 0, -1 );
- elem.draw();
- }
- p1 = p2;
- p1IsInView = p2IsInView;
- }
- }
-
- }
- void BuildingLink::SetParentAlignment( int alignment )
- {
- EditorObject* pTmp = EditorObjectMgr::instance()->getObjectAtLocation( parent.pos.x, parent.pos.y );
- if ( pTmp )
- pTmp->setAlignment( alignment ) ;
- else
- {
- gosASSERT(false);
- }
- for ( EList<Info, const Info& >::EConstIterator iter = children.Begin();
- !iter.IsDone(); iter++ )
- {
- pTmp = EditorObjectMgr::instance()->getObjectAtLocation( (*iter).pos.x, (*iter).pos.y ) ;
- if ( pTmp )
- pTmp->setAlignment( alignment );
- else
- {
- gosASSERT(false);
- }
- }
- }
- void BuildingLink::FixHeights()
- {
- parent.pos.z = land->getTerrainElevation( parent.pos );
- for ( EList<Info, const Info& >::EIterator iter = children.Begin();
- !iter.IsDone(); iter++ )
- {
- (*iter).pos.z = land->getTerrainElevation((*iter).pos );
- }
- }
- void BuildingLink::SetParentPosition( const Stuff::Vector3D& pos )
- {
- parent.pos = pos;
- }
|