////////////////////////////////////////////////////////////////////// // // 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 : bundles.cpp // Classes : CRayBundle // Description : Implementation // //////////////////////////////////////////////////////////////////////// #include #include "bundles.h" #include "renderer.h" #include "error.h" #include "stats.h" /////////////////////////////////////////////////////////////////////// // Class : CTraceBundle // Method : postTraceAction // Description : Make sure we trace the rays // Return Value : - // Comments : // Date last edited : 3/21/2003 int CTraceBundle::postTraceAction() { return TRUE; } /////////////////////////////////////////////////////////////////////// // Class : CTraceBundle // Method : postShade // Description : Make sure we trace the rays // Return Value : - // Comments : // Date last edited : 3/21/2003 void CTraceBundle::postShade(int nr,CRay **r,float **varying) { float *Ci = varying[VARIABLE_CI]; float *Oi = varying[VARIABLE_OI]; int i; T32 one; T32 *opacity; stats.numShadingRays += nr; one.real = 1.0f; if (depth == 0) { // First hit for (i=nr;i>0;i--,Ci+=3,Oi+=3) { CTraceRay *cRay = (CTraceRay *) (*r++); opacity = (T32 *) Oi; if ( (opacity[0].integer ^ one.integer) | (opacity[1].integer ^ one.integer) | (opacity[2].integer ^ one.integer)) { // We hit a transparent surface movvv(cRay->color,Ci); // Save the color and opacity as we'll need those movvv(cRay->opacity,Oi); rays[last++] = cRay; } else { const float multiplier = cRay->multiplier; // We hit an opaque surface cRay->dest[0] += Ci[0]*multiplier; cRay->dest[1] += Ci[1]*multiplier; cRay->dest[2] += Ci[2]*multiplier; } } } else { // Transparency hit for (i=nr;i>0;i--,Ci+=3,Oi+=3) { CTraceRay *cRay = (CTraceRay *) (*r++); opacity = (T32 *) Oi; const int transparent = (opacity[0].integer ^ one.integer) | (opacity[1].integer ^ one.integer) | (opacity[2].integer ^ one.integer); const float *backOpacity = cRay->opacity; Ci[0] *= 1 - backOpacity[0]; Ci[1] *= 1 - backOpacity[1]; Ci[2] *= 1 - backOpacity[2]; Oi[0] *= 1 - backOpacity[0]; Oi[1] *= 1 - backOpacity[1]; Oi[2] *= 1 - backOpacity[2]; addvv(cRay->color,Ci); addvv(cRay->opacity,Oi); if (transparent) { // We hit a transparent surface again, keep tracing rays[last++] = cRay; } else { const float multiplier = cRay->multiplier; // We hit an opaque surface cRay->dest[0] += cRay->color[0]*multiplier; cRay->dest[1] += cRay->color[1]*multiplier; cRay->dest[2] += cRay->color[2]*multiplier; } } } } /////////////////////////////////////////////////////////////////////// // Class : CTraceBundle // Method : postShade // Description : Called for the rays that don't hit anything // Return Value : - // Comments : // Date last edited : 3/21/2003 void CTraceBundle::postShade(int nr,CRay **r) { stats.numShadingRays += nr; if (depth > 0) { int i; for (i=nr;i>0;i--) { CTraceRay *cRay = (CTraceRay *) (*r++); const float multiplier = cRay->multiplier; cRay->dest[0] += cRay->color[0]*multiplier; cRay->dest[1] += cRay->color[1]*multiplier; cRay->dest[2] += cRay->color[2]*multiplier; } } } /////////////////////////////////////////////////////////////////////// // Class : CTraceBundle // Method : post // Description : Called after the first pass // Return Value : - // Comments : // Date last edited : 3/21/2003 void CTraceBundle::post() { numRays = last; last = 0; depth++; } /////////////////////////////////////////////////////////////////////// // Class : CTraceExBundle // Method : postTraceAction // Description : Make sure we trace the rays // Return Value : - // Comments : // Date last edited : 3/21/2003 int CTraceExBundle::postTraceAction() { return TRUE; } /////////////////////////////////////////////////////////////////////// // Class : CTraceExBundle // Method : postShade // Description : Make sure we trace the rays // Return Value : - // Comments : // Date last edited : 3/21/2003 void CTraceExBundle::postShade(int nr,CRay **r,float **varying) { float *Ci = varying[VARIABLE_CI]; float *Oi = varying[VARIABLE_OI]; int i; T32 one; T32 *opacity; stats.numShadingRays += nr; one.real = 1.0f; if (depth == 0) { // First hit for (i=nr;i>0;i--,Ci+=3,Oi+=3) { CTraceExRay *cRay = (CTraceExRay *) (*r++); *(cRay->destT) = cRay->t; opacity = (T32 *) Oi; if ( (opacity[0].integer ^ one.integer) | (opacity[1].integer ^ one.integer) | (opacity[2].integer ^ one.integer)) { // We hit a transparent surface movvv(cRay->color,Ci); // Save the color and opacity as we'll need those movvv(cRay->opacity,Oi); rays[last++] = cRay; } else { const float multiplier = cRay->multiplier; // We hit an opaque surface cRay->dest[0] += Ci[0]*multiplier; cRay->dest[1] += Ci[1]*multiplier; cRay->dest[2] += Ci[2]*multiplier; } } } else { // Transparency hit for (i=nr;i>0;i--,Ci+=3,Oi+=3) { CTraceRay *cRay = (CTraceRay *) (*r++); opacity = (T32 *) Oi; const int transparent = (opacity[0].integer ^ one.integer) | (opacity[1].integer ^ one.integer) | (opacity[2].integer ^ one.integer); const float *backOpacity = cRay->opacity; Ci[0] *= 1 - backOpacity[0]; Ci[1] *= 1 - backOpacity[1]; Ci[2] *= 1 - backOpacity[2]; Oi[0] *= 1 - backOpacity[0]; Oi[1] *= 1 - backOpacity[1]; Oi[2] *= 1 - backOpacity[2]; addvv(cRay->color,Ci); addvv(cRay->opacity,Oi); if (transparent) { // We hit a transparent surface again, keep tracing rays[last++] = cRay; } else { const float multiplier = cRay->multiplier; // We hit an opaque surface cRay->dest[0] += cRay->color[0]*multiplier; cRay->dest[1] += cRay->color[1]*multiplier; cRay->dest[2] += cRay->color[2]*multiplier; } } } } /////////////////////////////////////////////////////////////////////// // Class : CTraceExBundle // Method : postShade // Description : Called for the rays that don't hit anything // Return Value : - // Comments : // Date last edited : 3/21/2003 void CTraceExBundle::postShade(int nr,CRay **r) { stats.numShadingRays += nr; if (depth > 0) { int i; for (i=nr;i>0;i--) { CTraceExRay *cRay = (CTraceExRay *) (*r++); const float multiplier = cRay->multiplier; cRay->dest[0] += cRay->color[0]*multiplier; cRay->dest[1] += cRay->color[1]*multiplier; cRay->dest[2] += cRay->color[2]*multiplier; } } } /////////////////////////////////////////////////////////////////////// // Class : CTraceExBundle // Method : post // Description : Called after the first pass // Return Value : - // Comments : // Date last edited : 3/21/2003 void CTraceExBundle::post() { numRays = last; last = 0; depth++; } /////////////////////////////////////////////////////////////////////// // Class : CIrradianceBundle // Method : postTraceAction // Description : Make sure we trace the rays // Return Value : - // Comments : // Date last edited : 3/21/2003 int CIrradianceBundle::postTraceAction() { return shade; } /////////////////////////////////////////////////////////////////////// // Class : CIrradianceBundle // Method : postShade // Description : Make sure we trace the rays // Return Value : - // Comments : // Date last edited : 3/21/2003 void CIrradianceBundle::postShade(int nr,CRay **r,float **varying) { float *Ci = varying[VARIABLE_CI]; int i; stats.numShadingRays += nr; for (i=nr;i>0;i--,Ci+=3) { CIrradianceRay *cRay = (CIrradianceRay *) (*r++); movvv(cRay->dest,Ci); } } /////////////////////////////////////////////////////////////////////// // Class : CIrradianceBundle // Method : postShade // Description : Called for the rays that don't hit anything // Return Value : - // Comments : // Date last edited : 3/21/2003 void CIrradianceBundle::postShade(int nr,CRay **r) { stats.numShadingRays += nr; } /////////////////////////////////////////////////////////////////////// // Class : CIrradianceBundle // Method : post // Description : Called after the first pass // Return Value : - // Comments : // Date last edited : 3/21/2003 void CIrradianceBundle::post() { numRays = last; last = 0; depth++; } /////////////////////////////////////////////////////////////////////// // Class : CTransmissionBundle // Method : postTraceAction // Description : Make sure we trace the rays // Return Value : - // Comments : // Date last edited : 3/21/2003 int CTransmissionBundle::postTraceAction() { return TRUE; } /////////////////////////////////////////////////////////////////////// // Class : CTransmissionBundle // Method : postShade // Description : Make sure we trace the rays // Return Value : - // Comments : // Date last edited : 3/21/2003 void CTransmissionBundle::postShade(int nr,CRay **r,float **varying) { float *Ci = varying[VARIABLE_CI]; float *Oi = varying[VARIABLE_OI]; int i; T32 one; T32 *opacity; stats.numShadowRays += nr; one.real = 1.0f; if (depth == 0) { // First hit for (i=nr;i>0;i--,Ci+=3,Oi+=3) { CTransmissionRay *cRay = (CTransmissionRay *) (*r++); opacity = (T32 *) Oi; if ( (opacity[0].integer ^ one.integer) | (opacity[1].integer ^ one.integer) | (opacity[2].integer ^ one.integer)) { // We hit a transparent surface movvv(cRay->opacity,Oi); rays[last++] = cRay; } } } else { // Transparency hit for (i=nr;i>0;i--,Ci+=3,Oi+=3) { CTransmissionRay *cRay = (CTransmissionRay *) (*r++); opacity = (T32 *) Oi; const int transparent = (opacity[0].integer ^ one.integer) | (opacity[1].integer ^ one.integer) | (opacity[2].integer ^ one.integer); Oi[0] *= 1 - cRay->opacity[0]; Oi[1] *= 1 - cRay->opacity[1]; Oi[2] *= 1 - cRay->opacity[2]; movvv(cRay->opacity,Oi); if (transparent) { // Still transparent rays[last++] = cRay; } } } } /////////////////////////////////////////////////////////////////////// // Class : CTransmissionBundle // Method : postShade // Description : Called for the rays that don't hit anything // Return Value : - // Comments : // Date last edited : 3/21/2003 void CTransmissionBundle::postShade(int nr,CRay **r) { int i; stats.numShadowRays += nr; if (depth == 0) { for (i=nr;i>0;i--) { CTransmissionRay *cRay = (CTransmissionRay *) (*r++); const float multiplier = cRay->multiplier; cRay->dest[0] += multiplier; cRay->dest[1] += multiplier; cRay->dest[2] += multiplier; } } else { for (i=nr;i>0;i--) { CTransmissionRay *cRay = (CTransmissionRay *) (*r++); const float multiplier = cRay->multiplier; const float *opacity = cRay->opacity; cRay->dest[0] += (1-opacity[0])*multiplier; cRay->dest[1] += (1-opacity[1])*multiplier; cRay->dest[2] += (1-opacity[2])*multiplier; } } } /////////////////////////////////////////////////////////////////////// // Class : CTraceBundle // Method : post // Description : Called after the first pass // Return Value : - // Comments : // Date last edited : 3/21/2003 void CTransmissionBundle::post() { numRays = last; last = 0; depth++; } /////////////////////////////////////////////////////////////////////// // Class : CGatherBundle // Method : CGatherBundle // Description : Ctor // Return Value : - // Comments : // Date last edited : 3/23/2003 CGatherBundle::CGatherBundle() { } /////////////////////////////////////////////////////////////////////// // Class : CGatherBundle // Method : ~CGatherBundle // Description : Dtor // Return Value : - // Comments : // Date last edited : 3/23/2003 CGatherBundle::~CGatherBundle() { } /////////////////////////////////////////////////////////////////////// // Class : CGatherBundle // Method : postTraceAction // Description : // Return Value : TRUE if needs shading // Comments : // Date last edited : 3/23/2003 int CGatherBundle::postTraceAction() { CGatherVariable *cVariable; int i; // Dispatch the outputs that don't need shading for (cVariable=lookup->nonShadeOutputs;cVariable!=NULL;cVariable=cVariable->next) { cVariable->record(numRays,(CGatherRay **) rays,NULL); } // Adjust the tags for (i=0;iobject == NULL) { numMisses++; (*cRay->tags)++; } } return lookup->outputs != NULL; } /////////////////////////////////////////////////////////////////////// // Class : CGatherBundle // Method : postShade // Description : // Return Value : - // Comments : // Date last edited : 3/23/2003 void CGatherBundle::postShade(int nr,CRay **r,float **varying) { CGatherVariable *cVariable; stats.numShadingRays += nr; for (cVariable=lookup->outputs;cVariable!=NULL;cVariable=cVariable->next) { cVariable->record(nr,(CGatherRay **) r,varying); } } /////////////////////////////////////////////////////////////////////// // Class : CGatherBundle // Method : postShade // Description : // Return Value : - // Comments : // Date last edited : 3/23/2003 void CGatherBundle::postShade(int nr,CRay **r) { stats.numShadingRays += nr; } /////////////////////////////////////////////////////////////////////// // Class : CGatherBundle // Method : post // Description : // Return Value : - // Comments : // Date last edited : 3/23/2003 void CGatherBundle::post() { numRays = last; numRays = 0; last = 0; depth++; }