////////////////////////////////////////////////////////////////////// // // Pixie // // Copyright © 1999 - 2003, Okan Arikan // // Contact: okan@cs.berkeley.edu // // This library 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 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 // General Public License for more details. // // You should have received a copy of the GNU General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // File : object.cpp // Classes : CGeometry // Description : Implementation // //////////////////////////////////////////////////////////////////////// #include #include "object.h" #include "error.h" #include "renderer.h" #include "ri.h" #include "shading.h" #include "stats.h" #include "memory.h" #include "surface.h" #include "opengl.h" /////////////////////////////////////////////////////////////////////// // Class : CObject // Method : CObject // Description : Ctor // Return Value : - // Comments : // Date last edited : 3/11/2001 CObject::CObject(CAttributes *a,CXform *x) { stats.numObjects++; attributes = a; xform = x; attributes->attach(); xform->attach(); refCount = 0; } /////////////////////////////////////////////////////////////////////// // Class : CObject // Method : ~CObject // Description : Dtor // Return Value : - // Comments : // Date last edited : 3/11/2001 CObject::~CObject() { stats.numObjects--; attributes->detach(); xform->detach(); } /////////////////////////////////////////////////////////////////////// // Class : CObject // Method : bound // Description : Compute the bounding box of the object // Return Value : // Comments : // Date last edited : 10/16/2001 void CObject::bound(float *bmin,float *bmax) const { error(CODE_BUG,"An object is missing the \"bound\" function\n"); assert(FALSE); } /////////////////////////////////////////////////////////////////////// // Class : CObject // Method : tesselate // Description : Tesselate the object into raytracable primitives // Return Value : // Comments : // Date last edited : 10/16/2001 void CObject::tesselate(CShadingContext *context) { } /////////////////////////////////////////////////////////////////////// // Class : CObject // Method : dice // Description : Dice the object into smaller ones // Return Value : // Comments : // Date last edited : 10/16/2001 void CObject::dice(CShadingContext *rasterizer) { } /////////////////////////////////////////////////////////////////////// // Class : CObject // Method : copy // Description : Create a clone object // Return Value : // Comments : // Date last edited : 10/16/2001 void CObject::copy(CAttributes *,CXform *,CRendererContext *) const { error(CODE_BUG,"An object is missing the \"copy\" function\n"); assert(FALSE); } static float getDisp(float *mat,float disp) { float tmp[4],tmp2[4]; int i; float alpha; tmp[0] = urand(); tmp[1] = urand(); tmp[2] = urand(); tmp[3] = urand(); for (i=0;i<10;i++) { mulmp4(tmp2,mat,tmp); alpha = max(absf(tmp2[0]),absf(tmp2[1])); alpha = max(alpha,absf(tmp2[2])); alpha = max(alpha,absf(tmp2[3])); tmp[0] = tmp2[0] / alpha; tmp[1] = tmp2[1] / alpha; tmp[2] = tmp2[2] / alpha; tmp[3] = tmp2[3] / alpha; } return alpha; } /////////////////////////////////////////////////////////////////////// // Class : CObject // Method : makeBound // Description : Make sure we do not have empty bounding box // Return Value : // Comments : // Date last edited : 10/16/2001 void CObject::makeBound(float *bmin,float *bmax) const { vector D; float maxD; float maxDisp = attributes->maxDisplacement; subvv(D,bmax,bmin); maxD = D[0]; maxD = max(D[1],maxD); maxD = max(D[2],maxD); maxD *= attributes->bexpand; // Add the displacement amount of the surface if (attributes->maxDisplacementSpace != NULL) { matrix *from; matrix *to; ECoordinateSystem sys; if (currentRenderer->findCoordinateSystem(attributes->maxDisplacementSpace,from,to,sys)) { maxDisp = attributes->maxDisplacement * getDisp(*from,attributes->maxDisplacement); } free(attributes->maxDisplacementSpace); attributes->maxDisplacementSpace = NULL; } maxD += maxDisp; // Expand the bound accordingly subvf(bmin,maxD); addvf(bmax,maxD); } /////////////////////////////////////////////////////////////////////// // Class : CSurface // Method : CSurface // Description : Ctor // Return Value : // Comments : // Date last edited : 10/16/2001 CSurface::CSurface(CAttributes *a,CXform *x) : CObject(a,x) { } /////////////////////////////////////////////////////////////////////// // Class : CSurface // Method : ~CSurface // Description : Dtor // Return Value : // Comments : // Date last edited : 10/16/2001 CSurface::~CSurface() { } /////////////////////////////////////////////////////////////////////// // Class : CSurface // Method : dice // Description : Dice the object into smaller ones // Return Value : // Comments : // Date last edited : 10/16/2001 void CSurface::dice(CShadingContext *rasterizer) { CPatch *cSurface = new CPatch(attributes,xform,this,0,1,0,1,0,attributes->minSplits); cSurface->dice(rasterizer); cSurface->check(); } /////////////////////////////////////////////////////////////////////// // Class : CSurface // Method : moving // Description : TRUE if the object is moving // Return Value : // Comments : // Date last edited : 10/16/2001 int CSurface::moving() const { return FALSE; } /////////////////////////////////////////////////////////////////////// // Class : CSurface // Method : sample // Description : Sample a bunch of points on the surface // Return Value : TRUE if the sampling was done and shaders need to be executed // Comments : // Date last edited : 10/16/2001 void CSurface::sample(int,int,float **,unsigned int &) const { error(CODE_BUG,"An object is missing the \"sample\" function\n"); assert(FALSE); } /////////////////////////////////////////////////////////////////////// // Class : CSurface // Method : interpolate // Description : Interpolate the varying data and set the uniform data // Return Value : // Comments : // Date last edited : 10/16/2001 void CSurface::interpolate(int,float **) const { error(CODE_BUG,"An object is missing the \"interpolate\" function\n"); assert(FALSE); } /////////////////////////////////////////////////////////////////////// // Class : CSurface // Method : split // Description : Split an object // Return Value : // Comments : // Date last edited : 10/16/2001 void CSurface::shade(CShadingContext *context,int numRays,CRay **rays) { float **varying = context->currentShadingState->varying; float *u = varying[VARIABLE_U]; float *v = varying[VARIABLE_V]; float *time = varying[VARIABLE_TIME]; float *from = varying[VARIABLE_I]; int i; for (i=numRays;i>0;i--) { const CRay *cRay = *rays++; *u++ = cRay->u; *v++ = cRay->v; *time++ = cRay->time; movvv(from,cRay->from); from += 3; } context->shade(this,numRays,1,-1,0); }