Shadowrun: Awakened 29 September 2011 - Build 871
vol.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  * vol.c - Volume rendering helper routines etc.
00060  *
00061  *
00062  *  $Id: vol.cpp,v 1.3 2007-02-22 18:17:51 amalakho Exp $
00063  */
00064 
00065 #include<stdio.h>
00066 #include "machine.h"
00067 #include "types.h"
00068 #include "macros.h"
00069 #include "vector.h"
00070 #include "util.h"
00071 #include "vol.h"
00072 #include "box.h"
00073 #include "trace.h"
00074 #include "ui.h"
00075 #include "light.h"
00076 #include "shade.h"
00077 
00078 int scalarvol_bbox(void * obj, vector * min, vector * max) {
00079   box * b = (box *) obj;
00080 
00081   *min = b->min;
00082   *max = b->max;
00083 
00084   return 1;
00085 }
00086 
00087 void * newscalarvol(void * intex, vector min, vector max, 
00088                     int xs, int ys, int zs, char * fname, scalarvol * invol) {
00089   box * bx;
00090   texture * tx, * tex;
00091   scalarvol * vol;
00092 
00093   tex=(texture *)intex;
00094   tex->shadowcast = 0; /* doesn't cast a shadow */
00095 
00096   tx=(texture *)rt_getmem(sizeof(texture));
00097 
00098   /* is the volume data already loaded? */
00099   if (invol==NULL) {
00100     vol=(scalarvol *)rt_getmem(sizeof(scalarvol));
00101     vol->loaded=0;
00102     vol->data=NULL;
00103   }
00104   else
00105     vol=invol;
00106 
00107   vol->opacity=tex->opacity;
00108   vol->xres=xs;
00109   vol->yres=ys;
00110   vol->zres=zs;
00111   strcpy(vol->name, fname);
00112 
00113   tx->ctr.x = 0.0;
00114   tx->ctr.y = 0.0;
00115   tx->ctr.z = 0.0;
00116   tx->rot   = tx->ctr;
00117   tx->scale = tx->ctr;
00118   tx->uaxs  = tx->ctr;
00119   tx->vaxs  = tx->ctr;
00120 
00121   tx->islight = 0;
00122   tx->shadowcast = 0; /* doesn't cast a shadow */
00123 
00124   tx->col = tex->col;
00125   tx->ambient  = 1.0;
00126   tx->diffuse  = 0.0;
00127   tx->specular = 0.0;
00128   tx->opacity  = 1.0;
00129   tx->img = vol;
00130   tx->texfunc = (color(*)(void *, void *, void *))(scalar_volume_texture);
00131 
00132   bx=newbox(tx, min, max);
00133   tx->obj = (void *) bx; /* XXX hack! */
00134 
00135   return (void *) bx;
00136 }
00137 
00138 
00139 color VoxelColor(flt scalar) {
00140   color col;
00141 
00142   if (scalar > 1.0) 
00143     scalar = 1.0;
00144 
00145   if (scalar < 0.0)
00146     scalar = 0.0;
00147 
00148   if (scalar < 0.25) {
00149     col.r = scalar * 4.0;
00150     col.g = 0.0;
00151     col.b = 0.0;
00152   }
00153   else {
00154     if (scalar < 0.75) {
00155       col.r = 1.0;
00156       col.g = (scalar - 0.25) * 2.0;
00157       col.b = 0.0;
00158     }
00159     else {
00160       col.r = 1.0;
00161       col.g = 1.0;
00162       col.b = (scalar - 0.75) * 4.0;
00163     }
00164   }
00165 
00166   return col;
00167 } 
00168 
00169 color scalar_volume_texture(vector * hit, texture * tex, ray * ry) {
00170   color col, col2;
00171   box * bx;
00172   flt a, tx1, tx2, ty1, ty2, tz1, tz2;
00173   flt tnear, tfar;
00174   flt t, tdist, dt, sum, tt; 
00175   vector pnt, bln;
00176   scalarvol * vol;
00177   flt scalar, transval; 
00178   int x, y, z;
00179   unsigned char * ptr;
00180 
00181   bx=(box *) tex->obj;
00182   vol=(scalarvol *)bx->tex->img;
00183    
00184   col.r=0.0;
00185   col.g=0.0;
00186   col.b=0.0;
00187  
00188   tnear= -FHUGE;
00189   tfar= FHUGE;
00190  
00191   if (ry->d.x == 0.0) {
00192     if ((ry->o.x < bx->min.x) || (ry->o.x > bx->max.x)) return col;
00193   }
00194   else {
00195     tx1 = (bx->min.x - ry->o.x) / ry->d.x;
00196     tx2 = (bx->max.x - ry->o.x) / ry->d.x;
00197     if (tx1 > tx2) { a=tx1; tx1=tx2; tx2=a; }
00198     if (tx1 > tnear) tnear=tx1;
00199     if (tx2 < tfar)   tfar=tx2;
00200   }
00201   if (tnear > tfar) return col;
00202   if (tfar < 0.0) return col;
00203  
00204  if (ry->d.y == 0.0) {
00205     if ((ry->o.y < bx->min.y) || (ry->o.y > bx->max.y)) return col;
00206   }
00207   else {
00208     ty1 = (bx->min.y - ry->o.y) / ry->d.y;
00209     ty2 = (bx->max.y - ry->o.y) / ry->d.y;
00210     if (ty1 > ty2) { a=ty1; ty1=ty2; ty2=a; }
00211     if (ty1 > tnear) tnear=ty1;
00212     if (ty2 < tfar)   tfar=ty2;
00213   }
00214   if (tnear > tfar) return col;
00215   if (tfar < 0.0) return col;
00216  
00217   if (ry->d.z == 0.0) {
00218     if ((ry->o.z < bx->min.z) || (ry->o.z > bx->max.z)) return col;
00219   }
00220   else {
00221     tz1 = (bx->min.z - ry->o.z) / ry->d.z;
00222     tz2 = (bx->max.z - ry->o.z) / ry->d.z;
00223     if (tz1 > tz2) { a=tz1; tz1=tz2; tz2=a; }
00224     if (tz1 > tnear) tnear=tz1;
00225     if (tz2 < tfar)   tfar=tz2;
00226   }
00227   if (tnear > tfar) return col;
00228   if (tfar < 0.0) return col;
00229  
00230   if (tnear < 0.0) tnear=0.0;
00231  
00232   tdist=sqrt((flt) (vol->xres*vol->xres + vol->yres*vol->yres + vol->zres*vol->zres));
00233   tt = (vol->opacity / tdist); 
00234 
00235   bln.x=fabs(bx->min.x - bx->max.x);
00236   bln.y=fabs(bx->min.y - bx->max.y);
00237   bln.z=fabs(bx->min.z - bx->max.z);
00238   
00239   dt=sqrt(bln.x*bln.x + bln.y*bln.y + bln.z*bln.z) / tdist; 
00240   sum=0.0;
00241 
00242   /* move the volume residency check out of loop.. */
00243   if (!vol->loaded) {
00244     LoadVol(vol);
00245     vol->loaded=1;
00246   }
00247  
00248   for (t=tnear; t<=tfar; t+=dt) {
00249     pnt.x=((ry->o.x + (ry->d.x * t)) - bx->min.x) / bln.x;
00250     pnt.y=((ry->o.y + (ry->d.y * t)) - bx->min.y) / bln.y;
00251     pnt.z=((ry->o.z + (ry->d.z * t)) - bx->min.z) / bln.z;
00252  
00253     x=(int) ((vol->xres - 1.5) * pnt.x + 0.5);
00254     y=(int) ((vol->yres - 1.5) * pnt.y + 0.5);
00255     z=(int) ((vol->zres - 1.5) * pnt.z + 0.5);
00256    
00257     ptr = vol->data + ((vol->xres * vol->yres * z) + (vol->xres * y) + x);
00258    
00259     scalar = (flt) ((flt) 1.0 * ((int) ptr[0])) / 255.0;
00260 
00261     sum += tt * scalar; 
00262 
00263     transval = tt * scalar; 
00264 
00265     col2 = VoxelColor(scalar);
00266 
00267     if (sum < 1.0) {
00268       col.r += transval * col2.r;
00269       col.g += transval * col2.g;
00270       col.b += transval * col2.b;
00271       if (sum < 0.0) sum=0.0;
00272     }  
00273     else { 
00274       sum=1.0;
00275     }
00276   }
00277 
00278   if (sum < 1.0) {      /* spawn transmission rays / refraction */    
00279     color transcol;
00280 
00281     transcol = shade_transmission(ry, hit, 1.0 - sum);
00282 
00283     col.r += transcol.r; /* add the transmitted ray  */    
00284     col.g += transcol.g; /* to the diffuse and       */
00285     col.b += transcol.b; /* transmission total..     */  
00286   }
00287 
00288   return col;
00289 }
00290 
00291 void LoadVol(scalarvol * vol) { 
00292   FILE * dfile;
00293   int status;
00294   char msgtxt[2048];
00295  
00296   dfile=fopen(vol->name, "r");
00297   if (dfile==NULL) {
00298     char msgtxt[2048];
00299     sprintf(msgtxt, "Vol: can't open %s for input!!! Aborting\n",vol->name); 
00300     rt_ui_message(MSG_ERR, msgtxt);
00301     rt_ui_message(MSG_ABORT, "Rendering Aborted.");
00302     exit(1);
00303   }  
00304  
00305   sprintf(msgtxt, "loading %dx%dx%d volume set from %s",
00306       vol->xres, vol->yres, vol->zres, vol->name);
00307   rt_ui_message(MSG_0, msgtxt);
00308 
00309   vol->data = (unsigned char *)rt_getmem(vol->xres * vol->yres * vol->zres);
00310 
00311   status=fread(vol->data, 1, (vol->xres * vol->yres * vol->zres), dfile);
00312 }

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