Text archives Help
- From: abe@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r437 - in branches/itanium2: Core/Color Model/Groups Model/Intersections Model/Materials Model/Primitives Model/Readers Model/Readers/glm Readers Readers/DoubleEagle fox scenes
- Date: Fri, 22 Jul 2005 16:00:28 -0600 (MDT)
Author: abe
Date: Fri Jul 22 16:00:18 2005
New Revision: 437
Added:
branches/itanium2/Model/Intersections/TriangleEdge.h
branches/itanium2/Model/Primitives/BvhTriangleMesh.cc
branches/itanium2/Model/Primitives/BvhTriangleMesh.h
Modified:
branches/itanium2/Core/Color/ColorSpace.h
branches/itanium2/Model/Groups/RealisticBvh.cc
branches/itanium2/Model/Groups/RealisticBvh.h
branches/itanium2/Model/Groups/kdtree.cc
branches/itanium2/Model/Groups/kdtree.h
branches/itanium2/Model/Intersections/CMakeLists.txt
branches/itanium2/Model/Materials/Dielectric.cc
branches/itanium2/Model/Materials/Dielectric.h
branches/itanium2/Model/Materials/Lambertian.cc
branches/itanium2/Model/Materials/MetalMaterial.cc
branches/itanium2/Model/Materials/Phong.cc
branches/itanium2/Model/Materials/Phong.h
branches/itanium2/Model/Primitives/CMakeLists.txt
branches/itanium2/Model/Primitives/PrimitiveCommon.h
branches/itanium2/Model/Primitives/Triangle.cc
branches/itanium2/Model/Readers/CMakeLists.txt
branches/itanium2/Model/Readers/glm/glm.h
branches/itanium2/Readers/CMakeLists.txt
branches/itanium2/Readers/DoubleEagle/vn2v3c1.cc
branches/itanium2/fox/fox_manta.cc
branches/itanium2/scenes/objviewer.cc
Log:
Incremental changes for siggraph demo codes--and solomon wants to see some
code.
M scenes/objviewer.cc
Note this will test two different bvh trees.
M Readers/DoubleEagle/vn2v3c1.cc
Note this has evolved into a .v3c1 file tool with plenty of options.
M Readers/CMakeLists.txt
M Core/Color/ColorSpace.h
M fox/fox_manta.cc
Removed Manta_histx dependency. (histx support on altix not checked in)
M Model/Groups/kdtree.cc
M Model/Groups/RealisticBvh.cc
M Model/Groups/kdtree.h
M Model/Groups/RealisticBvh.h
Incremental changes to bvh and kdtree.
M Model/Materials/Dielectric.cc
M Model/Materials/Dielectric.h
M Model/Materials/Phong.cc
M Model/Materials/Phong.h
M Model/Materials/Lambertian.cc
M Model/Materials/MetalMaterial.cc
Added Pete Shirley's code.
M Model/Readers/glm/glm.h
M Model/Readers/CMakeLists.txt
A Model/Intersections/TriangleEdge.h
M Model/Intersections/CMakeLists.txt
Moved ray triangle intersection (used all over the place) to a single
function.
A Model/Primitives/BvhTriangleMesh.h
A Model/Primitives/BvhTriangleMesh.cc
Indexed triangle mesh backed up by bvh. Seems very slow, not sure why.
M Model/Primitives/CMakeLists.txt
M Model/Primitives/Triangle.cc
M Model/Primitives/PrimitiveCommon.h
Noticed that preprocess must be called inorder for activeLights to work....
added a comment...
Modified: branches/itanium2/Core/Color/ColorSpace.h
==============================================================================
--- branches/itanium2/Core/Color/ColorSpace.h (original)
+++ branches/itanium2/Core/Color/ColorSpace.h Fri Jul 22 16:00:18 2005
@@ -156,6 +156,14 @@
returnValue.data[i] = Exp(scale*data[i]);
return returnValue;
}
+
+ ColorSpace<Traits> attenuate(const ColorSpace<Traits> &scale)
const {
+ using SCIRun::Exp;
+ ColorSpace<Traits> returnValue;
+ for(int i=0;i<NumComponents;i++)
+ returnValue.data[i] = Exp(scale.data[i]*data[i]);
+ return returnValue;
+ }
protected:
// DO NOT MAKE THIS PUBLIC!
ComponentType data[NumComponents];
@@ -164,6 +172,7 @@
data[i] = fillValue;
}
};
+
}
#endif
Modified: branches/itanium2/Model/Groups/RealisticBvh.cc
==============================================================================
--- branches/itanium2/Model/Groups/RealisticBvh.cc (original)
+++ branches/itanium2/Model/Groups/RealisticBvh.cc Fri Jul 22 16:00:18
2005
@@ -1,4 +1,33 @@
+
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005
+ Silicon Graphics Inc. Mountain View California.
+
+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ */
+
#include <Interface/Context.h>
#include <Interface/RayPacket.h>
@@ -18,6 +47,8 @@
// Update the bounding box of this node.
child0->computeBounds( context, bounds );
child1->computeBounds( context, bounds );
+
+ split_axis = 0;
}
// Rearrange the pointers in the input array around a pivot point.
@@ -51,7 +82,7 @@
Object *RealisticBvh::build_branch( Object **array, int size, int axis ) {
- // Check to exit conditions.
+ // Check two exit conditions.
if (size == 1)
return array[0];
if (size == 2)
@@ -84,9 +115,19 @@
}
// Construct a bvh given an array of object pointers.
-RealisticBvh::RealisticBvh( Object **array, int size ) {
+RealisticBvh::RealisticBvh( Object **array, int size ) : split_axis( 0 ) {
+
+ // Check to see if there is only one node.
+ if (size == 1) {
+ child[0] = child[1] = array[0];
+ return;
+ }
+ if (size == 2) {
+ child[0] = array[0];
+ child[1] = array[1];
+ return;
+ }
- // Check to exit conditions.
PreprocessContext context;
// Compute the bounds of the array.
@@ -100,9 +141,6 @@
// Split along the axis.
int mid_point = qsplit( array, size, pivot[0], 0 );
- // Save the split axis.
- split_axis = 0;
-
// Create new left and right children.
child[0] = build_branch( array, mid_point, 1 );
child[1] = build_branch( array+mid_point, size-mid_point, 1 );
@@ -112,6 +150,11 @@
void RealisticBvh::preprocess(const PreprocessContext& context) {
// Build occurs in the constructor.
+ if (child[0])
+ child[0]->preprocess( context );
+
+ if (child[1])
+ child[1]->preprocess( context );
}
void RealisticBvh::computeBounds(const PreprocessContext& context, BBox&
bbox) const {
Modified: branches/itanium2/Model/Groups/RealisticBvh.h
==============================================================================
--- branches/itanium2/Model/Groups/RealisticBvh.h (original)
+++ branches/itanium2/Model/Groups/RealisticBvh.h Fri Jul 22 16:00:18
2005
@@ -1,5 +1,31 @@
-
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005
+ Silicon Graphics Inc. Mountain View California.
+
+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ */
#ifndef Manta_Model_RealisticBvh__H
#define Manta_Model_RealisticBvh__H
@@ -11,6 +37,7 @@
// This class follows the implementation from
// "Realistic Ray Tracing"
+
// This implemention relies on virtual method calls to determine
// internal nodes from leaf nodes, there is no explicit
representation.
Modified: branches/itanium2/Model/Groups/kdtree.cc
==============================================================================
--- branches/itanium2/Model/Groups/kdtree.cc (original)
+++ branches/itanium2/Model/Groups/kdtree.cc Fri Jul 22 16:00:18 2005
@@ -1,4 +1,33 @@
+
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005
+ Silicon Graphics Inc. Mountain View California.
+
+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ */
+
#include <iostream>
Modified: branches/itanium2/Model/Groups/kdtree.h
==============================================================================
--- branches/itanium2/Model/Groups/kdtree.h (original)
+++ branches/itanium2/Model/Groups/kdtree.h Fri Jul 22 16:00:18 2005
@@ -1,3 +1,31 @@
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005
+ Silicon Graphics Inc. Mountain View California.
+
+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ */
+
#ifndef __KD_TREE_H__
#define __KD_TREE_H__
Modified: branches/itanium2/Model/Intersections/CMakeLists.txt
==============================================================================
--- branches/itanium2/Model/Intersections/CMakeLists.txt (original)
+++ branches/itanium2/Model/Intersections/CMakeLists.txt Fri Jul 22
16:00:18 2005
@@ -1,5 +1,5 @@
SET(Manta_Intersections_SRCS
Intersections/AxisAlignedBox.h
- # Intersections/AxisAlignedBox.cc
+ Intersections/TriangleEdge.h
Intersections/Plane.h
)
Added: branches/itanium2/Model/Intersections/TriangleEdge.h
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Intersections/TriangleEdge.h Fri Jul 22
16:00:18 2005
@@ -0,0 +1,108 @@
+
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005
+ Silicon Graphics Inc. Mountain View California.
+
+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef Manta_Model_Intersections_TriangleEdge
+#define Manta_Model_Intersections_TriangleEdge
+
+#include <MantaTypes.h>
+#include <Core/Geometry/Ray.h>
+#include <Core/Geometry/PointVector.h>
+#include <Interface/RayPacket.h>
+
+namespace Manta {
+
+ namespace Intersection {
+
+ inline bool intersectTriangleEdge(Real &t, Real &u, Real &v,
+
const Ray &ray,
+
const Vector &edge1, const Vector
&edge2, const Point &p0 )
+ {
+
+ Vector tvec, pvec, qvec;
+
+ /* begin calculating determinant - also used to
calculate U parameter */
+ pvec = Cross( ray.direction(), edge2 );
+
+ // CROSS(pvec, dir, edge2);
+
+ /* if determinant is near zero, ray lies in plane of
triangle */
+ // det = DOT(edge1, pvec);
+ Real det = Dot( edge1, pvec );
+
+ /* calculate distance from vert0 to ray origin */
+ // SUB(tvec, orig, vert0);
+ tvec = ray.origin() - p0;
+
+ qvec = Cross( tvec, edge1 );
+ // CROSS(qvec, tvec, edge1);
+
+ /* calculate U parameter */
+ // float uu = DOT(tvec, pvec);
+ // float vv;
+ Real uu = Dot( tvec, pvec );
+ Real vv;
+
+ if (det > 1e-5) {
+ if (uu < 0.0 || uu > det)
+ return false;
+
+ /* calculate V parameter and test bounds */
+ vv = Dot( ray.direction(), qvec );
+
+ if (vv < 0.0 || uu + vv > det)
+ return false;
+
+ }
+ else if(det < -1e-5f) {
+ if (uu > 0.0 || uu < det)
+ return false;
+
+ /* calculate V parameter and test bounds */
+ vv = Dot(ray.direction(), qvec) ;
+ if (vv > 0.0 || uu + vv < det)
+ return false;
+ }
+ else {
+ return false; /* ray is parallell to the
plane of the triangle */
+ }
+
+ Real inv_det = 1.0 / det;
+
+ t = (Dot( edge2, qvec ) * inv_det);
+ u = (uu * inv_det);
+ v = (vv * inv_det);
+
+ return true;
+ }
+ }
+};
+
+#endif
+
+
Modified: branches/itanium2/Model/Materials/Dielectric.cc
==============================================================================
--- branches/itanium2/Model/Materials/Dielectric.cc (original)
+++ branches/itanium2/Model/Materials/Dielectric.cc Fri Jul 22 16:00:18
2005
@@ -1,4 +1,3 @@
-
#include <Model/Materials/Dielectric.h>
#include <Core/Math/ipow.h>
#include <Interface/AmbientLight.h>
@@ -12,13 +11,54 @@
#include <Interface/ShadowAlgorithm.h>
#include <Core/Util/NotFinished.h>
+/* New Dielectric by P. Shirley 7/18
+ Notes:
+ 1. just single ray packets for reflected and refracted rays
+ 2. Assumes normal vector points toward n and away from nt
+ 3. I removed shadow rays and phong highlight. I am assuming
+ highlights will be in the background and specular rays
+ will thus create pseudo-highlights
+ 4. I have an old version of Manta but I had to change sphere
+ to return hits beyond t=epsilon rather than t=0
+
+ Changes that should be made later:
+ 1. compress rays into packets (espectially refraction rays)
+ 2. add extinction (Beer's Law)
+ 3. get rid of diffuse and specular constructor args
+*/
+
using namespace Manta;
-Dielectric::Dielectric(const Color& diffuse, const Color& specular,
-
int specpow, double n, double nt)
-: diffuse(diffuse), specular(specular), specpow(specpow),
-n(n), nt(nt)
+// Note-- both v and n must be unit vectors!
+// v is the incident vector and is rewritten
+bool Refract(const Vector& n, double ni, double nt, Vector& v)
{
+ double k;
+ Vector s;
+
+ k = Dot(v, n);
+ s = (ni/nt) * (v - k*n);
+ k = 1.0 - Dot(s,s);
+
+ if (k < 1.0e-6)
+ {
+ return false; // no refraction possible
+ }
+ else
+ {
+ v = s - sqrt(k)*n;
+ return true;
+ }
+}
+
+
+Dielectric::Dielectric(const Color& diffuse, const Color& specular, const
Color &minusC_,
+ int specpow, double n, double nt)
+ : diffuse(diffuse), specular(specular), specpow(specpow),
+ n(n), nt(nt), minusC( minusC_ )
+{
+ r0 = (n - nt) / (n + nt);
+ r0 *= r0;
}
Dielectric::~Dielectric()
@@ -27,142 +67,101 @@
void Dielectric::shade(const RenderContext& context, RayPacket& rays) const
{
- // Shade a bunch of rays. We know that they all have the same intersected
- // object and are all of the same material
-
rays.normalizeDirections();
-
- // Compute normals
rays.computeNormals(context);
-
-
- Scene *scene = (Scene*)context.scene;
- LightSet *activeLights = scene->getLights();
-
- // Compute ambient contributions for all rays
- activeLights->getAmbientLight()->computeAmbient(context, rays);
-
- RayPacketData data;
- int start = 0;
- do {
- RayPacket shadowRays(data, 0, rays.getDepth(), 0);
- int end = context.shadowAlgorithm->computeShadows(context, activeLights,
-
rays, start,
shadowRays);
-
- if(shadowRays.getFlags() & RayPacket::NormalizedDirections){
- for(int i=start;i<end;i++){
- RayPacket::Element& e = rays.get(i);
- Color totalDiffuse(e.ambientLight);
- Color totalSpecular = Color::black();
- for(int j=e.shadowBegin;j<e.shadowEnd;j++){
- RayPacket::Element& s =
shadowRays.get(j);
- if(!s.hitInfo.wasHit()){
- double cos_theta =
Dot(s.ray.direction(), e.normal);
- totalDiffuse +=
s.light*cos_theta;
- Vector H =
s.ray.direction()-e.ray.direction();
- H.normalize();
- double cos_alpha = Dot(H,
e.normal);
- if(cos_alpha > 0)
- totalSpecular +=
s.light * ipow(cos_alpha, specpow);
- }
- }
- rays.setResult(i,
diffuse*totalDiffuse+specular*totalSpecular);
- }
- } else {
- for(int i=start;i<end;i++){
- RayPacket::Element& e = rays.get(i);
- Color totalDiffuse(e.ambientLight);
- Color totalSpecular = Color::black();
- for(int j=e.shadowBegin;j<e.shadowEnd;j++){
- RayPacket::Element& s =
shadowRays.get(j);
- if(!s.hitInfo.wasHit()){
- s.ray.normalizeDirection();
- double cos_theta =
Dot(s.ray.direction(), e.normal);
- totalDiffuse +=
s.light*cos_theta;
- Vector H =
s.ray.direction()-e.ray.direction();
- H.normalize();
- double cos_alpha = Dot(H,
e.normal);
- if(cos_alpha > 0)
- totalSpecular +=
s.light * ipow(cos_alpha, specpow);
- }
- }
- rays.setResult(i,
diffuse*totalDiffuse+specular*totalSpecular);
- }
- }
- start = end;
- } while(start < rays.getSize());
-
+ if (!(rays.getFlags() & rays.HaveUnitNormals)) {
+ // I would like to replace this with a call to
+ // rays.normalizeNormals() but need to add it.
+ fprintf(stderr, "Dielectric assumes unit normals\n");
+ exit(-1);
+ }
- int maxdepth = 5;
- if(rays.getDepth() < maxdepth) {
- // Compute refractions
- double c[RayPacket::MaxSize];
- double tst[RayPacket::MaxSize];
- Color col[RayPacket::MaxSize];
-
- RayPacketData rfdata;
- RayPacket refr_rays(rfdata, rays.getSize(), rays.getDepth()+1,
-
RayPacket::NormalizedDirections);
- refr_rays.useLocalColors();
+ if(rays.getDepth() >= context.scene->getRenderParameters().maxDepth)
+ {
+ for(int i=0;i<rays.getSize();i++)
+ rays.setResult(i, Color::white()); // average scene color might be
better
+ }
+ else
+ {
rays.computeHitPositions();
-
- for(int i=0;i<rays.getSize();i++){
- RayPacket::Element& e = rays.get(i);
- Vector d = e.ray.direction();
- Vector norm = e.normal;
- tst[i] = 1-((n*n*(1-Dot(d,e.normal)*Dot(d,e.normal)))/(nt*nt));
- Vector refr_dir = ((n*(d-norm*Dot(d,norm)))/nt)-(norm*tst[i]);
- RayPacket::Element& r = refr_rays.get(i);
- double x = refr_dir.x()*0.00001-e.hitPosition.x();
- double y = refr_dir.y()*0.00001-e.hitPosition.y();
- double z = refr_dir.z()*0.00001-e.hitPosition.z();
- r.ray.set(Point(x,y,z), refr_dir);
-
- if(Dot(d,norm) < 0) {
- c[i] = -Dot(e.ray.direction(), e.normal);
- col[i] = Color::white();
- }
- else {
- c[i] = Dot(refr_dir, e.normal);
- double tmpt = e.hitInfo.minT();
- col[i] = e.color->attenuate(-tmpt);
- }
- }
-
- // Compute reflections
- RayPacketData rdata;
- RayPacket refl_rays(rdata, rays.getSize(), rays.getDepth()+1,
-
RayPacket::NormalizedDirections);
- refl_rays.useLocalColors();
- double *refl = new double[rays.getSize()];
- for(int i=0;i<rays.getSize();i++) {
- double R0 = ((n-1)*(n-1))/((n+1)*(n+1));
- refl[i] = R0 + ((1-R0)*(1-c[i])*(1-c[i])*(1-c[i])*(1-c[i])*(1-c[i]));
- RayPacket::Element& e = rays.get(i);
- Vector refl_dir = e.ray.direction() - e.normal*(2*Dot(e.normal,
e.ray.direction()));
- RayPacket::Element& r = refl_rays.get(i);
- double x = refl_dir.x()*0.00001+e.hitPosition.x();
- double y = refl_dir.y()*0.00001+e.hitPosition.y();
- double z = refl_dir.z()*0.00001+e.hitPosition.z();
- r.ray.set(Point(x,y,z), refl_dir);
- }
-
- // Store Color
- refl_rays.resetHit();
- refr_rays.resetHit();
- context.renderer->traceRays(context, refl_rays);
- context.renderer->traceRays(context, refr_rays);
- for(int i=0;i<rays.getSize();i++){
- RayPacket::Element& e = rays.get(i);
- RayPacket::Element& rl = refl_rays.get(i);
- RayPacket::Element& rf = refr_rays.get(i);
- if(tst[i] < 0) {
- *e.color += col[i]*(*rl.color);
- }
- else {
- *e.color += col[i]*(((*rl.color) * refl[i]) +
-
((*rf.color) * (1-refl[i])));
- }
+ for(int i=0;i<rays.getSize();i++)
+ {
+ RayPacket::Element& e = rays.get(i);
+ double cosine = -Dot(e.normal, e.ray.direction());
+ Vector refl_dir, refr_dir;
+ bool from_outside = (cosine > 0);
+ bool total_internal_reflection;
+ refr_dir = e.ray.direction();
+ refl_dir = e.ray.direction() + 2 * cosine * e.normal;
+ if (from_outside) {
+ total_internal_reflection = !Refract(e.normal, n, nt,
refr_dir);
+ }
+ else
+ {
+ total_internal_reflection = !Refract(-e.normal, nt, n,
refr_dir);
+ cosine = -cosine;
+ }
+
+ if (total_internal_reflection) {
+ // Create a size one ray packet
+ int flags = 0;
+ int size = 1;
+ RayPacketData raydata;
+ RayPacket refl_rays(raydata, size, rays.getDepth()+1, flags);
+
+ RayPacket::Element& r = refl_rays.get(0);
+ r.ray.set(e.hitPosition, refl_dir);
+ refl_rays.useLocalColors();
+ context.renderer->traceRays(context, refl_rays);
+
+ // Apply beer's law
attenuation.
+ // (*r.color) =
r.color->attenuate( minusC * r.hitInfo.minT() );
+
+ rays.setResult(i, *r.color);
+ }
+ else // reflection and refraction
+ {
+ float cosine2;
+ if (from_outside) {
+ cosine2 = -Dot(e.normal, refr_dir);
+ }
+ else {
+ cosine2 = Dot(e.normal, refr_dir);
+ }
+
+ if (cosine2 < cosine) cosine = cosine2; // for Schlick
+ float k = 1 - cosine;
+ k*=k*k*k*k;
+ float R = r0*(1-k) + k;
+
+ int flags = 0;
+ int size = 1;
+
+
+ // Reflected rays.
+ RayPacketData raydata;
+ RayPacket refl_rays(raydata, size, rays.getDepth()+1, flags);
+ RayPacket::Element& r = refl_rays.get(0);
+ r.ray.set(e.hitPosition, refl_dir);
+ refl_rays.useLocalColors();
+ context.renderer->traceRays(context, refl_rays);
+
+ // Refracted rays.
+ RayPacketData raydata2;
+ RayPacket refr_rays(raydata2, size, rays.getDepth()+1, flags);
+ RayPacket::Element& r2 = refr_rays.get(0);
+ r2.ray.set(e.hitPosition, refr_dir);
+ refr_rays.normalizeDirections();
+ refr_rays.useLocalColors();
+ context.renderer->traceRays(context, refr_rays);
+
+ // Apply beer's law
attenuation.
+ // (*r2.color) *=
minusC.attenuate( r2.hitInfo.minT() );
+
+ rays.setResult(i, (Color::white()*R)*(*r.color) +
+ (Color::white()*(1-R))*(*r2.color) );
+
+ }
}
}
Modified: branches/itanium2/Model/Materials/Dielectric.h
==============================================================================
--- branches/itanium2/Model/Materials/Dielectric.h (original)
+++ branches/itanium2/Model/Materials/Dielectric.h Fri Jul 22 16:00:18
2005
@@ -10,16 +10,19 @@
class Dielectric : public LitMaterial {
public:
- Dielectric(const Color& diffuse, const Color& specular, int specpow,
+ // minusC = log( beersA ) but there isn't an easy way to take
the log of a color.
+ Dielectric(const Color& reflected, const Color& specular, const Color
&minusC, int specpow,
double n, double nt);
+
virtual ~Dielectric();
virtual void shade(const RenderContext& context, RayPacket& rays) const;
private:
Color diffuse;
Color specular;
+ Color minusC; // Beer's law.
int specpow;
- double n, nt;
+ double n, nt, r0;
};
}
Modified: branches/itanium2/Model/Materials/Lambertian.cc
==============================================================================
--- branches/itanium2/Model/Materials/Lambertian.cc (original)
+++ branches/itanium2/Model/Materials/Lambertian.cc Fri Jul 22 16:00:18
2005
@@ -7,7 +7,6 @@
#include <Interface/AmbientLight.h>
#include <Interface/Context.h>
#include <Interface/ShadowAlgorithm.h>
-#include <Interface/Scene.h>
#include <Model/Textures/Constant.h>
using namespace Manta;
@@ -18,7 +17,7 @@
}
Lambertian::Lambertian(const Texture<Color>* colortex)
-: colortex(colortex)
+ : colortex(colortex)
{
}
@@ -30,92 +29,36 @@
{
// Shade a bunch of rays. We know that they all have the same intersected
// object and are all of the same material
-
+
// Compute normals
rays.computeNormals(context);
-
+
// Compute colors
Color colors[RayPacket::MaxSize];
colortex->mapValues(context, rays, colors);
-
+
// Compute ambient contributions for all rays
- Scene *scene = (Scene*)context.scene;
- scene->getLights()->getAmbientLight()->computeAmbient(context, rays);
-
-#if 0
- RayPacket::Iterator ray_iter = rays.begin(); // Iterate across the
ray packet making shadow rays.
- RayPacket::Iterator ray_end = rays.end();
- RayPacket::Iterator ray_last; // Iterator to the last ray in the
shadow packet.
- RayPacket::Iterator ray_copy; // Iterator between ray_iter and
ray_last.
-
- RayPacket shadow_rays; // Ray Packet for the shadow rays..
- RayPacket::Iterator shadow_iter // Iterator over shadow packets.
-
- for (;ray_iter<ray_end;++ray_iter) {
-
- // Create a shadow ray packet.
- ray_last = context.shadowAlgorithm->computeShadows( context,
scene->getLights(),
- ray_iter,
ray_end,
-
shadow_rays );
-
- // Compute the total contribution for each ray that has
shadow rays
- // in this shadow packet.
- for (ray_copy=ray_iter;ray_copy<ray_last;++ray_copy) {
- Color total_light = ray_copy.getAmbientLight();
-
- // Iterate over the shadow rays for this inital ray.
- for
(shadow_iter=ray_copy.shadowBegin();shadow_iter<ray_copy.shadowEnd();++shadow_iter)
{
-
- // Check to see if a hit occured.
- if (shadow_iter.getHitInfo().wasHit()) {
- Real cos_theta =
Dot(shadow_iter.getRay().direction(),
-
ray_copy.getNormal() );
- // Add the contribution for this
light.
- total_light += shadow_iter.getLight();
- }
- }
-
- // Set the color for this ray.
- ray_copy.setResult( colors[i]*totalLight );
- }
- }
-
-#endif
+ activeLights->getAmbientLight()->computeAmbient(context, rays);
+
RayPacketData data;
int start = 0;
+ rays.normalizeDirections();
do {
RayPacket shadowRays(data, 0, rays.getDepth(), 0);
- int end = context.shadowAlgorithm->computeShadows(context,
scene->getLights(),
-
rays, start,
shadowRays);
- if(shadowRays.getFlags() & RayPacket::NormalizedDirections){
+ int end = context.shadowAlgorithm->computeShadows(context, activeLights,
+ rays, start,
shadowRays);
for(int i=start;i<end;i++){
- RayPacket::Element& e = rays.get(i);
- Color totalLight(e.ambientLight);
- for(int j=e.shadowBegin;j<e.shadowEnd;j++){
- RayPacket::Element& s =
shadowRays.get(j);
- if(!s.hitInfo.wasHit()){
- double cos_theta =
Dot(s.ray.direction(), e.normal);
- totalLight +=
s.light*cos_theta;
- }
- }
- rays.setResult(i, colors[i]*totalLight);
- }
- } else {
- for(int i=start;i<end;i++){
- RayPacket::Element& e = rays.get(i);
- Color totalLight(e.ambientLight);
- for(int j=e.shadowBegin;j<e.shadowEnd;j++){
- RayPacket::Element& s =
shadowRays.get(j);
- if(!s.hitInfo.wasHit()){
- s.ray.normalizeDirection();
- double cos_theta =
Dot(s.ray.direction(), e.normal);
- totalLight +=
s.light*cos_theta;
- }
- }
- rays.setResult(i, colors[i]*totalLight);
+ RayPacket::Element& e = rays.get(i);
+ Color totalLight(e.ambientLight);
+ for(int j=e.shadowBegin;j<e.shadowEnd;j++){
+ RayPacket::Element& s = shadowRays.get(j);
+ if(!s.hitInfo.wasHit()){
+ double cos_theta = Dot(s.ray.direction(), e.normal);
+ totalLight += s.light*cos_theta;
+ }
+ }
+ rays.setResult(i, colors[i]*totalLight);
}
- }
start = end;
} while(start < rays.getSize());
-
}
Modified: branches/itanium2/Model/Materials/MetalMaterial.cc
==============================================================================
--- branches/itanium2/Model/Materials/MetalMaterial.cc (original)
+++ branches/itanium2/Model/Materials/MetalMaterial.cc Fri Jul 22 16:00:18
2005
@@ -31,93 +31,42 @@
void MetalMaterial::shade(const RenderContext& context, RayPacket& rays)
const
{
- // Shade a bunch of rays. We know that they all have the same intersected
- // object and are all of the same material
-
rays.normalizeDirections();
-
- // Compute normals
rays.computeNormals(context);
-
- // Compute colors
Color specular[RayPacket::MaxSize];
specular_reflectance->mapValues(context, rays, specular);
- RayPacketData data;
- int start = 0;
- do {
- RayPacket shadowRays(data, 0, rays.getDepth(), 0);
- int end = context.shadowAlgorithm->computeShadows(context, activeLights,
- rays, start,
shadowRays);
-
- if(shadowRays.getFlags() & RayPacket::NormalizedDirections){
- for(int i=start;i<end;i++){
- RayPacket::Element& e = rays.get(i);
- Color totalSpecular = Color::black();
-
- // for the shadows
- for(int j=e.shadowBegin;j<e.shadowEnd;j++){
- RayPacket::Element& s = shadowRays.get(j);
- if(!s.hitInfo.wasHit()){
- Vector H = s.ray.direction()-e.ray.direction();
- H.normalize();
- double cos_alpha = Dot(H, e.normal);
- if(cos_alpha > 0)
- totalSpecular += s.light*ipow(cos_alpha, phong_exponent);
- }
- }
- rays.setResult(i, specular[i]*totalSpecular);
- }
- } else {
- for(int i=start;i<end;i++){
- RayPacket::Element& e = rays.get(i);
- Color totalSpecular = Color::black();
- for(int j=e.shadowBegin;j<e.shadowEnd;j++){
- RayPacket::Element& s = shadowRays.get(j);
- if(!s.hitInfo.wasHit()){
- s.ray.normalizeDirection();
- Vector H = s.ray.direction()-e.ray.direction();
- H.normalize();
- double cos_alpha = Dot(H, e.normal);
- if(cos_alpha > 0)
- totalSpecular += s.light*ipow(cos_alpha, phong_exponent);
- }
- }
- rays.setResult(i, specular[i]*totalSpecular);
- }
- }
- start = end;
- } while(start < rays.getSize());
-
// Compute reflections
- if(rays.getDepth() < context.scene->getRenderParameters().maxDepth){
+ if(rays.getDepth() < context.scene->getRenderParameters().maxDepth)
+ {
rays.computeHitPositions();
RayPacketData rdata;
RayPacket refl_rays(rdata, rays.getSize(), rays.getDepth()+1,
RayPacket::NormalizedDirections);
refl_rays.useLocalColors();
- for(int i=0;i<rays.getSize();i++){
- RayPacket::Element& e = rays.get(i);
- Vector refl_dir = e.ray.direction() - e.normal*(2*Dot(e.normal,
e.ray.direction()));
- RayPacket::Element& r = refl_rays.get(i);
- r.ray.set(e.hitPosition, refl_dir);
+ for(int i=0;i<rays.getSize();i++)
+ {
+ RayPacket::Element& e = rays.get(i);
+ Vector refl_dir = e.ray.direction() - e.normal*(2*Dot(e.normal,
e.ray.direction()));
+ RayPacket::Element& r = refl_rays.get(i);
+ r.ray.set(e.hitPosition, refl_dir);
}
refl_rays.resetHit();
context.renderer->traceRays(context, refl_rays);
- for(int i=0;i<rays.getSize();i++){
- RayPacket::Element& e = rays.get(i);
- RayPacket::Element& r = refl_rays.get(i);
- double cosine = -Dot(e.normal, e.ray.direction());
- if(cosine < 0)
- cosine =-cosine;
-
- float k = 1 - cosine;
- k*=k*k*k*k;
+ for(int i=0;i<rays.getSize();i++) {
+ RayPacket::Element& e = rays.get(i);
+ RayPacket::Element& r = refl_rays.get(i);
+
+ // compute Schlick Fresnel approximation
+ double cosine = -Dot(e.normal, e.ray.direction());
+ if(cosine < 0) cosine =-cosine;
+ float k = 1 - cosine;
+ k*=k*k*k*k;
- Color R = specular[i] * (1-k) + Color::white()*k;
+ Color R = specular[i] * (1-k) + Color::white()*k;
- *e.color += R * *r.color;
+ *e.color = R * (*r.color);
}
}
}
Modified: branches/itanium2/Model/Materials/Phong.cc
==============================================================================
--- branches/itanium2/Model/Materials/Phong.cc (original)
+++ branches/itanium2/Model/Materials/Phong.cc Fri Jul 22 16:00:18 2005
@@ -50,28 +50,26 @@
// Compute colors
Color diffuse[RayPacket::MaxSize];
diffusetex->mapValues(context, rays, diffuse);
-
Color specular[RayPacket::MaxSize];
speculartex->mapValues(context, rays, specular);
-
- double refl[RayPacket::MaxSize];
+ double refl[RayPacket::MaxSize];
refltex->mapValues(context, rays, refl);
// Compute normals
rays.computeNormals(context);
// Compute ambient contributions for all rays
-
context.scene->getLights()->getAmbientLight()->computeAmbient(context, rays);
+ activeLights->getAmbientLight()->computeAmbient(context, rays);
RayPacketData data;
int start = 0;
do {
RayPacket shadowRays(data, 0, rays.getDepth(), 0);
- int end = context.shadowAlgorithm->computeShadows(context,
context.scene->getLights(),
+ int end = context.shadowAlgorithm->computeShadows(context, activeLights,
rays, start,
shadowRays);
- if(shadowRays.getFlags() & RayPacket::NormalizedDirections){
- for(int i=start;i<end;i++){
+ rays.normalizeDirections();
+ for(int i=start;i<end;i++){
RayPacket::Element& e = rays.get(i);
Color totalDiffuse(e.ambientLight);
Color totalSpecular = Color::black();
@@ -90,28 +88,6 @@
}
rays.setResult(i, diffuse[i]*totalDiffuse+specular[i]*totalSpecular);
}
- } else {
- for(int i=start;i<end;i++){
- RayPacket::Element& e = rays.get(i);
- Color totalDiffuse(e.ambientLight);
- Color totalSpecular = Color::black();
- for(int j=e.shadowBegin;j<e.shadowEnd;j++){
- RayPacket::Element& s = shadowRays.get(j);
- if(!s.hitInfo.wasHit()){
- s.ray.normalizeDirection();
- double cos_theta = Dot(s.ray.direction(), e.normal);
- totalDiffuse += s.light*cos_theta;
- Vector H = s.ray.direction()-e.ray.direction();
- double cos_alpha = Dot(H, e.normal);
- if(cos_alpha > 0){
- double length = H.length();
- totalSpecular += s.light * ipow(cos_alpha/length, specpow);
- }
- }
- }
- rays.setResult(i, diffuse[i]*totalDiffuse+specular[i]*totalSpecular);
- }
- }
start = end;
} while(start < rays.getSize());
Modified: branches/itanium2/Model/Materials/Phong.h
==============================================================================
--- branches/itanium2/Model/Materials/Phong.h (original)
+++ branches/itanium2/Model/Materials/Phong.h Fri Jul 22 16:00:18 2005
@@ -11,10 +11,10 @@
class Phong : public LitMaterial {
public:
- Phong(const Color& diffuse, const Color& specular, int specpow,
- double refl);
- Phong(const Texture<Color>* diffuse, const Texture<Color>* specular,
- int specpow, const Texture<double>* refl);
+
+ // Note if refl == 0 the phong shader won't cast a reflected
ray.
+ Phong(const Color& diffuse, const Color& specular, int specpow, double
refl = 0.0);
+ Phong(const Texture<Color>* diffuse, const Texture<Color>* specular, int
specpow, const Texture<double>* refl);
virtual ~Phong();
virtual void shade(const RenderContext& context, RayPacket& rays) const;
Added: branches/itanium2/Model/Primitives/BvhTriangleMesh.cc
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Primitives/BvhTriangleMesh.cc Fri Jul 22
16:00:18 2005
@@ -0,0 +1,310 @@
+
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005
+ Silicon Graphics Inc. Mountain View California.
+
+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ */
+
+#include <Model/Primitives/BvhTriangleMesh.h>
+#include <Model/Intersections/TriangleEdge.h>
+#include <Model/Intersections/AxisAlignedBox.h>
+
+using namespace Manta;
+
+
+BvhTriangleMesh::Node::Node( int triangle_index_ ) : triangle_index(
triangle_index_ ) {
+
+ child[0] = child[1] = 0;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// Intersection helpers.
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+void BvhTriangleMesh::intersect_leaf(Node *node, const RenderContext
&context, RayPacket &rays ) const {
+
+ // Determine the triangle index.
+ int index = node->triangle_index;
+
+ // Intersect each ray in the packet with the triangle.
+ IndexedTriangle &tri = triangle_array[index];
+
+ Real hit_t, a, b;
+
+ for (int i=0;i<rays.getSize();++i) {
+ RayPacket::Element &e = rays.get(i);
+
+ // Intersect the ray with a triangle.
+ if (Intersection::intersectTriangleEdge( hit_t, // Output ray
t parameter.
+
a, b, // Output texture coords.
+
+
e.ray, // Input ray.
+
+
edge_array[tri.e0], // Input triangle
+
edge_array[tri.e1],
+
vertex_array[tri.v0] ))
+ {
+ // Check to see if the hit is closest so far.
+ if (e.hitInfo.hit(hit_t, material, this, tex)) {
+
+ // Copy over the hit record.
+ Hit &info = e.hitInfo.scratchpad<Hit>();
+
+ info.tri = tri;
+ info.a = a;
+ info.b = b;
+ }
+ }
+ }
+}
+
+void BvhTriangleMesh::intersect_internal(Node *node, const RenderContext&
context, RayPacket& rays) const {
+
+ // Intersect the ray packet with the bounds of this node.
+ bool bbox_intersect[RayPacket::MaxSize];
+
+ for(int i=0;i<rays.getSize();i++) {
+
+ RayPacket::Element& e = rays.get(i);
+
+ // Check to see if the ray hits this node's bounding box.
+ Real min_t, max_t;
+ bbox_intersect[i] = Intersection::intersectAaBox(
node->bounds,
+
+
min_t, max_t,
e.ray,
+
e.signMask,
e.inverseDirection,
+
0.0,
+
e.hitInfo.minT()
);
+ }
+
+ // Find runs of rays which intersect this bounding box and intersect
those
+ // with the children.
+ int begin = 0;
+ int end = 0;
+ int first_child;
+
+ while (begin < rays.getSize()) {
+
+ // Find the beginning of a run.
+ while ((begin < rays.getSize()) && (!bbox_intersect[begin]))
+ ++begin;
+
+ // Determine the first child for the first ray in the packet.
+ first_child = rays.get( begin ).signMask[ node->split_axis ];
+
+ // Find the end of this run.
+ end = begin;
+ while ((end < rays.getSize()) && (bbox_intersect[end]) &&
+ (rays.get( begin ).signMask[ node->split_axis ] ==
first_child))
+ ++end;
+
+ if ((end > begin) && (begin < rays.getSize())) {
+
+ // Create a sub packet.
+ RayPacket sub_packet( rays, begin, end );
+
+
/////////////////////////////////////////////////////////////////////////
+ // Intersect with both children.
+
+ // Check if the node is internal or a leaf.
+ if (node->child[first_child]->isLeaf())
+ intersect_leaf( node->child[first_child],
context, rays );
+ else
+ intersect_internal( node->child[first_child],
context, rays );
+
+ // Check if the node is internal or a leaf.
+ if (node->child[!first_child]->isLeaf())
+ intersect_leaf( node->child[!first_child],
context, rays );
+ else
+ intersect_internal(
node->child[!first_child], context, rays );
+ }
+
+ begin = end;
+ }
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// Builder methods
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+// Rearrange the pointers in the input array around a pivot point.
+int BvhTriangleMesh::qsplit( int *array, int size, Real pivot, int axis ) {
+
+ int ret_val = 0;
+ for (int i=0; i<size;++i) {
+
+ // Get the bounds of each individual triangle.
+ BBox bounds;
+ compute_bounds( bounds, array[i] );
+
+ // Find the centroid of those bounds.
+ Real centroid = (bounds[0][axis] + bounds[1][axis]) * 0.5;
+
+ if (centroid < pivot) {
+ int tmp = array[i];
+ array[i] = array[ret_val];
+ array[ret_val] = tmp;
+ ++ret_val;
+ }
+ }
+
+ if ((ret_val == 0) || (ret_val == size))
+ ret_val = size / 2;
+
+ return ret_val;
+}
+
+BvhTriangleMesh::Node *BvhTriangleMesh::build_branch( int *array, int size,
int axis ) {
+
+ assert( size != 0 );
+
+ // Check two exit conditions.
+ if (size == 1) {
+ return new Node( array[0] );
+ }
+
+ // Create a new node.
+ Node *new_node = new Node();
+
+ // Compute the bounds of the entire array of triangles.
+ for (int i=0;i<size;++i) {
+ compute_bounds( new_node->bounds, array[i] );
+ }
+
+ if (size == 2) {
+ new_node->child[0] = new Node( array[0] );
+ new_node->child[1] = new Node( array[1] );
+ return new_node;
+ }
+
+ // Find a pivot point.
+ Point pivot((Vector(new_node->bounds[0]) +
Vector(new_node->bounds[1])) * 0.5);
+
+ // Split along the axis.
+ int mid_point = qsplit( array, size, pivot[axis], axis );
+
+ // save the split axis.
+ new_node->split_axis = axis;
+
+ // Create new left and right children.
+ assert( mid_point != 0 );
+ assert( mid_point != size);
+
+ new_node->child[0] = build_branch( array, mid_point, (axis+1)%3 );
+ new_node->child[1] = build_branch( array+mid_point, size-mid_point,
(axis+1)%3 );
+
+ return new_node;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// Public interface.
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+// Construct a BVH from an array of objects.
+BvhTriangleMesh::BvhTriangleMesh( Point *vertex_array_,
+
Vector
*edge_array_,
+
Vector
*normal_array_,
+
IndexedTriangle
*triangle_array_,
+
+
int *array, int
size,
+
+
Material *material
) :
+ PrimitiveCommon( material ),
+ vertex_array( vertex_array_ ),
+ edge_array ( edge_array_ ),
+ normal_array( normal_array_ ),
+ triangle_array( triangle_array_ )
+
+
+{
+
+ // Create a new node.
+ root = new Node();
+
+ // Compute the bounds of the entire array of triangles.
+ for (int i=0;i<size;++i) {
+ compute_bounds( root->bounds, array[i] );
+ }
+
+ // Find a pivot point.
+ Point pivot((Vector(root->bounds[0]) + Vector(root->bounds[1])) *
0.5);
+
+ // Split along the axis.
+ int mid_point = qsplit( array, size, pivot[0], 0 );
+
+ // save the split axis.
+ root->split_axis = 0;
+
+ // Create new left and right children.
+ root->child[0] = build_branch( array, mid_point, 1 );
+ root->child[1] = build_branch( array+mid_point, size-mid_point, 1 );
+}
+
+// Public interface.
+void BvhTriangleMesh::computeBounds(const PreprocessContext& context, BBox&
bbox) const {
+
+ // The root node contains the bounds for the entire model.
+ bbox.extendByBox( root->bounds );
+}
+
+void BvhTriangleMesh::computeNormal(const RenderContext& context, RayPacket&
rays) const {
+
+ rays.computeHitPositions();
+
+ // Iterate over each ray in the packet.
+ for (int i=0;i<rays.getSize();++i) {
+
+ RayPacket::Element &e = rays.get( i );
+
+ // Determine the intersected triangle.
+ Hit &hit = e.hitInfo.scratchpad<Hit>();
+
+ // Interpolate normals across the face.
+ Real ab = 1.0 - (hit.a + hit.b);
+
+ e.normal = (normal_array[ hit.tri.n0 ] * hit.a) +
+ (normal_array[ hit.tri.n1 ] * hit.b) +
+ (normal_array[
hit.tri.n2 ] * ab);
+ }
+
+}
+
+void BvhTriangleMesh::intersect (const RenderContext& context, RayPacket&
rays) const {
+
+ rays.computeInverseDirections();
+
+ // Intersect the ray packet with this mesh.
+ intersect_internal( root, context, rays );
+}
+
+
+
Added: branches/itanium2/Model/Primitives/BvhTriangleMesh.h
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Primitives/BvhTriangleMesh.h Fri Jul 22
16:00:18 2005
@@ -0,0 +1,148 @@
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005
+ Silicon Graphics Inc. Mountain View California.
+
+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef Manta_Model_BvhTriangleMesh__H
+#define Manta_Model_BvhTriangleMesh__H
+
+
+#include <Model/Primitives/PrimitiveCommon.h>
+#include <MantaTypes.h>
+#include <Core/Geometry/PointVector.h>
+#include <Core/Geometry/BBox.h>
+
+namespace Manta {
+
+ // This class implements a triangle mesh with a single material. The
triangle
+ // mesh is represented in indexed form such that verticies and vertex
normals
+ // are shared between faces.
+
+ // The class uses a BVH acceleration structure.
+
+ class BvhTriangleMesh : public PrimitiveCommon {
+ public:
+
///////////////////////////////////////////////////////////////////////////
+ // Triangle structures.
+ struct IndexedTriangle {
+ int v0; // Vertex.
+ int e0, e1; // Edges.
+ int n0, n1, n2; // Vertex Normals.
+ };
+ private:
+ // Hit Record structure.
+ struct Hit {
+ IndexedTriangle tri;
+ Real a, b;
+ };
+
+
///////////////////////////////////////////////////////////////////////////
+ // BVH Structures.
+ struct Node {
+
+ // Internal node members.
+ BBox bounds;
+ Node *child[2]; // Both pointers null if the node is
a leaf.
+ int split_axis;
+
+ // Leaf members.
+ int triangle_index;
+
+ // Constructors.
+ Node() : split_axis( 0 ), triangle_index( -1 ) { };
+ Node( int triangle_index_ );
+ ~Node() { if (child[0]) delete child[0]; if
(child[1]) delete child[1]; };
+
+ // Leaf methods.
+ inline bool isLeaf() const { return (!child[0]) &&
(!child[1]); };
+ };
+
+
///////////////////////////////////////////////////////////////////////////
+ // Data members indexed to.
+ Point *vertex_array;
+ Vector *edge_array;
+ Vector *normal_array;
+
+ // Triangles which are indexed into in the bvh leaves.
+ IndexedTriangle *triangle_array;
+
+
///////////////////////////////////////////////////////////////////////////
+ // Root node of the bvh.
+ Node *root;
+
+
///////////////////////////////////////////////////////////////////////////
+ // Helper methods.
+
+ // This method traverses the bvh.
+ void intersect_leaf( Node *node, const RenderContext&
context, RayPacket& rays) const;
+ void intersect_internal( Node *node, const RenderContext&
context, RayPacket& rays) const;
+
+
///////////////////////////////////////////////////////////////////////////
+ // Serial builder methods.
+ Node *build_branch( int *array, int size, int axis );
+ int qsplit( int *array, int size, Real pivot, int axis );
+
+ inline void compute_bounds( BBox &bounds, int triangle )
const {
+
+ Point &v0 = vertex_array[ triangle_array[ triangle
].v0 ];
+ Vector &e0 = edge_array [ triangle_array[ triangle
].e0 ];
+ Vector &e1 = edge_array [ triangle_array[ triangle
].e1 ];
+
+ bounds.extendByPoint( v0 );
+ bounds.extendByPoint( v0 + e0 );
+ bounds.extendByPoint( v0 + e1 );
+
+ }
+
+ public:
+
+ // A third party, such as the builder, is responsible for
storing the mesh data.
+ // Several BvhhTriangleMesh instances may share a single set
of vertex, edge,
+ // and normal arrays. Each instance would be constructed
using a different
+ // int array of triangle indices.
+
+ BvhTriangleMesh( // Mesh data (possibly shared) to index into.
+ Point *vertex_array_,
+
Vector *edge_array_,
+
Vector *normal_array_,
+
IndexedTriangle *triangle_array_,
+
+
// Array of indicies in the triangle array for this bvh.
+
int *array, int size,
+
Material *material = 0 );
+
+ ~BvhTriangleMesh() { delete root; }
+
+ // Public interface.
+ void computeBounds(const PreprocessContext& context, BBox& bbox) const;
+ void computeNormal(const RenderContext& context, RayPacket&
rays) const;
+ void intersect (const RenderContext& context, RayPacket& rays) const;
+ };
+
+};
+
+#endif
+
\ No newline at end of file
Modified: branches/itanium2/Model/Primitives/CMakeLists.txt
==============================================================================
--- branches/itanium2/Model/Primitives/CMakeLists.txt (original)
+++ branches/itanium2/Model/Primitives/CMakeLists.txt Fri Jul 22 16:00:18
2005
@@ -1,39 +1,32 @@
SET (Manta_Primitives_SRCS
+ Primitives/Parallelogram.h
Primitives/Parallelogram.cc
+ Primitives/PrimitiveCommon.h
Primitives/PrimitiveCommon.cc
+ Primitives/Sphere.h
Primitives/Sphere.cc
+ Primitives/SuperEllipsoid.h
Primitives/SuperEllipsoid.cc
+ Primitives/Cube.h
Primitives/Cube.cc
+ Primitives/Cone.h
Primitives/Cone.cc
+ Primitives/Triangle.h
Primitives/Triangle.cc
+ Primitives/HeavyTriangle.h
Primitives/HeavyTriangle.cc
+ Primitives/TexTriangle.h
Primitives/TexTriangle.cc
+ Primitives/VertexColoredTriangle.h
Primitives/VertexColoredTriangle.cc
+ Primitives/Disk.h
Primitives/Disk.cc
+ Primitives/Hemisphere.h
Primitives/Hemisphere.cc
+ Primitives/Heightfield.h
Primitives/Heightfield.cc
+ Primitives/BvhTriangleMesh.h
+ Primitives/BvhTriangleMesh.cc
)
-SET(INCLUDE_DOT_H TRUE)
-
-# Should header files be included on the build line?
-# (for example if the project is built with xcode)
-IF(INCLUDE_DOT_H)
- SET (Manta_Primitives_SRCS
- ${Manta_Primitives_SRCS}
- Primitives/Parallelogram.h
- Primitives/PrimitiveCommon.h
- Primitives/Sphere.h
- Primitives/SuperEllipsoid.h
- Primitives/Cube.h
- Primitives/Cone.h
- Primitives/Triangle.h
- Primitives/HeavyTriangle.h
- Primitives/TexTriangle.h
- Primitives/VertexColoredTriangle.h
- Primitives/Disk.h
- Primitives/Hemisphere.h
- Primitives/Heightfield.h
- )
-ENDIF(INCLUDE_DOT_H)
Modified: branches/itanium2/Model/Primitives/PrimitiveCommon.h
==============================================================================
--- branches/itanium2/Model/Primitives/PrimitiveCommon.h (original)
+++ branches/itanium2/Model/Primitives/PrimitiveCommon.h Fri Jul 22
16:00:18 2005
@@ -4,7 +4,7 @@
#include <Interface/Primitive.h>
-namespace Manta{
+namespace Manta {
class Material;
class PrimitiveCommon : public Primitive {
public:
@@ -12,6 +12,8 @@
PrimitiveCommon() { }; // Empty default constructor (used
for an array of some primitive)
virtual ~PrimitiveCommon();
+ // Note that this preprocess method sets up the activeLights
for the associated
+ // material (not sure what happens for shared materials)
virtual void preprocess(const PreprocessContext&);
virtual void setTexCoordMapper(const TexCoordMapper* new_tex);
protected:
Modified: branches/itanium2/Model/Primitives/Triangle.cc
==============================================================================
--- branches/itanium2/Model/Primitives/Triangle.cc (original)
+++ branches/itanium2/Model/Primitives/Triangle.cc Fri Jul 22 16:00:18
2005
@@ -5,6 +5,8 @@
#include <iostream>
#include <sgi_stl_warnings_on.h>
+#include <Model/Intersections/TriangleEdge.h>
+
using namespace Manta;
using namespace std;
@@ -39,7 +41,8 @@
RayPacket::Element& e = rays.get(i);
const Vector& dir(e.ray.direction());
Vector o(p1 - e.ray.origin());
-
+
+ #if 0
double det=Dot(_n,dir);
if(det>1.e-9 || det < -1.e-9) {
double idet = 1./det;
@@ -50,14 +53,22 @@
double B = Dot(DX, _e1)*idet;
if(B>0.0 && A+B<1.0) {
double t=Dot(_n, o)*idet;
- if (e.hitInfo.hit(t, material, this, tex)){
+ #endif
+
+ Real t, A, B;
+
+ bool h = Intersection::intersectTriangleEdge( t, A, B, e.ray,
_e1, _e2, p1 );
+
+ if (h && e.hitInfo.hit(t, material, this, tex)){
TriangleHit& th = e.hitInfo.scratchpad<TriangleHit>();
th.a = A;
th.b = B;
}
+#if 0
}
}
}
+#endif
}
}
Modified: branches/itanium2/Model/Readers/CMakeLists.txt
==============================================================================
--- branches/itanium2/Model/Readers/CMakeLists.txt (original)
+++ branches/itanium2/Model/Readers/CMakeLists.txt Fri Jul 22 16:00:18
2005
@@ -1,7 +1,5 @@
SET (Manta_Readers_SRCS
- Readers/PlyReader.cc
- Readers/rply/rply.c
Readers/glm/glm.h
Readers/glm/glm.cc)
Modified: branches/itanium2/Model/Readers/glm/glm.h
==============================================================================
--- branches/itanium2/Model/Readers/glm/glm.h (original)
+++ branches/itanium2/Model/Readers/glm/glm.h Fri Jul 22 16:00:18 2005
@@ -52,7 +52,7 @@
unsigned int vindices[3]; /* array of triangle
vertex indices */
unsigned int nindices[3]; /* array of triangle
normal indices */
unsigned int tindices[3]; /* array of triangle
texcoord indices*/
- unsigned int findex; /* index of triangle
facet normal */
+ unsigned int findex; /* index of
triangle facet normal */
} GLMtriangle;
/* GLMgroup: Structure that defines a group in a model.
Modified: branches/itanium2/Readers/CMakeLists.txt
==============================================================================
--- branches/itanium2/Readers/CMakeLists.txt (original)
+++ branches/itanium2/Readers/CMakeLists.txt Fri Jul 22 16:00:18 2005
@@ -2,12 +2,11 @@
SET (READERS_DOUBLE_EAGLE 0 CACHE BOOL "Include Double Eagle Tanker
Conversion Program")
IF (READERS_DOUBLE_EAGLE)
ADD_EXECUTABLE(vn2v3c1 DoubleEagle/vn2v3c1.cc)
- TARGET_LINK_LIBRARIES(vn2v3c1 SCIRun_Core Manta_Core)
-
- TARGET_LINK_LIBRARIES(vn2v3c1 ${CMAKE_THREAD_LIBS_INIT}
- ${OPENGL_LIBRARIES}
- ${X11_LIBRARIES}
- -lm)
+ TARGET_LINK_LIBRARIES(vn2v3c1 SCIRun_Core Manta_Core Manta_Model)
+ TARGET_LINK_LIBRARIES(vn2v3c1 ${CMAKE_THREAD_LIBS_INIT}
+ ${OPENGL_LIBRARIES}
+ ${X11_LIBRARIES}
+ -lm)
ENDIF(READERS_DOUBLE_EAGLE)
Modified: branches/itanium2/Readers/DoubleEagle/vn2v3c1.cc
==============================================================================
--- branches/itanium2/Readers/DoubleEagle/vn2v3c1.cc (original)
+++ branches/itanium2/Readers/DoubleEagle/vn2v3c1.cc Fri Jul 22 16:00:18
2005
@@ -12,17 +12,28 @@
#include <Core/Geometry/PointVector.h>
#include <Core/Geometry/BBox.h>
+#include <Model/Readers/glm/glm.h>
+
using namespace std;
using namespace Manta;
+using namespace Glm;
// This program loads data files from the Double Eagle tanker and produces
// one v3c1 file with per face color information.
// The program takes the input path (and recursively examines all
subdirectories)
// as well as the output file name.
-void search_directory ( const char *directory_name, unsigned char
current_color[3] );
-void process_data_file( const char *file_name, unsigned char
current_color[3] );
+
+// vn3 file format.
+void search_directory( const char *directory_name, unsigned char
current_color[3] );
+void process_vn3_file( const char *file_name, unsigned char
current_color[3] );
+
+// Obj file format.
+void process_obj_file( const char *file_name );
+
+// v3c1 format.
void v3c1_info( const char *file_name );
+void v3c1_clip( const char *file_name, const Point &plane_point, const
Vector &plane_normal );
FILE *out_file = 0;
int total_faces = 0;
@@ -56,39 +67,61 @@
color[2] = 0.003921f * (float)new_color[2];
}
+
+ float *vertex( int i ) {
+ switch (i) {
+ case 0:
+ return vertex0;
+ case 1:
+ return vertex1;
+ default:
+ return vertex2;
+ };
+ }
};
vector<nv3_face> in_buffer;
vector<v3c1_face> out_buffer;
-enum CommandType { NONE, CONVERT, INFO };
+enum CommandType { NONE, CONVERT_VN, CONVERT_OBJ, INFO, CUT };
int main( int argc, char **argv ) {
+ // Input file names.
int file_list_begin = 0;
int file_list_end = 0;
+
+ // Output file name.
char *output_file_name = 0;
+ // Cutting plane.
+ Point plane_point;
+ Vector plane_normal;
+
CommandType command = NONE;
// Check the command line args.
for (int i=1;i<argc;++i) {
string arg = argv[i];
- if (arg == "-path") {
- command = CONVERT;
-
+ if (arg == "-vn3") {
+ command = CONVERT_VN;
+ }
+ else if (arg == "-obj") {
+ command = CONVERT_OBJ;
+ }
+ else if (arg == "-out") {
+ output_file_name = argv[++i];
+ }
+ else if (arg == "-in") {
file_list_begin = ++i;
file_list_end = file_list_begin+1;
while ((file_list_end < argc) &&
(argv[file_list_end][0] != '-')) {
- ++file_list_end;
+ ++file_list_end;
}
}
- else if (arg == "-file") {
- output_file_name = argv[++i];
- }
else if (arg == "-info") {
command = INFO;
@@ -99,21 +132,33 @@
++file_list_end;
}
}
+ else if (arg == "-clip") {
+ command = CUT;
+
+ plane_point[0] = atof( argv[++i] );
+ plane_point[1] = atof( argv[++i] );
+ plane_point[2] = atof( argv[++i] );
+
+ plane_normal[0] = atof( argv[++i] );
+ plane_normal[1] = atof( argv[++i] );
+ plane_normal[2] = atof( argv[++i] );
+ }
}
// Check that both were found.
if ((command == NONE) || (file_list_begin == 0)) {
- printf( "Usage: v2v3c1 -path <tanker path> -file
<outfile.v3c1>\n"
- " v2v3v1 -info <infile.v3c1 ...> -- Computes
bounds and number of triangles." );
+ printf( "Usage: v2v3c1 -vn3 -in <tanker paths...> -out
<outfile.v3c1>\n"
+ " v2v3c1 -obj -in
<file1.obj ...> [-out <outfile.v3c1>]\n -- Outfile optional uses group names
otherwise."
+ " v2v3c1 -info <infile.v3c1 ...> -- Computes
bounds and number of triangles.\n"
+ " v2v3c1 -clip <px>
<py> <pz> <nx> <ny> <nz> -- Apply a clipping plane to the input files. \n");
return 1;
}
-
unsigned char default_color[3] = { 179, 179, 179 };
// Switch on the command.
switch (command) {
- case CONVERT:
+ case CONVERT_VN:
// Open the output file.
if ((out_file = fopen( output_file_name, "w" )) == 0) {
@@ -131,7 +176,30 @@
// Output the bounds.
std::cout << "Bounds: " << bounds[0] << " " << bounds[1] <<
std::endl;
-
+ break;
+ case CONVERT_OBJ:
+
+ // Check to see if more then one output file should be used.
+ if (output_file_name) {
+ // Open the output file.
+ if ((out_file = fopen( output_file_name, "w" )) == 0)
{
+ perror( "Could not open output file." );
+ return 1;
+ }
+ }
+
+ for (int i=file_list_begin;i<file_list_end;++i) {
+ process_obj_file( argv[i] );
+ }
+
+ // Close the output file.
+ if (out_file) {
+ fclose( out_file );
+ }
+
+ // Output the bounds.
+ std::cout << "Bounds: " << bounds[0] << " " << bounds[1] <<
std::endl;
+
break;
case INFO:
// Output info for each file.
@@ -142,6 +210,21 @@
// Output the bounds.
std::cout << "All: faces: " << total_faces << " "<<
bounds[0] << " " << bounds[1] << std::endl;
break;
+ case CUT:
+ // Open the output file.
+ if ((out_file = fopen( output_file_name, "w" )) == 0) {
+ perror( "Could not open output file." );
+ return 1;
+ }
+
+ for (int i=file_list_begin;i<file_list_end;++i) {
+ v3c1_clip( argv[i], plane_point, plane_normal );
+ }
+
+ std::cout << "All: faces: " << total_faces << " "<<
bounds[0] << " " << bounds[1] << std::endl;
+
+ fclose(out_file);
+ break;
};
}
@@ -174,7 +257,7 @@
sprintf( next_file, "%s/%s", directory_name,
entry->d_name );
// process the .bin file.
- process_data_file( next_file, current_color );
+ process_vn3_file( next_file, current_color );
}
else {
// Check to see if the name is a directory.
@@ -209,7 +292,7 @@
closedir( dir );
}
-void process_data_file( const char *file_name, unsigned char
current_color[3] ) {
+void process_vn3_file( const char *file_name, unsigned char current_color[3]
) {
// Open the data file.
FILE *in_file = fopen( file_name, "r" );
@@ -273,6 +356,85 @@
total_faces += file_faces;
}
+void process_obj_file( const char *file_name ) {
+
+ // Load in the file using glm.
+ GLMmodel *model = glmReadOBJ( file_name );
+ if (model == 0) {
+ std::cout << "Error cannot read model from file." <<
std::endl;
+ return;
+ }
+
+ // Flip the face winding.
+ // glmReverseWinding( model );
+
+ FILE *out;
+ int group_num = 0;
+ v3c1_face out_face;
+
+ // Iterate over the groups.
+ GLMgroup *group = model->groups;
+ while (group) {
+
+ // Check to see what output file to use.
+ if (out_file == 0) {
+ // Use an output file per group.
+ char file_name[128];
+ sprintf( file_name, "%d%s.v3c1", group_num,
group->name );
+
+ out = fopen( file_name, "w" );
+ if (out == 0) {
+ printf( "Error could not open output file:
%s\n", file_name );
+ return;
+ }
+
+ printf( "Group: %d File: %s ", group_num, file_name );
+ }
+ else {
+ // Use a single output file.
+ out = out_file;
+
+ printf( "Group: %d\n", group_num );
+ }
+
+ // Output all of the triangles in the group.
+ for (int i=0;i<group->numtriangles;++i) {
+ int tri_index = group->triangles[i];
+
+ // Copy out three vertices.
+ for (int v=0;v<3;++v) {
+ int vertex_index =
model->triangles[tri_index].vindices[v];
+ out_face.vertex(v)[0] =
model->vertices[(3*vertex_index)];
+ out_face.vertex(v)[1] =
model->vertices[(3*vertex_index)+1];
+ out_face.vertex(v)[2] =
model->vertices[(3*vertex_index)+2];
+
+ // Bound the vertex.
+ }
+
+ // Copy out the color.
+ int mtl_index = group->material;
+ for (int c=0; c<3;++c) {
+ out_face.color[c] =
model->materials[mtl_index].diffuse[c];
+ }
+
+ // Output.
+ fwrite( &out_face, sizeof( v3c1_face ), 1, out );
+ }
+
+ // Close the file if we are using one per group.
+ if (out_file == 0) {
+ fclose( out );
+ }
+
+ printf( "Faces: %d\n", group->numtriangles );
+ total_faces += group->numtriangles;
+
+ // Proceed to next group.
+ ++group_num;
+ group = group->next;
+ }
+}
+
void v3c1_info( const char *file_name ) {
// Open the data file.
@@ -292,8 +454,7 @@
// Output number of faces.
if ((file_size % sizeof(v3c1_face)) != 0) {
- printf( "%s size %d is not a multiple of sizeof(v3c1_face)
(%d) ",
- file_name, (int)file_size,
(int)sizeof(v3c1_face) );
+ printf( "%s size %d is not a multiple of sizeof(v3c1_face)
(%d) ", file_name, (int)file_size, (int)sizeof(v3c1_face) );
}
else {
printf( "%s faces: %d ", file_name, (int)file_faces );
@@ -326,4 +487,72 @@
total_faces += file_faces;
};
+void v3c1_clip( const char *file_name, const Point &plane_point, const
Vector &plane_normal ) {
+
+ // Open the data file.
+ FILE *in_file = fopen( file_name, "r" );
+ if (!in_file) {
+ perror( "Could not open data file." );
+ return;
+ }
+
+ // Determine the file size.
+ fseek( in_file, 0, SEEK_END );
+ long file_size = ftell( in_file );
+ fseek( in_file, 0, SEEK_SET );
+
+ // Determine the total number of faces in this file.
+ long file_faces = file_size / (sizeof(v3c1_face));
+
+ // Output number of faces.
+ if ((file_size % sizeof(v3c1_face)) != 0) {
+ printf( "%s size %d is not a multiple of sizeof(v3c1_face)
(%d)\n",
+ file_name, (int)file_size,
(int)sizeof(v3c1_face) );
+ }
+ else {
+ printf( "%s faces: %d\n", file_name, (int)file_faces );
+ }
+
+ // Read in the data.
+ out_buffer.resize( file_faces );
+ fread( &out_buffer[0], sizeof(v3c1_face), file_faces, in_file );
+
+ fclose( in_file );
+
+ // Copy the faces into the output buffer.
+ for (int i=0;i<file_faces;++i) {
+
+ bool not_clipped = true;
+ // Compare the face to the cutting plane.
+ for (int f=0;f<3;++f) {
+
+ // Check to see if this vertex is on the back side of
the plane.
+ Point vertex( out_buffer[i].vertex(f)[0],
+ out_buffer[i].vertex(f)[1],
+
out_buffer[i].vertex(f)[2] );
+
+ // Determine if the triangle should be added.
+ not_clipped = not_clipped &&
(Dot((vertex-plane_point),plane_normal) < 0.0);
+
+ }
+
+ // Output the face if it is not clipped.
+ if (not_clipped) {
+
+ // Compare the face to the cutting plane.
+ for (int f=0;f<3;++f) {
+
+ // Check to see if this vertex is on the back
side of the plane.
+ Point vertex( out_buffer[i].vertex(f)[0],
+
out_buffer[i].vertex(f)[1],
+
out_buffer[i].vertex(f)[2] );
+
+ bounds.extendByPoint( vertex );
+ }
+
+ ++total_faces;
+ fwrite( &out_buffer[i], sizeof( v3c1_face ), 1,
out_file );
+ }
+ }
+}
Modified: branches/itanium2/fox/fox_manta.cc
==============================================================================
--- branches/itanium2/fox/fox_manta.cc (original)
+++ branches/itanium2/fox/fox_manta.cc Fri Jul 22 16:00:18 2005
@@ -15,7 +15,7 @@
#include <fox/FMantaQuakeNav.h>
#include <fox/FMantaTrackballNav.h>
-#include <histx/SingleSamplerCounter.h>
+// #include <histx/SingleSamplerCounter.h>
#include <string>
#include <stdlib.h>
Modified: branches/itanium2/scenes/objviewer.cc
==============================================================================
--- branches/itanium2/scenes/objviewer.cc (original)
+++ branches/itanium2/scenes/objviewer.cc Fri Jul 22 16:00:18 2005
@@ -14,9 +14,10 @@
#include <Model/Primitives/Triangle.h>
#include <Model/Primitives/Parallelogram.h>
#include <Model/Primitives/Cube.h>
+#include <Model/Primitives/BvhTriangleMesh.h>
#include <Model/Materials/Lambertian.h>
#include <Model/Materials/Phong.h>
-// #include <Model/Materials/Dielectric.h>
+#include <Model/Materials/Dielectric.h>
#include <Model/Materials/NormalMaterial.h>
#include <Model/Groups/Group.h>
#include <Model/Groups/RealisticBvh.h>
@@ -37,6 +38,12 @@
using namespace Manta;
using namespace SCIRun;
using namespace Glm;
+
+Object *create_single_bvh( GLMmodel *model );
+Object *create_bvh_meshs ( GLMmodel *model );
+
+BBox bounds;
+
///////////////////////////////////////////////////////////////////////////
// This function loads a specified .obj file into a runtime acceleration
@@ -45,6 +52,7 @@
Scene* make_scene(const ReadContext& context, const vector<string>& args) {
string file_name;
+ bool use_single_bvh = false;
// Check the arguments.
for (int i=0;i<args.size();++i) {
@@ -54,6 +62,9 @@
if (!getStringArg(i, args, file_name))
throw IllegalArgument("objviewer -file
<filename>", i, args);
}
+ if (args[i] == "-single") {
+ use_single_bvh = true;
+ }
}
// Load in the file using glm.
@@ -65,17 +76,61 @@
// Flip the face winding.
glmReverseWinding( model );
- // glmScale( model, 10.0 );
+ Object *bvh = 0;
+
+ if (use_single_bvh)
+ bvh = create_single_bvh( model );
+ else
+ bvh = create_bvh_meshs( model );
+
/////////////////////////////////////////////////////////////////////////////
- // Allocate storage for primitives and materials.
- int total_triangles = model->numtriangles;
- Triangle *triangle_array = new Triangle[ total_triangles ];
- Material **material_array = new Material *[ model->nummaterials ];
+ // Create the scene.
+ Scene *scene = new Scene();
- int tri = 0;
- int mtl = 0;
+ // Add a head light.
+ LightSet *lights = new LightSet();
+ lights->add( new HeadLight( 2.0, Color(RGB(1.0,1.0,1.0)) ));
+ lights->setAmbientLight( new ConstantAmbient( Color(RGB(0.2,0.2,0.2)
) ));
+ scene->setLights( lights );
+
+ Material* red=new Lambertian(Color(RGBColor(.6,0,0)));
+ Material* yellow=new Lambertian(Color(RGBColor(.6,.6,0)));
+
+
+ // Add a checkerboard floor.
+ Material* plane_matl = new Phong(new
CheckerTexture<Color>(Color(RGBColor(.6,.6,0)),
+
Color(RGBColor(0,0,0)),
+
Vector(1,0,0),
+
Vector(0,1,0)),
+
new
Constant<Color>(Color(RGBColor(.6,.6,.6))),
+
32,
+
new
CheckerTexture<double>(0.2, 0.5,
+
Vector(1,0,0),
+
Vector(0,1,0)));
+
+ Parallelogram* floor = new Parallelogram(yellow,
Point(-20,-20,bounds[0][2]),
+
Vector(40,0,0), Vector(0,40,0));
+ Group *manta_group = new Group();
+ manta_group->add( floor );
+ // manta_group->add( new Cube( red, bounds[0], bounds[1] ) );
+ manta_group->add( bvh );
+ // Add the bvh to the scene.
+ scene->setObject( manta_group );
+
+ // Background.
+ scene->setBackground( new ConstantBackground( Color(RGB(0.8, 0.8,
0.8)) ) );
+
+ return scene;
+}
+
+Material **material_array = 0;
+
+void create_materials( GLMmodel *model ) {
+
+ material_array = new Material *[ model->nummaterials ];
+
// Read in the materials.
for (int i=0;i<model->nummaterials;++i) {
@@ -91,13 +146,34 @@
// Note that the first material added by blender is
always an
// unused default material..
- // material_array[i-1] = new Dielectric( diffuse,
Color(RGB(0.6,0.6,0.8)), 128, 1.2, 1.2 );
+ // material_array[i-1] = new Dielectric( diffuse,
+ //
Color(RGB(0.6,0.6,0.8)),
+ //
Color(RGB(log(c0),log(c1),log(c2))),
+ //
128, 1.2, 1.0 );
// }
// else {
material_array[i-1] = new Lambertian( diffuse );
- // material_array[i-1] = new Phong( diffuse,
diffuse*1.1, 128, 0.5 );
+ // material_array[i-1] = new Phong( diffuse,
diffuse*1.1, 128 );
// }
}
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Create a single bvh to contain the mesh.
+Object *create_single_bvh( GLMmodel *model ) {
+
+ Triangle *triangle_array;
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Allocate storage for primitives and materials.
+ int total_triangles = model->numtriangles;
+ triangle_array = new Triangle[ total_triangles ];
+
+ create_materials( model );
+
+ int tri = 0;
+ int mtl = 0;
// Lambertian *default_material = new Lambertian( Color(RGB( 1.0,
0.0, 0.0 ) ) );
Material *default_material = new NormalMaterial();
@@ -105,7 +181,7 @@
// Read in the groups.
GLMgroup *group = model->groups;
while (group != 0) {
-
+
// Determine the material for this group.
Material *material;
if ((group->material-1) < model->nummaterials) {
@@ -114,7 +190,7 @@
else {
material = default_material;
}
-
+
// Copy out triangles.
int total_faces = group->numtriangles;
for (int i=0;i<total_faces;++i) {
@@ -123,6 +199,7 @@
for (int v=0;v<3;++v) {
int index = model->triangles[
group->triangles[i] ].vindices[v];
float *f = model->vertices+(index*3);
+
// Copy out the vertex.
vertex[v][0] = f[0];
vertex[v][1] = f[1];
@@ -133,7 +210,7 @@
triangle_array[tri++] =
Triangle( material, vertex[0], vertex[1],
vertex[2] );
}
-
+
// Move to the next group.
group = group->next;
++mtl;
@@ -157,60 +234,240 @@
double time_end = Time::currentSeconds();
- std::cerr << "Bvh creation time: " << (time_end - time_begin)
- << " seconds." << std::endl;
-
+ std::cerr << "Bvh creation time: " << (time_end - time_begin) << "
seconds." << std::endl;
/////////////////////////////////////////////////////////////////////////////
// Check the size of bounding boxes.
PreprocessContext p_context;
-
- BBox bounds;
bvh->computeBounds( p_context, bounds );
-
- std::cerr << "Bvh: Bounding box " << bounds[0] << " : " << bounds[1]
<< std::endl;
-
+
+ std::cerr << "Bvh: Bounding box " << bounds[0] << " : " << bounds[1]
<< std::endl;
+
+ return bvh;
+}
+
+Object *create_many_bvh( GLMmodel *model ) {
+
+ Triangle *triangle_array;
+
/////////////////////////////////////////////////////////////////////////////
- // Create the scene.
- Scene *scene = new Scene();
+ // Allocate storage for primitives and materials.
+ int total_triangles = model->numtriangles;
+ triangle_array = new Triangle[ total_triangles ];
- // Add a head light.
- LightSet *lights = new LightSet();
- lights->add( new HeadLight( 2.0, Color(RGB(1.0,1.0,1.0)) ));
- lights->setAmbientLight( new ConstantAmbient( Color(RGB(0.2,0.2,0.2)
) ));
- scene->setLights( lights );
+ create_materials( model );
- Material* red=new Lambertian(Color(RGBColor(.6,0,0)));
- Material* yellow=new Lambertian(Color(RGBColor(.6,.6,0)));
+ int tri = 0;
+ int mtl = 0;
+ // Lambertian *default_material = new Lambertian( Color(RGB( 1.0,
0.0, 0.0 ) ) );
+ Material *default_material = new NormalMaterial();
- // Add a checkerboard floor.
- Material* plane_matl = new Phong(new
CheckerTexture<Color>(Color(RGBColor(.6,.6,0)),
-
Color(RGBColor(0,0,0)),
-
Vector(1,0,0),
-
Vector(0,1,0)),
-
new
Constant<Color>(Color(RGBColor(.6,.6,.6))),
-
32,
-
new
CheckerTexture<double>(0.2, 0.5,
-
Vector(1,0,0),
-
Vector(0,1,0)));
+ // Read in the groups.
+ GLMgroup *group = model->groups;
+ while (group != 0) {
+
+ // Determine the material for this group.
+ Material *material;
+ if ((group->material-1) < model->nummaterials) {
+ material = material_array[group->material-1];
+ }
+ else {
+ material = default_material;
+ }
+
+ // Copy out triangles.
+ int total_faces = group->numtriangles;
+ for (int i=0;i<total_faces;++i) {
+
+ Point vertex[3];
+ for (int v=0;v<3;++v) {
+ int index = model->triangles[
group->triangles[i] ].vindices[v];
+ float *f = model->vertices+(index*3);
+
+ // Copy out the vertex.
+ vertex[v][0] = f[0];
+ vertex[v][1] = f[1];
+ vertex[v][2] = f[2];
+ }
+
+ // Create a new triangle.
+ triangle_array[tri++] = Triangle( material,
vertex[0], vertex[1], vertex[2] );
+ }
+
+ // Move to the next group.
+ group = group->next;
+ ++mtl;
+ }
- Parallelogram* floor = new Parallelogram(plane_matl,
Point(-20,-20,bounds[0][2]),
-
Vector(40,0,0), Vector(0,40,0));
- Group *manta_group = new Group();
- manta_group->add( floor );
- // manta_group->add( new Cube( red, bounds[0], bounds[1] ) );
- manta_group->add( bvh );
+
/////////////////////////////////////////////////////////////////////////////
+ // Create an acceleration structure.
- // Add the bvh to the scene.
- scene->setObject( manta_group );
+ // Make an array of pointers to triangles for input to the bvh.
+ Object **triangle_ptr_array = new Object *[ total_triangles ];
+ for (int i=0;i<total_triangles;++i) {
+ triangle_ptr_array[i] = triangle_array+i;
+ }
- // Background.
- scene->setBackground( new ConstantBackground( Color(RGB(0.8, 0.8,
0.8)) ) );
+ std::cerr << "Total triangles added: " << tri << std::endl;
- return scene;
+ double time_begin = Time::currentSeconds();
+
+ // Construct the bvh.
+ RealisticBvh *bvh = new RealisticBvh( triangle_ptr_array,
total_triangles );
+
+ double time_end = Time::currentSeconds();
+
+ std::cerr << "Bvh creation time: " << (time_end - time_begin) << "
seconds." << std::endl;
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Check the size of bounding boxes.
+ PreprocessContext p_context;
+ bvh->computeBounds( p_context, bounds );
+
+ std::cerr << "Bvh: Bounding box " << bounds[0] << " : " << bounds[1]
<< std::endl;
+
+ return bvh;
}
+Object *create_bvh_meshs( GLMmodel *model ) {
+
+ Point *vertex_array;
+ Vector *edge_array;
+ Vector *normal_array;
+
+ typedef BvhTriangleMesh::IndexedTriangle IndexedTriangle;
+ IndexedTriangle *triangle_array;
+
+ create_materials( model );
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Determine the total number of faces and normals.
+ int total_triangles = model->numtriangles;
+ int total_vnormals = model->numnormals;
+
+ // Allocate storage for vertex and edges.
+ vertex_array = new Point[ total_triangles ];
+ edge_array = new Vector[ total_triangles*2 ];
+
+ // Allocate storage for normals.
+ normal_array = new Vector[ total_vnormals ];
+
+ // Allocate storage for triangles.
+ triangle_array = new IndexedTriangle[ total_triangles ];
+
/////////////////////////////////////////////////////////////////////////////
+
+ // Keep track of iterators over the arrays.
+ int vertex = 0;
+ int edge = 0;
+ int normal = 0;
+ int triangle = 0;
+
+ // Copy all of the vertex normals out.
+ for (normal=0;normal<total_vnormals;++normal) {
+ normal_array[normal] = Vector( model->normals[1+(normal*3)],
+ model->normals[1+(normal*3)+1],
+
model->normals[1+(normal*3)+2] );
+ }
+
+ // Copy all of the triangles out.
+ for (triangle=0;triangle<total_triangles;++triangle) {
+
+ // Determine the three vertices of the triangle.
+ Point p[3];
+ for (int v=0;v<3;++v) {
+ int index = model->triangles[ triangle
].vindices[v];
+ float *f = model->vertices+(index*3);
+
+ p[v][0] = f[0];
+ p[v][1] = f[1];
+ p[v][2] = f[2];
+ }
+
+ // Copy the v0 vertex.
+ triangle_array[triangle].v0 = vertex;
+ vertex_array[vertex++] = p[0];
+
+ // Compute the edges of the triangle.
+ triangle_array[triangle].e0 = edge;
+ edge_array[edge++] = (p[1] - p[0]);
+
+ triangle_array[triangle].e1 = edge;
+ edge_array[edge++] = (p[2] - p[0]);
+
+ // Copy the vertex normal indices.
+ triangle_array[triangle].n0 = model->triangles[ triangle
].nindices[0]-1;
+ triangle_array[triangle].n1 = model->triangles[ triangle
].nindices[1]-1;
+ triangle_array[triangle].n2 = model->triangles[ triangle
].nindices[2]-1;
+ }
+
+
/////////////////////////////////////////////////////////////////////////////
+
+ // Allocate input array for the top level bvh.
+ Object **object_array = new Object *[ model->numgroups ];
+ int object = 0;
+
+ Material *default_material = new NormalMaterial();
+ PreprocessContext context;
+
+ // Create a bvh for each group.
+ GLMgroup *group = model->groups;
+ while (group != 0) {
+
+ if (group->numtriangles > 0) {
+
+ // Determine the material for this group.
+ Material *material;
+ if ((group->material-1) < model->nummaterials) {
+ material = material_array[group->material-1];
+ }
+ else {
+ material = default_material;
+ }
+
+ // Create an input array for the mesh.
+ int *input_array = new int[ group->numtriangles ];
+
+ for (int i=0;i<group->numtriangles;++i) {
+ input_array[i] = group->triangles[i];
+ }
+
+ // Construct a bvh.
+ object_array[object] = new BvhTriangleMesh(
vertex_array,
+
edge_array,
+
normal_array,
+
triangle_array,
+
+
input_array,
(int)group->numtriangles,
+
material );
+
+ delete [] input_array;
+
+ // Mesh bounds.
+ BBox mesh_bounds;
+ object_array[object]->computeBounds( context,
mesh_bounds );
+
+ std::cerr << "Added mesh: bounds: " << mesh_bounds[0]
<< " " << mesh_bounds[1] << std::endl;
+
+ ++object;
+ }
+ // Move to the next group.
+ group = group->next;
+
+ }
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Construct a bvh over the sub meshes.
+ Object *obj;
+ if (object > 1)
+ obj = new RealisticBvh( object_array, object );
+ else
+ obj = object_array[0];
+
+ // Determine the bounds of the scene.
+ obj->computeBounds( context, bounds );
+
+ return obj;
+}
-
\ No newline at end of file
- [MANTA] r437 - in branches/itanium2: Core/Color Model/Groups Model/Intersections Model/Materials Model/Primitives Model/Readers Model/Readers/glm Readers Readers/DoubleEagle fox scenes, abe, 07/22/2005
Archive powered by MHonArc 2.6.16.