Shadowrun: Awakened 29 September 2011 - Build 871
extvol.cpp
Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2010 Intel Corporation.  All Rights Reserved.
00003 
00004     This file is part of Threading Building Blocks.
00005 
00006     Threading Building Blocks is free software; you can redistribute it
00007     and/or modify it under the terms of the GNU General Public License
00008     version 2 as published by the Free Software Foundation.
00009 
00010     Threading Building Blocks is distributed in the hope that it will be
00011     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00012     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with Threading Building Blocks; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019     As a special exception, you may use this file as part of a free software
00020     library without restriction.  Specifically, if other files instantiate
00021     templates or use macros or inline functions from this file, or you compile
00022     this file and link it with other files to produce an executable, this
00023     file does not by itself cause the resulting executable to be covered by
00024     the GNU General Public License.  This exception does not however
00025     invalidate any other reasons why the executable file might be covered by
00026     the GNU General Public License.
00027 */
00028 
00029 /*
00030     The original source for this example is
00031     Copyright (c) 1994-2008 John E. Stone
00032     All rights reserved.
00033 
00034     Redistribution and use in source and binary forms, with or without
00035     modification, are permitted provided that the following conditions
00036     are met:
00037     1. Redistributions of source code must retain the above copyright
00038        notice, this list of conditions and the following disclaimer.
00039     2. Redistributions in binary form must reproduce the above copyright
00040        notice, this list of conditions and the following disclaimer in the
00041        documentation and/or other materials provided with the distribution.
00042     3. The name of the author may not be used to endorse or promote products
00043        derived from this software without specific prior written permission.
00044 
00045     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
00046     OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00047     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00048     ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00049     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00050     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00051     OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00052     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00053     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00054     OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00055     SUCH DAMAGE.
00056 */
00057 
00058 /*
00059  * extvol.c - Volume rendering helper routines etc.
00060  *
00061  *  $Id: extvol.cpp,v 1.2 2007-02-22 17:54:15 dpoulsen Exp $
00062  */
00063 
00064 #include<stdio.h>
00065 
00066 #include "machine.h"
00067 #include "types.h"
00068 #include "macros.h"
00069 #include "vector.h"
00070 #include "util.h"
00071 #include "box.h"
00072 #include "extvol.h"
00073 #include "trace.h"
00074 #include "sphere.h"
00075 #include "light.h"
00076 #include "shade.h"
00077 #include "global.h"
00078 
00079 
00080 int extvol_bbox(void * obj, vector * min, vector * max) {
00081   box * b = (box *) obj;
00082 
00083   *min = b->min;
00084   *max = b->max;
00085 
00086   return 1;
00087 }
00088 
00089 static object_methods extvol_methods = {
00090   (void (*)(void *, void *))(box_intersect),
00091   (void (*)(void *, void *, void *, void *))(box_normal),
00092   extvol_bbox, 
00093   free 
00094 };
00095 
00096 extvol * newextvol(void * voidtex, vector min, vector max, 
00097                    int samples, flt (* evaluator)(flt, flt, flt)) { 
00098   extvol * xvol;
00099   texture * tex;
00100   
00101   tex = (texture *) voidtex;
00102 
00103   xvol = (extvol *) rt_getmem(sizeof(extvol));
00104   memset(xvol, 0, sizeof(extvol));
00105 
00106   xvol->methods = &extvol_methods;
00107 
00108   xvol->min=min;
00109   xvol->max=max;
00110   xvol->evaluator = evaluator;
00111   xvol->ambient = tex->ambient;
00112   xvol->diffuse = tex->diffuse;
00113   xvol->opacity = tex->opacity;  
00114   xvol->samples = samples;
00115 
00116   xvol->tex = (texture *)rt_getmem(sizeof(texture));
00117   memset(xvol->tex, 0, sizeof(texture));
00118 
00119   xvol->tex->ctr.x = 0.0;
00120   xvol->tex->ctr.y = 0.0;
00121   xvol->tex->ctr.z = 0.0;
00122   xvol->tex->rot = xvol->tex->ctr;
00123   xvol->tex->scale = xvol->tex->ctr;
00124   xvol->tex->uaxs = xvol->tex->ctr;
00125   xvol->tex->vaxs = xvol->tex->ctr;
00126   xvol->tex->islight = 0;
00127   xvol->tex->shadowcast = 0;
00128 
00129   xvol->tex->col=tex->col;
00130   xvol->tex->ambient=1.0;
00131   xvol->tex->diffuse=0.0;
00132   xvol->tex->specular=0.0;
00133   xvol->tex->opacity=1.0;
00134   xvol->tex->img=NULL;
00135   xvol->tex->texfunc=(color(*)(void *, void *, void *))(ext_volume_texture);
00136   xvol->tex->obj = (void *) xvol; /* XXX hack! */
00137 
00138   return xvol;
00139 }
00140 
00141 color ExtVoxelColor(flt scalar) {
00142   color col;
00143 
00144   if (scalar > 1.0) 
00145     scalar = 1.0;
00146 
00147   if (scalar < 0.0)
00148     scalar = 0.0;
00149 
00150   if (scalar < 0.5) {
00151     col.g = 0.0;
00152   }
00153   else {
00154     col.g = (scalar - 0.5) * 2.0;
00155   }
00156 
00157   col.r = scalar;
00158   col.b = 1.0 - (scalar / 2.0);
00159 
00160   return col;
00161 } 
00162 
00163 color ext_volume_texture(vector * hit, texture * tex, ray * ry) {
00164   color col, col2;
00165   box * bx;
00166   extvol * xvol;
00167   flt a, tx1, tx2, ty1, ty2, tz1, tz2;
00168   flt tnear, tfar;
00169   flt t, tdist, dt, ddt, sum, tt; 
00170   vector pnt, bln;
00171   flt scalar, transval; 
00172   int i;
00173   point_light * li;
00174   color diffint; 
00175   vector N, L;
00176   flt inten;
00177 
00178   col.r = 0.0;
00179   col.g = 0.0;
00180   col.b = 0.0;
00181 
00182     bx = (box *) tex->obj;
00183   xvol = (extvol *) tex->obj;
00184  
00185   tnear= -FHUGE;
00186   tfar= FHUGE;
00187  
00188   if (ry->d.x == 0.0) {
00189     if ((ry->o.x < bx->min.x) || (ry->o.x > bx->max.x)) return col;
00190   }
00191   else {
00192     tx1 = (bx->min.x - ry->o.x) / ry->d.x;
00193     tx2 = (bx->max.x - ry->o.x) / ry->d.x;
00194     if (tx1 > tx2) { a=tx1; tx1=tx2; tx2=a; }
00195     if (tx1 > tnear) tnear=tx1;
00196     if (tx2 < tfar)   tfar=tx2;
00197   }
00198   if (tnear > tfar) return col;
00199   if (tfar < 0.0) return col;
00200  
00201  if (ry->d.y == 0.0) {
00202     if ((ry->o.y < bx->min.y) || (ry->o.y > bx->max.y)) return col;
00203   }
00204   else {
00205     ty1 = (bx->min.y - ry->o.y) / ry->d.y;
00206     ty2 = (bx->max.y - ry->o.y) / ry->d.y;
00207     if (ty1 > ty2) { a=ty1; ty1=ty2; ty2=a; }
00208     if (ty1 > tnear) tnear=ty1;
00209     if (ty2 < tfar)   tfar=ty2;
00210   }
00211   if (tnear > tfar) return col;
00212   if (tfar < 0.0) return col;
00213  
00214   if (ry->d.z == 0.0) {
00215     if ((ry->o.z < bx->min.z) || (ry->o.z > bx->max.z)) return col;
00216   }
00217   else {
00218     tz1 = (bx->min.z - ry->o.z) / ry->d.z;
00219     tz2 = (bx->max.z - ry->o.z) / ry->d.z;
00220     if (tz1 > tz2) { a=tz1; tz1=tz2; tz2=a; }
00221     if (tz1 > tnear) tnear=tz1;
00222     if (tz2 < tfar)   tfar=tz2;
00223   }
00224   if (tnear > tfar) return col;
00225   if (tfar < 0.0) return col;
00226  
00227   if (tnear < 0.0) tnear=0.0;
00228  
00229   tdist = xvol->samples;
00230 
00231   tt = (xvol->opacity / tdist); 
00232 
00233   bln.x=fabs(bx->min.x - bx->max.x);
00234   bln.y=fabs(bx->min.y - bx->max.y);
00235   bln.z=fabs(bx->min.z - bx->max.z);
00236   
00237      dt = 1.0 / tdist; 
00238     sum = 0.0;
00239 
00240 /* Accumulate color as the ray passes through the voxels */
00241   for (t=tnear; t<=tfar; t+=dt) {
00242     if (sum < 1.0) {
00243       pnt.x=((ry->o.x + (ry->d.x * t)) - bx->min.x) / bln.x;
00244       pnt.y=((ry->o.y + (ry->d.y * t)) - bx->min.y) / bln.y;
00245       pnt.z=((ry->o.z + (ry->d.z * t)) - bx->min.z) / bln.z;
00246 
00247       /* call external evaluator assume 0.0 -> 1.0 range.. */ 
00248       scalar = xvol->evaluator(pnt.x, pnt.y, pnt.z);  
00249 
00250       transval = tt * scalar; 
00251       sum += transval; 
00252 
00253       col2 = ExtVoxelColor(scalar);
00254 
00255       col.r += transval * col2.r * xvol->ambient;
00256       col.g += transval * col2.g * xvol->ambient;
00257       col.b += transval * col2.b * xvol->ambient;
00258 
00259       ddt = dt;
00260 
00261       /* Add in diffuse shaded light sources (no shadows) */
00262       if (xvol->diffuse > 0.0) {
00263   
00264         /* Calculate the Volume gradient at the voxel */
00265         N.x = (xvol->evaluator(pnt.x - ddt, pnt.y, pnt.z)  -  
00266               xvol->evaluator(pnt.x + ddt, pnt.y, pnt.z)) *  8.0 * tt; 
00267   
00268         N.y = (xvol->evaluator(pnt.x, pnt.y - ddt, pnt.z)  -  
00269               xvol->evaluator(pnt.x, pnt.y + ddt, pnt.z)) *  8.0 * tt; 
00270   
00271         N.z = (xvol->evaluator(pnt.x, pnt.y, pnt.z - ddt)  -  
00272               xvol->evaluator(pnt.x, pnt.y, pnt.z + ddt)) *  8.0 * tt; 
00273  
00274         /* only light surfaces with enough of a normal.. */
00275         if ((N.x*N.x + N.y*N.y + N.z*N.z) > 0.0) { 
00276           diffint.r = 0.0; 
00277           diffint.g = 0.0; 
00278           diffint.b = 0.0; 
00279     
00280           /* add the contribution of each of the lights.. */
00281           for (i=0; i<numlights; i++) {
00282             li=lightlist[i];
00283             VSUB(li->ctr, (*hit), L)
00284             VNorm(&L);
00285             VDOT(inten, N, L)
00286     
00287             /* only add light if its from the front of the surface */
00288             /* could add back-lighting if we wanted to later.. */
00289             if (inten > 0.0) {
00290               diffint.r += inten*li->tex->col.r;
00291               diffint.g += inten*li->tex->col.g;
00292               diffint.b += inten*li->tex->col.b;
00293             }
00294           }   
00295           col.r += col2.r * diffint.r * xvol->diffuse;
00296           col.g += col2.g * diffint.g * xvol->diffuse;
00297           col.b += col2.b * diffint.b * xvol->diffuse;
00298         }
00299       }
00300     }   
00301     else { 
00302       sum=1.0;
00303     }  
00304   }
00305 
00306   /* Add in transmitted ray from outside environment */
00307   if (sum < 1.0) {      /* spawn transmission rays / refraction */
00308     color transcol;
00309 
00310     transcol = shade_transmission(ry, hit, 1.0 - sum);
00311 
00312     col.r += transcol.r; /* add the transmitted ray  */
00313     col.g += transcol.g; /* to the diffuse and       */
00314     col.b += transcol.b; /* transmission total..     */
00315   }
00316 
00317   return col;
00318 }
00319 
00320 
00321 

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net