Show klandmark.cpp syntax highlighted
/*
Copyright (C) 2003, 2004, 2005 by Luca Cappa
Written by Luca Cappa groton@users.sourceforge.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//
//??
//remember that KLandmark does not need an UpdateMove () call, while KSprite3D needs it!
#include "cssysdef.h"
#include "csutil/sysfunc.h"
#include "csutil/cscolor.h"
#include "csutil/cmdhelp.h"
#include "csutil/cspmeter.h"
#include "csutil/csstring.h"
#include "csutil/scfstr.h"
#include "csutil/array.h"
#include "cstool/csview.h"
#include "cstool/initapp.h"
#include "cstool/collider.h"
#include "iutil/vfs.h"
#include "iutil/eventq.h"
#include "iutil/event.h"
#include "iutil/objreg.h"
#include "iutil/csinput.h"
#include "iutil/virtclk.h"
#include "iutil/plugin.h"
#include "iutil/string.h"
#include "iutil/document.h"
#include "iengine/sector.h"
#include "iengine/engine.h"
#include "iengine/camera.h"
#include "iengine/light.h"
#include "iengine/texture.h"
#include "iengine/mesh.h"
#include "iengine/movable.h"
#include "iengine/material.h"
#include "imesh/thing.h"
#include "imesh/object.h"
#include "ivideo/graph3d.h"
#include "ivideo/graph2d.h"
#include "ivideo/natwin.h"
#include "ivideo/txtmgr.h"
#include "ivideo/texture.h"
#include "ivideo/material.h"
#include "ivideo/fontserv.h"
#include "igraphic/imageio.h"
#include "ivaria/reporter.h"
#include "ivaria/stdrep.h"
#include "ivaria/conout.h"
#include "ivaria/reporter.h"
#include "ivaria/stdrep.h"
#include "ivaria/collider.h"
#include "csgeom/quaterni.h"
#include "csgeom/transfrm.h"
#include "csgeom/math3d_d.h"
#include "csgeom/math3d.h"
#include "igeom/polymesh.h"
#include "igeom/objmodel.h"
#include "imap/loader.h"
#include "iaws/aws.h"
#include "iaws/awscnvs.h"
#include "korientation.h"
#include "kblock.h"
#include "kmap.h"
#include "kblockid.h"
#include "kflags.h"
#include "ksprite3d.h"
#include "kappstate.h"
#include "ske.h"
#include "kutil.h"
//Include for this file.
#include "klandmark.h"
SCF_IMPLEMENT_IBASE_EXT (KLandmark)
SCF_IMPLEMENTS_INTERFACE (KLandmark)
SCF_IMPLEMENTS_INTERFACE (iKXMLWriter)
SCF_IMPLEMENTS_INTERFACE (iKXMLReader)
SCF_IMPLEMENT_IBASE_EXT_END
SCF_IMPLEMENT_IBASE (KLandmark::KLocalDraggable)
SCF_IMPLEMENTS_INTERFACE (iKDraggable)
SCF_IMPLEMENT_IBASE_END
SCF_IMPLEMENT_IBASE (KLandmark::KLocalDragHandler)
SCF_IMPLEMENTS_INTERFACE (iKDragHandler)
SCF_IMPLEMENT_IBASE_END
KLandmark::KLandmark (): m_position (0,0,0), m_yRotation (0),
m_visible (true)
{
SCF_CONSTRUCT_IBASE (0);
scfiKLocalDragHandler = new KLocalDragHandler (this);
scfiKLocalDraggable = new KLocalDraggable (this);
m_name = 0;
//
//Set the internal draggable interface.
scfiKLocalDraggable->SetDragHandler (scfiKLocalDragHandler);
}
KLandmark::~KLandmark ()
{
scfiKLocalDragHandler->DecRef ();//??
scfiKLocalDraggable->DecRef ();//??
SCF_DESTRUCT_IBASE ();
}
void KLandmark::Release ()
{
//I do this cause the ObjAdd in AddKSprite3D does an increfing of the
//KSprite3D.
this->ObjRemoveAll ();
//Release all the ksprite3ds.
size_t i;
for (i = 0; i < m_ksprite3dList.Length (); i++)
m_ksprite3dList[i]->Release ();
}
void KLandmark::AddKSprite3D (KSprite3D* p_spr3d, const csVector3& p_offset)
{
//Builds the KLandmark->(KSprite3D, KSprite3D, ...) hierarchy.
this->ObjAdd (p_spr3d);
//
//Substitute the KSprite3D default drag handler with the KLandmark's one.
p_spr3d->SetDraggable (scfiKLocalDraggable);
scfiKLocalDraggable->SetDragHandler (scfiKLocalDragHandler);
//
//Add this landmark (more specifically add its iKDraggable interface) to
//the iMeshWrapper's iObject.
p_spr3d->GetMeshWrapper ()->QueryObject ()->ObjAdd (scfiKLocalDraggable);
m_ksprite3dList.Push (p_spr3d);
m_offsets.Push (csVector3 (p_offset));
}
void KLandmark::SetSector (iSector* p_sector)
{
size_t i;
for (i = 0; i < m_ksprite3dList.Length (); i++)
{
//Get the KSprite3D.
csRef<KSprite3D> l_ks3d = m_ksprite3dList.Get (i);
l_ks3d->SetSector (p_sector);
l_ks3d->UpdateMove ();
}//for
}
/**
Returns a box containing all the sprites: ie
the union of all boxes offsetted by their offset.
*/
csBox3 KLandmark::GetBoundingBox ()
{
csBox3 l_unionBox;
size_t i;
for (i = 0; i < m_ksprite3dList.Length (); i++)
{
//Get the KSprite3D.
csRef<KSprite3D> l_s3d = m_ksprite3dList.Get (i);
csBox3 l_box;
l_s3d->GetBoundingBox (l_box);
//Add the offset to the box (ie translate it)
l_box.SetCenter (m_offsets.Get(i));
//Compute the union
l_unionBox += l_box;
}//for
return l_unionBox;
}
csVector3 KLandmark::GetSize ()
{
return GetBoxSize (GetBoundingBox ());
}
void KLandmark::SetSize (const csVector3& p_size)
{
size_t i;
csBox3 l_origBox = GetBoundingBox ();
csBox3 l_newBox;
l_newBox.StartBoundingBox (csVector3 (0, 0, 0));
l_newBox.AddBoundingVertex (p_size);
float l_xScalingFactor = (l_newBox.MaxX () - l_newBox.MinX ()) /
(l_origBox.MaxX () - l_origBox.MinX ());
float l_yScalingFactor = (l_newBox.MaxY () - l_newBox.MinY ()) /
(l_origBox.MaxY () - l_origBox.MinY ());
float l_zScalingFactor = (l_newBox.MaxZ () - l_newBox.MinZ ()) /
(l_origBox.MaxZ () - l_origBox.MinZ ());
//
//Resize all the offsets.
csArray<csVector3> l_newOffsets;
for (i = 0; i < m_offsets.Length(); i++)
{
csVector3 l_v = m_offsets.Get (i);
l_newOffsets.Push (csVector3 (l_v.x * l_xScalingFactor,
l_v.y * l_yScalingFactor, l_v.z * l_zScalingFactor));
}//for
m_offsets.DeleteAll ();
for (i = 0; i < m_ksprite3dList.Length(); i++)
m_offsets.Push (l_newOffsets.Get (i));
//
//Change the size of all sprites.
for (i = 0; i < m_ksprite3dList.Length(); i++)
{
csRef<KSprite3D> l_ks3d = m_ksprite3dList.Get (i);
csBox3 l_box;
l_ks3d->GetBoundingBox (l_box);
csVector3 l_size = GetBoxSize (l_box);
float l_xSize = l_size.x * l_xScalingFactor;
float l_ySize = l_size.y * l_yScalingFactor;
float l_zSize = l_size.z * l_zScalingFactor;
l_ks3d->Resize (l_xSize, l_ySize, l_zSize);
}//for
}
csVector3 const& KLandmark::GetPosition ()
{
return m_position;
}
csVector3& KLandmark::GetOffset (int p_i)
{
return (m_offsets.Get (p_i));
}
float KLandmark::GetYRotation ()
{
return m_yRotation;
}
void KLandmark::SetPosition (csVector3 const& p_pos)
{
m_position = p_pos;
size_t i;
for (i = 0; i < m_ksprite3dList.Length(); i++)
{
csRef<KSprite3D> l_ks3d = m_ksprite3dList.Get (i);
csYRotMatrix3 l_mat (m_yRotation);
csReversibleTransform l_transf (l_mat, m_position);
const csVector3& l_curVec = (m_offsets.Get (i));
l_ks3d->SetYRotationPosition (m_yRotation,
m_position + l_transf.Other2ThisRelative (l_curVec));
l_ks3d->UpdateMove ();
}//for
}
void KLandmark::SetYRotation (float p_yRotation)
{
m_yRotation = p_yRotation;
size_t i;
for (i = 0; i < m_ksprite3dList.Length(); i++)
{
csRef<KSprite3D> l_ks3d = m_ksprite3dList.Get (i);
csYRotMatrix3 l_mat (p_yRotation);
csReversibleTransform l_transf (l_mat, this->m_position);
const csVector3& l_curVec = (this->m_offsets.Get (i));
l_ks3d->SetYRotationPosition (m_yRotation,
m_position + l_transf.Other2ThisRelative (l_curVec));
l_ks3d->UpdateMove ();
}//for
}
void KLandmark::SetMaterial (const char* p_matName)
{
size_t i;
for (i = 0; i < m_ksprite3dList.Length(); i++)
{
csRef<KSprite3D> l_ks3d = m_ksprite3dList.Get (i);
l_ks3d->SetMaterialName (p_matName);
}//for
}
char const* KLandmark::GetName ()
{
return m_name;
}
void KLandmark::SetName (char const* p_name)
{
delete m_name;
m_name = csStrNew (p_name);
}
void KLandmark::SetVisible (bool p_visible)
{
m_visible = p_visible;
size_t i;
for (i = 0; i < m_ksprite3dList.Length (); i++)
{
csRef<KSprite3D> l_ks3d = m_ksprite3dList.Get (i);
l_ks3d->SetVisible (p_visible);
}//for
}
bool KLandmark::IsVisible ()
{
return m_visible;
}
void KLandmark::CreateColliders (iCollideSystem* p_cS,
csRefArray<iCollider>& p_c)
{
for (size_t i = 0; i < m_ksprite3dList.Length (); i++)
{
csRef<KSprite3D> l_s3d = m_ksprite3dList.Get (i);
csRef<iPolygonMesh> l_polmesh = l_s3d->GetMeshWrapper ()->
GetMeshObject()->GetObjectModel ()->GetPolygonMeshColldet ();
CS_ASSERT (l_polmesh != NULL);
csRef<iCollider> l_c = p_cS->CreateCollider (l_polmesh);
p_c.Push (l_c);
}//for
}
void KLandmark::AttachColliders (iCollideSystem* p_cS)
{
for (size_t i = 0; i < m_ksprite3dList.Length (); i++)
{
csRef<KSprite3D> l_s3d = m_ksprite3dList.Get (i);
csRef<iPolygonMesh> l_polMesh = l_s3d->GetMeshWrapper ()->
GetMeshObject()->GetObjectModel ()->GetPolygonMeshColldet ();
CS_ASSERT (l_polMesh != NULL);
//the ref to the csColliderW is not needed afterward since it is stored
//inside the iObject of iMeshWrapper.
csRef<csColliderWrapper> l_cW = new csColliderWrapper (
l_s3d->GetMeshWrapper()->QueryObject (), p_cS, l_polMesh);
l_cW->SetName (l_s3d->GetName ());
}//for
}
void KLandmark::DetachColliders (iCollideSystem* p_cS)
{
for (size_t i = 0; i < m_ksprite3dList.Length (); i++)
{
csRef<KSprite3D> l_s3d = m_ksprite3dList.Get (i);
csRef<csColliderWrapper> l_cW = CS_GET_CHILD_OBJECT
(l_s3d->GetMeshWrapper()->QueryObject (), csColliderWrapper);
CS_ASSERT (l_cW != NULL);
l_s3d->GetMeshWrapper()->QueryObject ()->ObjRemove (l_cW);
}//for
}
void KLandmark::GetReversibleTransform
(csArray<csReversibleTransform>& p_rTS)
{
size_t i;
for (i = 0; i < m_ksprite3dList.Length(); i++)
{
csRef<KSprite3D> l_ks3d = m_ksprite3dList.Get (i);
csReversibleTransform l_rT = l_ks3d->GetMovable ().GetFullTransform ();
p_rTS.Push (l_rT);
}//for
}
bool KLandmark::KLocalDragHandler::HandleDrag (float p_x, float p_y)
{
switch (m_dragType)
{
case TRANSLATION:
{
csVector3 lInt;
float lDist;
g_ske->CalculateIntersection (p_x, p_y, csPlane3 (0, 1, 0), lInt, lDist);
lInt.y = m_parent->GetPosition ().y;//Maintain the Y position!
m_parent->SetPosition (lInt);
return true;
}
case ROTATION:
{
static int l_oldMouseYLM = 0;
if (l_oldMouseYLM == 0)
l_oldMouseYLM = p_y;//only called the first time we get in here.
float l_angle = (K_2PI / 480.0f) * (p_y - l_oldMouseYLM);
l_oldMouseYLM = p_y;//store old value.
l_angle += m_parent->GetYRotation ();
clampRadiantAngle (l_angle);
m_parent->SetYRotation (l_angle);
return true;
}
}//switch
return false;
}
const csRefArray<iMeshWrapper> KLandmark::KLocalDraggable::GetMeshWrappers () const
{
csRefArray<iMeshWrapper> l_mWL;
csRef<iObjectIterator> l_oI = m_parent->GetIterator ();
while (l_oI->HasNext ())
{
csRef<KSprite3D> l_s3d = (KSprite3D*) (l_oI->Next ());
csRef<iMeshWrapper> l_mW = CS_GET_CHILD_OBJECT (l_s3d, iMeshWrapper);
l_mWL.Push (l_mW);
}//while
return csRefArray<iMeshWrapper>(l_mWL);
}
bool KLandmark::Write (iDocumentNode* p_node) const
{
return true;
}
bool KLandmark::Read (iDocumentNode* p_node)
{
if (strcmp (p_node->GetValue (), "landmark"))
return false;
const char* l_name = p_node->GetAttributeValue ("name");
float l_x = p_node->GetAttributeValueAsFloat ("x");
float l_y = p_node->GetAttributeValueAsFloat ("y");
float l_z = p_node->GetAttributeValueAsFloat ("z");
float l_yrotation = p_node->GetAttributeValueAsFloat ("yrotation");
this->SetName (l_name);
csVector3 l_pos (l_x, l_y, l_z);
csRef<iDocumentNodeIterator> l_it3 = p_node->GetNodes ();
while (l_it3->HasNext ())
{
csRef<iDocumentNode> l_s3dNode = l_it3->Next ();
if (l_s3dNode->GetType () != CS_NODE_ELEMENT)
continue;
const char* value = l_s3dNode->GetValue ();
if (!strcmpi(value,"sprite3d"))
{
const char* l_name = l_s3dNode->GetAttributeValue ("name");
const char* l_model = l_s3dNode->GetAttributeValue ("model");
const char* l_materialName = l_s3dNode->GetAttributeValue ("materialname");
float l_xOffset = l_s3dNode->GetAttributeValueAsFloat ("xoffset");
float l_yOffset = l_s3dNode->GetAttributeValueAsFloat ("yoffset");
float l_zOffset = l_s3dNode->GetAttributeValueAsFloat ("zoffset");
float l_xScale = l_s3dNode->GetAttributeValueAsFloat ("xscale");
float l_yScale = l_s3dNode->GetAttributeValueAsFloat ("yscale");
float l_zScale = l_s3dNode->GetAttributeValueAsFloat ("zscale");
float l_yRotation = l_s3dNode->GetAttributeValueAsFloat ("yrotation");
//
//create and add a klandmark to the list.
csRef<KSprite3D> l_ks3d;
l_ks3d.AttachNew (new KSprite3D ());
l_ks3d->Create (l_name, l_model, l_materialName,
l_xScale, l_yScale, l_zScale);
this->AddKSprite3D (l_ks3d, csVector3 (l_xOffset, l_yOffset, l_zOffset));
}//if
}//while
//
//set the position.
//?? Remember to set the position after we added all the KSprite3D to the landmark.
this->SetYRotation (l_yrotation);
this->SetPosition (l_pos);
return true;
}
See more files for this project here