7a6d165641
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1118 178a84e3-b1eb-0310-8ba1-8eac791a3b58
217 lines
7.1 KiB
C++
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 */
|