stk-code_catmod/src/ssg_help.cpp
grumbel 7a6d165641 - moved trunk/ to trunk/supertuxkart
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1118 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2007-05-27 16:01:53 +00:00

217 lines
7.1 KiB
C++

// $Id: ssg_help.cpp 837 2006-10-23 07:43:05Z hiker $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004-2005 Steve Baker <sjbaker1@airmail.net>
// Copyright (C) 2006 SuperTuxKart-Team, Joerg Henrichs, Steve Baker
//
// 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 <iostream>
#include <plib/ssg.h>
#include "ssg_help.hpp"
// -----------------------------------------------------------------------------
/** Make VtTables use display lists.
*
* Calls recursively 'makeDList' in all ssgVtxTable of the entity.
* \param entity Tree in which to create display lists.
*/
void createDisplayLists(ssgEntity* entity)
{
if (!entity) return;
ssgVtxTable* table = dynamic_cast<ssgVtxTable*>(entity);
if(table)
{
if(table->getNumTriangles()>1) table->makeDList();
}
ssgBranch* branch = dynamic_cast<ssgBranch*>(entity);
if (branch)
{
for(ssgEntity* i = branch->getKid(0); i != NULL;
i = branch->getNextKid())
{
createDisplayLists(i);
} // for
} // if branch
} // createDisplayLists
// -----------------------------------------------------------------------------
/** Adds a transform node to the branch.
*
* Creates a new ssgTransform node to which all children of the branch are
* added. The new ssgTransform is then set as the only child of the
* branch.
* \param branch The branch to which a transform node is added.
*/
ssgTransform* add_transform(ssgBranch* branch)
{
if (!branch) return 0;
ssgTransform* transform = new ssgTransform;
transform->ref();
for(ssgEntity* i = branch->getKid(0); i != NULL; i = branch->getNextKid())
{
transform->addKid(i);
}
branch->removeAllKids();
branch->addKid(transform);
// Set some user data, so that the wheel isn't ssgFlatten()'ed
branch->setUserData(new ssgBase());
transform->setUserData(new ssgBase());
return transform;
} // add_transform
// -----------------------------------------------------------------------------
/** Recursively prints a model.
*
* Recursively prints a model. That function can most likely be removed, the
* print method of the ssg objects do the same.
* \param entity The entity ro print (can't be constant because of ssg functions
* which are not const correct)
* \param indent Indentation to use
* \param maxLevel maximum number of levels to print
*/
void print_model(ssgEntity* entity, const int indent, const int maxLevel)
{
if(maxLevel <0) return;
if (entity)
{
for(int i = 0; i < indent; ++i)
std::cout << " ";
std::cout << entity->getTypeName() << " " << entity->getType() << " '"
<< entity->getPrintableName()
<< "' '"
<< (entity->getName() ? entity->getName() : "null")
<< "' " << entity << std::endl;
ssgBranch* branch = dynamic_cast<ssgBranch*>(entity);
if (branch)
{
for(ssgEntity* i = branch->getKid(0); i != NULL;
i = branch->getNextKid())
{
print_model(i, indent + 1, maxLevel-1);
}
} // if branch
} // if entity
} // print_model
// -----------------------------------------------------------------------------
/** Computes the minimum and maximum x/y coordinates for a ssgEntity.
*
* Recursively computes the minimum x and y coordinates of a ssgEntity.
* \param p ssgEntity for which t compute the extend (can't be constant because
* of plib not const correct)
* \param x_min minimum x value
* \param x_max maximum x value
* \param y_min minimum y value
* \param y_max maximum y value
* \param z_min minimum z value, optional parameter!
* \param z_max minimum z value, optional parameter!
*/
void MinMax(ssgEntity* p, float *x_min, float *x_max,
float *y_min, float *y_max,
float *z_min, float *z_max)
{
sgMat4 mat;
sgMakeIdentMat4(mat);
*x_min = *y_min = 10000.0f; if(z_min) *z_min = 10000.0f;
*x_max = *y_max = -10000.0f; if(z_max) *z_max = -10000.0f;
MinMax(p, mat, x_min, x_max, y_min, y_max, z_min, z_max);
} // MinMax
/** Internal function used by MinMax. */
void MinMax(ssgEntity* p, sgMat4 m, float* x_min, float* x_max,
float* y_min, float* y_max,
float* z_min, float* z_max)
{
if(p->isAKindOf(ssgTypeLeaf()))
{
ssgLeaf* l=(ssgLeaf*)p;
for(int i=0; i<l->getNumTriangles(); i++)
{
short v1,v2,v3;
sgVec3 vv1, vv2, vv3;
l->getTriangle(i, &v1, &v2, &v3);
sgXformPnt3 ( vv1, l->getVertex(v1), m );
sgXformPnt3 ( vv2, l->getVertex(v2), m );
sgXformPnt3 ( vv3, l->getVertex(v3), m );
*x_min = std::min(*x_min, vv1[0]); *x_max = std::max(*x_max, vv1[0]);
*x_min = std::min(*x_min, vv2[0]); *x_max = std::max(*x_max, vv2[0]);
*x_min = std::min(*x_min, vv3[0]); *x_max = std::max(*x_max, vv3[0]);
*y_min = std::min(*y_min, vv1[1]); *y_max = std::max(*y_max, vv1[1]);
*y_min = std::min(*y_min, vv2[1]); *y_max = std::max(*y_max, vv2[1]);
*y_min = std::min(*y_min, vv3[1]); *y_max = std::max(*y_max, vv3[1]);
if(z_min)
{
*z_min = std::min(*z_min, vv1[2]);
*z_min = std::min(*z_min, vv2[2]);
*z_min = std::min(*z_min, vv3[2]);
}
if(z_max)
{
*z_max = std::max(*z_max, vv1[2]);
*z_max = std::max(*z_max, vv2[2]);
*z_max = std::max(*z_max, vv3[2]);
}
} // for i<p->getNumTriangles
}
else if (p->isAKindOf(ssgTypeTransform()))
{
ssgBaseTransform* t=(ssgBaseTransform*)p;
sgMat4 tmpT, tmpM;
t->getTransform(tmpT);
sgCopyMat4(tmpM, m);
sgPreMultMat4(tmpM,tmpT);
for(ssgEntity* e=t->getKid(0); e!=NULL; e=t->getNextKid())
{
MinMax(e, tmpM, x_min, x_max, y_min, y_max, z_min, z_max);
} // for i<getNumKids
}
else if (p->isAKindOf(ssgTypeBranch()))
{
ssgBranch* b =(ssgBranch*)p;
for(ssgEntity* e=b->getKid(0); e!=NULL; e=b->getNextKid())
{
MinMax(e, m, x_min, x_max, y_min, y_max, z_min, z_max);
} // for i<getNumKids
}
else
{
printf("StaticSSG::MinMax: unkown type\n");
p->print(stdout, 0, 0);
}
} // MinMax
// -----------------------------------------------------------------------------
/* EOF */