Text archives Help
- From: bigler@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r850 - in branches/vertical: Core/Geometry Core/Math Image Interface Model/AmbientLights Model/Cameras Model/Groups Model/Materials Model/MiscObjects Model/Primitives Model/Textures UserInterface
- Date: Thu, 19 Jan 2006 15:16:26 -0700 (MST)
Author: bigler
Date: Thu Jan 19 15:16:23 2006
New Revision: 850
Modified:
branches/vertical/Core/Geometry/PointVector.h
branches/vertical/Core/Math/CatmullRomInterpolator.h
branches/vertical/Image/SimpleImage.h
branches/vertical/Interface/RayPacket.h
branches/vertical/Model/AmbientLights/ConstantAmbient.cc
branches/vertical/Model/Cameras/FisheyeCamera.cc
branches/vertical/Model/Groups/CMakeLists.txt
branches/vertical/Model/Groups/GriddedGroup.cc
branches/vertical/Model/Groups/GriddedGroup.h
branches/vertical/Model/Groups/KDTree.cc
branches/vertical/Model/Groups/KDTree.h
branches/vertical/Model/Groups/TransparentKDTree.cc
branches/vertical/Model/Groups/TransparentKDTree.h
branches/vertical/Model/Materials/AmbientOcclusion.cc
branches/vertical/Model/Materials/AmbientOcclusion.h
branches/vertical/Model/Materials/CMakeLists.txt
branches/vertical/Model/Materials/Dielectric.cc
branches/vertical/Model/MiscObjects/CMakeLists.txt
branches/vertical/Model/MiscObjects/CuttingPlane.cc
branches/vertical/Model/Primitives/Cone.cc
branches/vertical/Model/Primitives/Heightfield.h
branches/vertical/Model/Primitives/Hemisphere.cc
branches/vertical/Model/Primitives/Sphere.cc
branches/vertical/Model/Textures/OakTexture.h
branches/vertical/UserInterface/CameraPathAutomator.cc
branches/vertical/UserInterface/CameraPathAutomator.h
branches/vertical/UserInterface/XWindowUI.cc
Log:
Core/Geometry/PointVector.h
Removed heinous operator& and replaced the functionality with
getDataPtr().
Core/Math/CatmullRomInterpolator.h
More float friendly notation. (i.e. 4 instead of 4.0).
Image/SimpleImage.h
Put namespace designation in front of the function rather than using
namespace in the function.
Interface/RayPacket.h
Added copyScratchpad() function that will do a memcpy of the
scratchpad data for a single element of the RayPacket.
Model/AmbientLights/ConstantAmbient.cc
Removed unneeded include of NotFinished.h.
Model/Cameras/FisheyeCamera.cc
Model/Materials/Dielectric.cc
Model/Primitives/Cone.cc
Model/Primitives/Heightfield.h
Model/Primitives/Hemisphere.cc
Model/Primitives/Sphere.cc
Model/Textures/OakTexture.h
UserInterface/XWindowUI.cc
Include Core/Math/Expon.h to get the Sqrt function.
Other namespace cleanup.
Model/Groups/CMakeLists.txt
Compile GriddedGroup, KDTree, TransparentKDTree, and KDTreeLoader.
Model/Groups/GriddedGroup.cc
Model/Groups/GriddedGroup.h
Updates for vertical RayPackets.
More Real==float friendly notation.
Model/Groups/KDTree.cc
Model/Groups/KDTree.h
Updates for vertical RayPackets.
Removed Mailboxing code.
API to intersectTriangles and intersect_node changed.
Model/Groups/TransparentKDTree.cc
Model/Groups/TransparentKDTree.h
Updates for vertical RayPackets.
API to intersectTrianglesTransparent changed.
_intersect is now intersect_node to match KDTree API.
Model/Materials/AmbientOcclusion.cc
Upates for vertical RayPackets and new shadow algorithm interface.
Major structural changes. Compute the ambient occlusion values
first. Then compute the lambertian shading. After this, multiply the
sum of the ambient occlusion and lambertian values by the diffuse
color.
Model/Materials/AmbientOcclusion.h
Fixed broken API of generateDirections.
inv_num_directions is now a ColorComponent type.
Model/Materials/CMakeLists.txt
Compile AmbientOcclusion.
Model/MiscObjects/CMakeLists.txt
Compile CuttingPlane.
Model/MiscObjects/CuttingPlane.cc
Updates for vertical RayPackets.
UserInterface/CameraPathAutomator.cc
UserInterface/CameraPathAutomator.h
eye and lookat are now Vectors instead of Points to allow it to work
with the CatmullRomInterpolator without weird casting.
Modified: branches/vertical/Core/Geometry/PointVector.h
==============================================================================
--- branches/vertical/Core/Geometry/PointVector.h (original)
+++ branches/vertical/Core/Geometry/PointVector.h Thu Jan 19 15:16:23
2006
@@ -79,8 +79,7 @@
}
T &operator[] ( int i ) {
return data[i];
- }
- const T *operator &() const { return data; }
+ }
#else
%extend {
@@ -89,6 +88,10 @@
}
}
#endif
+ // One might be tempted to add an "operator &" function, but
+ // that could lead to problems when you want an address to the
+ // object rather than a pointer to data.
+ const T* getDataPtr() const { return data; }
VectorT<T, Dim> operator+(const VectorT<T, Dim>& v) const {
VectorT<T, Dim> result;
@@ -249,6 +252,9 @@
private:
T data[Dim];
+
+ // Do not use this function!!!! Use getDataPtr() instead.
+ // const T *operator &() const { return data; }
};
@@ -325,6 +331,10 @@
}
}
#endif
+ // One might be tempted to add an "operator &" function, but
+ // that could lead to problems when you want an address to the
+ // object rather than a pointer to data.
+ const T* getDataPtr() const { return data; }
VectorT<T, Dim> operator-(const PointT<T, Dim>& p) const {
VectorT<T, Dim> result;
@@ -393,6 +403,9 @@
private:
T data[Dim];
+
+ // Do not use this function!!!! Use getDataPtr() instead.
+ // const T *operator &() const { return data; }
};
// Two multiplication by a scalar operators.
Modified: branches/vertical/Core/Math/CatmullRomInterpolator.h
==============================================================================
--- branches/vertical/Core/Math/CatmullRomInterpolator.h (original)
+++ branches/vertical/Core/Math/CatmullRomInterpolator.h Thu Jan 19
15:16:23 2006
@@ -45,12 +45,12 @@
Real t2 = t*t;
Real t3 = t*t2;
- PointType r0 = (P_i * 2.0);
- PointType r1 = (P_im1*-1.0 + P_ip1) * t;
- PointType r2 = (P_im1* 2.0 + P_i*-5.0 + P_ip1* 4.0 -P_ip2) * t2;
- PointType r3 = (P_im1*-1.0 + P_i* 3.0 + P_ip1*-3.0 +P_ip2) * t3;
+ PointType r0 = (P_i * 2);
+ PointType r1 = (P_im1*-1 + P_ip1) * t;
+ PointType r2 = (P_im1* 2 + P_i*-5 + P_ip1* 4 -P_ip2) * t2;
+ PointType r3 = (P_im1*-1 + P_i* 3 + P_ip1*-3 +P_ip2) * t3;
- result = (r0 + r1)*0.5 + (r2 + r3)*0.5;
+ result = (r0 + r1)*(Real)0.5 + (r2 + r3)*(Real)0.5;
}
Modified: branches/vertical/Image/SimpleImage.h
==============================================================================
--- branches/vertical/Image/SimpleImage.h (original)
+++ branches/vertical/Image/SimpleImage.h Thu Jan 19 15:16:23 2006
@@ -70,10 +70,9 @@
Image* SimpleImage<Pixel>::create(const std::vector<std::string>& args,
bool stereo, int xres, int yres)
{
- using namespace SCIRun;
if(args.size() != 0)
- throw IllegalValue<std::string>("Illegal argument to SimpleImage
create",
- args[0]);
+ throw SCIRun::IllegalValue<std::string>
+ ("Illegal argument to SimpleImage create", args[0]);
return new SimpleImage<Pixel>(stereo, xres, yres);
}
Modified: branches/vertical/Interface/RayPacket.h
==============================================================================
--- branches/vertical/Interface/RayPacket.h (original)
+++ branches/vertical/Interface/RayPacket.h Thu Jan 19 15:16:23 2006
@@ -492,6 +492,13 @@
# endif
return *(T*)data->scratchpad_data[which];
}
+ // This will copy the contects of the scratchpad from the incoming
+ // RayPacket.
+ void copyScratchpad(int which, RayPacket& copy, int which_copy) {
+ memcpy( data->scratchpad_data[which],
+ copy.data->scratchpad_data[which_copy],
+ RayPacketData::MaxScratchpadSize);
+ }
private:
RayPacket(const RayPacket&);
Modified: branches/vertical/Model/AmbientLights/ConstantAmbient.cc
==============================================================================
--- branches/vertical/Model/AmbientLights/ConstantAmbient.cc (original)
+++ branches/vertical/Model/AmbientLights/ConstantAmbient.cc Thu Jan 19
15:16:23 2006
@@ -1,7 +1,6 @@
#include <Model/AmbientLights/ConstantAmbient.h>
#include <Interface/RayPacket.h>
-#include <Core/Util/NotFinished.h>
#include <sgi_stl_warnings_off.h>
#include <sstream>
@@ -24,7 +23,7 @@
}
void ConstantAmbient::computeAmbient(const RenderContext&,
- RayPacket& rays,
+ RayPacket& rays,
ColorArray ambient) const
{
for(int i=rays.begin();i<rays.end();i++)
Modified: branches/vertical/Model/Cameras/FisheyeCamera.cc
==============================================================================
--- branches/vertical/Model/Cameras/FisheyeCamera.cc (original)
+++ branches/vertical/Model/Cameras/FisheyeCamera.cc Thu Jan 19 15:16:23
2006
@@ -8,12 +8,16 @@
#include <Core/Geometry/AffineTransform.h>
#include <Core/Math/MiscMath.h>
#include <Core/Math/Trig.h>
+#include <Core/Math/Expon.h>
#include <Core/Util/Assert.h>
+
+#include <sgi_stl_warnings_off.h>
#include <iostream>
+#include <sgi_stl_warnings_on.h>
using namespace Manta;
+using namespace SCIRun;
using namespace std;
-using SCIRun::Clamp;
FisheyeCamera::FisheyeCamera(const vector<string>& args)
{
Modified: branches/vertical/Model/Groups/CMakeLists.txt
==============================================================================
--- branches/vertical/Model/Groups/CMakeLists.txt (original)
+++ branches/vertical/Model/Groups/CMakeLists.txt Thu Jan 19 15:16:23
2006
@@ -2,16 +2,16 @@
SET (Manta_Groups_SRCS
Groups/BVH.h
Groups/BVH.cc
- #Groups/GriddedGroup.h
- #Groups/GriddedGroup.cc
+ Groups/GriddedGroup.h
+ Groups/GriddedGroup.cc
Groups/Group.h
Groups/Group.cc
- #Groups/KDTree.h
- #Groups/KDTree.cc
- #Groups/TransparentKDTree.h
- #Groups/TransparentKDTree.cc
- #Groups/KDTreeLoader.h
- #Groups/KDTreeLoader.cc
+ Groups/KDTree.h
+ Groups/KDTree.cc
+ Groups/TransparentKDTree.h
+ Groups/TransparentKDTree.cc
+ Groups/KDTreeLoader.h
+ Groups/KDTreeLoader.cc
#Groups/FrustumKDTree.h
#Groups/FrustumKDTree.cc
Groups/PsiGammaTable.cc
Modified: branches/vertical/Model/Groups/GriddedGroup.cc
==============================================================================
--- branches/vertical/Model/Groups/GriddedGroup.cc (original)
+++ branches/vertical/Model/Groups/GriddedGroup.cc Thu Jan 19 15:16:23
2006
@@ -26,7 +26,7 @@
for(int i=0; i< argc; i++){
string arg = args[i];
if(arg == "-cellfactor"){
- if(!getDoubleArg(i, args, cellfactor))
+ if(!getArg<Real>(i, args, cellfactor))
throw IllegalArgument("GriddedGroup -cellfactor", i, args);
gotCellfactor = true;
} else {
@@ -75,11 +75,11 @@
max += diag*1.e-5;
diag = max-min;
- double volume = diag.x()*diag.y()*diag.z();
- double vol3 = Cbrt(volume);
+ Real volume = diag.x()*diag.y()*diag.z();
+ Real vol3 = Cbrt(volume);
int numObjects = objs.size();
int target_numcells = static_cast<int>(numObjects*cellfactor);
- double avgside = cbrt(static_cast<double>(target_numcells));
+ Real avgside = cbrt(static_cast<Real>(target_numcells));
int nx = static_cast<int>(diag.x()/vol3 * avgside + 0.8);
int ny = static_cast<int>(diag.y()/vol3 * avgside + 0.8);
int nz = static_cast<int>(diag.z()/vol3 * avgside + 0.8);
@@ -165,29 +165,35 @@
rays.computeInverseDirections();
for(int i=rays.begin(); i<rays.end(); i++) {
+ Point origin(rays.getOrigin(i));
+ Vector direction(rays.getOrigin(i));
+ Vector inv_direction(rays.getInverseDirection(i));
// Step 2
- Vector v1 = (min-rays.getOrigin(i))*rays.getInverseDirection(i);
- Vector v2 = (max-rays.getOrigin(i))*rays.getInverseDirection(i);
+ Vector v1 = (min-origin)*inv_direction;
+ Vector v2 = (max-origin)*inv_direction;
Vector vmin = Min(v1, v2);
Vector vmax = Max(v1, v2);
- double tnear = vmin.maxComponent();
- double tfar = vmax.minComponent();
+ Real tnear = vmin.maxComponent();
+ Real tfar = vmax.minComponent();
if(tnear >= tfar)
return;
- if(tfar < 1.e-6)
+ if(tfar < (Real)1.e-6)
return;
if(tnear < 0)
tnear = 0;
// Step 3
- Point p = e.ray.origin() + tnear * e.ray.direction();
+ Point p = origin + tnear * direction;
Vector L = (p-min)*inv_cellsize;
int Lx = Clamp(static_cast<int>(L.x()), 0, cells.getNx()-1);
int Ly = Clamp(static_cast<int>(L.y()), 0, cells.getNy()-1);
int Lz = Clamp(static_cast<int>(L.z()), 0, cells.getNz()-1);
// Step 4
- Vector sign = diag*e.ray.direction();
+ // This could be made faster with the new RayPacket::signs.
+ // i.e. int dirs[2] = { 1, -1 };
+ // i.e. dix = dirs[rays.getSign(i,0)]; or 1-rays.getSign(0)*2;
+ Vector sign = diag*direction;
int dix = sign.x()>0?1:-1;
int stopx = sign.x()>0?cells.getNx():-1;
int diy = sign.y()>0?1:-1;
@@ -196,34 +202,36 @@
int stopz = sign.z()>0?cells.getNz():-1;
// Step 5
- double dtdx = Abs(cellsize.x()/e.ray.direction().x());
- double dtdy = Abs(cellsize.y()/e.ray.direction().y());
- double dtdz = Abs(cellsize.z()/e.ray.direction().z());
+ Real dtdx = Abs(cellsize.x()*inv_direction.x());
+ Real dtdy = Abs(cellsize.y()*inv_direction.y());
+ Real dtdz = Abs(cellsize.z()*inv_direction.z());
// Step 6
- double far_x;
+ Real far_x;
+ // This could be written as:
+ // far_x = (Lx+1-rays.getSign(i,0))*cellsize.x() + min.x();
if(sign.x()>0)
far_x = (Lx+1)*cellsize.x() + min.x();
else
far_x = Lx*cellsize.x() + min.x();
- double far_y;
+ Real far_y;
if(sign.y()>0)
far_y = (Ly+1)*cellsize.y() + min.y();
else
far_y = Ly*cellsize.y() + min.y();
- double far_z;
+ Real far_z;
if(sign.z()>0)
far_z = (Lz+1)*cellsize.z() + min.z();
else
far_z = Lz*cellsize.z() + min.z();
// Step 7
- double tnext_x = (far_x - e.ray.origin().x())*e.inverseDirection.x();
- double tnext_y = (far_y - e.ray.origin().y())*e.inverseDirection.y();
- double tnext_z = (far_z - e.ray.origin().z())*e.inverseDirection.z();
+ Real tnext_x = (far_x - origin.x())*inv_direction.x();
+ Real tnext_y = (far_y - origin.y())*inv_direction.y();
+ Real tnext_z = (far_z - origin.z())*inv_direction.z();
// Step 8
- while(tnear < e.hitInfo.minT()){
+ while(tnear < rays.getMinT(i)){
int idx = cells.getIndex(Lx, Ly, Lz);
int l = cells[idx];
Modified: branches/vertical/Model/Groups/GriddedGroup.h
==============================================================================
--- branches/vertical/Model/Groups/GriddedGroup.h (original)
+++ branches/vertical/Model/Groups/GriddedGroup.h Thu Jan 19 15:16:23
2006
@@ -134,7 +134,7 @@
GriddedGroup(const GriddedGroup&);
GriddedGroup& operator=(const GriddedGroup&);
- double cellfactor;
+ Real cellfactor;
Point min, max;
Vector diag;
Vector cellsize;
Modified: branches/vertical/Model/Groups/KDTree.cc
==============================================================================
--- branches/vertical/Model/Groups/KDTree.cc (original)
+++ branches/vertical/Model/Groups/KDTree.cc Thu Jan 19 15:16:23 2006
@@ -28,12 +28,8 @@
DEALINGS IN THE SOFTWARE.
*/
-#include <iostream>
-
-
-#include <stdio.h>
-#include "varray.h"
-#include "KDTree.h"
+#include <Model/Groups/KDTree.h>
+#include <Model/Groups/varray.h>
#include <Model/Intersections/AxisAlignedBox.h>
#include <Interface/Context.h>
@@ -43,6 +39,12 @@
#include <SCIRun/Core/Thread/Runnable.h>
#include <SCIRun/Core/Thread/Barrier.h>
+#include <sgi_stl_warnings_off.h>
+#include <iostream>
+#include <sgi_stl_warnings_off.h>
+
+#include <stdio.h>
+
using namespace Manta;
using namespace Manta::Kdtree;
using namespace SCIRun;
@@ -86,66 +88,47 @@
// INTERSECT TRIANGLES INTERSECT TRIANGLES INTERSECT TRIANGLES INTERSECT
TRI
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-int KDTree::intersectTriangles(const Ray* ray,
- unsigned int listBegin, int listSize,
- float maxDist, void *userData,
- const RenderContext& /*context*/,
- RayTriangleMailbox &mailbox ) const
+int KDTree::intersectTriangles(const Pointf& origin, const Vectorf&
direction,
+ unsigned int listBegin, unsigned int listSize,
+ float maxDist,
+ RayTriIntersectUserData& isectData) const
{
- int i;
- RayTriIntersectUserData *ud = (RayTriIntersectUserData*)userData;
float nearest_u, nearest_v;
int nearest_tri = -1;
- Vectorf direction = ray->direction();
- Pointf origin = ray->origin();
-
- // Intersect the ray with all the triangles.
- int listEnd = listBegin+listSize;
+ // Intersect the ray with all the triangles.
+ unsigned int listEnd = listBegin+listSize;
- // if (listSize < 40)
- // ud->duplicate = 4;
-
#pragma swp
- for (i = listBegin; i < listEnd; i++) {
+ for (unsigned int i = listBegin; i < listEnd; ++i) {
int triIdx = triIndices->get(i);
Triangle &tri = tris->get(triIdx);
float t, u, v;
-#if SHOW_DUPLICATES
- //if (!mailbox.only_check( ray, triIdx )) {
- // global_counter++;
- //ud->duplicate++;
- //}
-#endif
-
- // Insert mailbox check here.
- // if (intersectTriangle3Edge( direction, origin, tri.edge1, tri.edge2,
tri[0], t, u, v )) {
- if (mailbox.not_mapped( (RayTriangleMailbox::RayNumber)ray, triIdx )) {
-
-
- if(/*mailbox.not_mapped( ray, triIdx ) &&*/ intersect_triangle3_edge(
&origin[0], &direction[0], &tri[0][0], &t, &u, &v, &tri.edge1, &tri.edge2 )) {
-
- // Check to see if the t value is closer.
- if (t < maxDist) {
- maxDist = t;
- nearest_u = u;
- nearest_v = v;
- nearest_tri = triIdx;
- }
+ if(intersect_triangle3_edge( origin.getDataPtr(), direction.getDataPtr(),
+ &tri[0][0],
+ &t, &u, &v,
+ tri.edge1.getDataPtr(),
+ tri.edge2.getDataPtr() ))
+ {
+ // Check to see if the t value is closer.
+ if (t < maxDist) {
+ maxDist = t;
+ nearest_u = u;
+ nearest_v = v;
+ nearest_tri = triIdx;
+ }
}
- }
-
}
-
+
if (nearest_tri >= 0) {
- ud->rayHit.t = maxDist;
- ud->rayHit.u = nearest_u;
- ud->rayHit.v = nearest_v;
- ud->rayHitTriIndex = nearest_tri;
+ isectData.rayHit.t = maxDist;
+ isectData.rayHit.u = nearest_u;
+ isectData.rayHit.v = nearest_v;
+ isectData.rayHitTriIndex = nearest_tri;
return 1;
- } else {
+ } else {
return 0;
}
}
@@ -157,36 +140,33 @@
///////////////////////////////////////////////////////////////////////////////
void KDTree::intersect(const RenderContext& context, RayPacket& rays) const
{
-
- // Normalize and compute inverse directions,
- // As a side effect this also computes the sign mask for the box
intersection.
rays.normalizeDirections();
rays.computeInverseDirections();
rays.computeSigns();
-
+
RayTriIntersectUserData isectData;
-
+
for(int i=rays.begin();i<rays.end();i++) {
-
+
Real minDist, maxDist;
-
+
// Intersect the ray with the bounding box for the group.
- if (Intersection::intersectAaBox( bbox,
- minDist, maxDist,
- e.ray,
- e.sign,
- e.inverseDirection )) {
-
- // Determine the actual minimum distance.
- minDist = SCIRun::Max( minDist, (Real)T_EPSILON );
- maxDist = SCIRun::Min( maxDist, e.hitInfo.minT() );
-
- // Send the ray to the _intersect function.
- isectData.rayHitTriIndex = -1;
- isectData.duplicate = 0;
- intersect_node( rootNode, &e.ray, e, isectData, context,
(float)minDist, (float)maxDist);
+ if (Intersection::intersectAaBox( bbox,
+ minDist, maxDist,
+ rays.getRay(i),
+ rays.getSigns(i),
+ rays.getInverseDirection(i)))
+ {
+ // Determine the actual minimum distance.
+ minDist = SCIRun::Max( minDist, T_EPSILON );
+ maxDist = SCIRun::Min( maxDist, rays.getMinT(i) );
+
+ // Send the ray to the _intersect function.
+ isectData.rayHitTriIndex = -1;
+ isectData.duplicate = 0;
+ intersect_node( rootNode, rays, i, isectData, context,
(float)minDist, (float)maxDist);
- }
+ }
}
}
@@ -195,10 +175,10 @@
///////////////////////////////////////////////////////////////////////////////
void KDTree::computeNormal(const RenderContext& /*context*/,
RayPacket& rays) const {
-
+
// Copy the normal out of the KDTree::ScratchPadInfo structure.
- for (int i=0;i<rays.getSize();++i) {
- rays.get(i).normal =
rays.get(i).hitInfo.scratchpad<ScratchPadInfo>().normal;
+ for (int i=rays.begin();i<rays.end();++i) {
+ rays.setNormal(i, rays.scratchpad<ScratchPadInfo>(i).normal);
}
}
@@ -210,143 +190,131 @@
// Traversal Stack Entry.
struct TravStackEntry {
- KDTreeNode* node; // 8 bytes
+ KDTreeNode* node; // 8 bytes(64 bit builds), 4 bytes(32 bit builds)
float t; // 4 bytes
int prev; // 4 bytes
};
-void KDTree::intersect_node( KDTreeNode *startNode,
- const Ray* ray, RayPacket::Element &e,
- RayTriIntersectUserData &isectData,
+void KDTree::intersect_node( KDTreeNode *startNode,
+ RayPacket& rays, int which,
+ RayTriIntersectUserData &isectData,
const RenderContext &context,
- float minDist, float maxDist) const
+ float minDist, float maxDist) const
{
-
- // Mailbox for this traversal.
- RayTriangleMailbox mailbox;
- mailbox.clear();
-
- KDTreeNode *nearNode, *farNode;
- float split;
- int axis, entryPos, exitPos;
- int tmp;
-
- Pointf origin = ray->origin();
- Vectorf direction = ray->direction();
-
+ KDTreeNode *nearNode = startNode;
+ KDTreeNode *farNode;
+ int entryPos = 0;
+ int exitPos = 1;
+
// Keep a stack of entry and exit positions into the traversal nodes.
#ifdef __ia64__
// __declspec(align(128))
#endif
- TravStackEntry travStack[128];
+ TravStackEntry travStack[128];
// Initialize the first two entries on the stack.
- entryPos = 0;
- nearNode = startNode;
- travStack[0].node = startNode;
- travStack[0].prev = 1;
-
- // Check for the case that the minimum intersection point is behind the
origin.
- travStack[entryPos].t = minDist < 0.0f ? 0.0f : minDist;
-
- exitPos = 1;
- travStack[1].node = NULL;
- travStack[1].t = maxDist;
- travStack[1].prev = 0;
+ travStack[entryPos].node = startNode;
+ // Check for the case that the minimum intersection point is behind
+ // the origin.
+ travStack[entryPos].t = minDist < 0 ? 0 : minDist;
+ travStack[entryPos].prev = 1;
+
+ travStack[exitPos].node = NULL;
+ travStack[exitPos].t = maxDist;
+ travStack[exitPos].prev = 0;
+
+ Pointf origin = rays.getOrigin(which);
+ Vectorf direction = rays.getDirection(which);
+ Vectorf invDirection = rays.getInverseDirection(which);
while (travStack[entryPos].prev) {
-
+
// Traverse down until we find a leaf node.
#pragma swp
while (nearNode && nearNode->isInternal()) {
-
+
// Determine the axis and the split point.
- axis = nearNode->axis();
- split = nearNode->split();
-
- // Find where along the axis the ray enters and exits.
- float entryPos_coord_on_axis =
- travStack[entryPos].t*direction[axis] + origin[axis];
-
- float exitPos_coord_on_axis =
- travStack[exitPos].t*direction[axis] + origin[axis];
-
+ int axis = nearNode->axis();
+ float split = nearNode->split();
+
+ // Find where along the axis the ray enters and exits.
+ float entryPos_coord_on_axis =
+ travStack[entryPos].t*direction[axis] + origin[axis];
+ float exitPos_coord_on_axis =
+ travStack[exitPos].t*direction[axis] + origin[axis];
+
// Check to see which side of the split the ray enters first.
if (entryPos_coord_on_axis <= split) {
-
- // Check to see if entry and exit are on the
- // same side of the split.
- if (exitPos_coord_on_axis <= split) {
-
- // Same side of the split, so the original interval is ok.
- nearNode = nearNode->left();
- continue;
- }
-
- // Otherwise update the near and far nodes, and then update
- // the interval below.
- farNode = nearNode->right();
- nearNode = nearNode->left();
+
+ // Check to see if entry and exit are on the
+ // same side of the split.
+ if (exitPos_coord_on_axis <= split) {
+
+ // Same side of the split, so the original interval is ok.
+ nearNode = nearNode->left();
+ continue;
+ }
+
+ // Otherwise update the near and far nodes, and then update
+ // the interval below.
+ farNode = nearNode->right();
+ nearNode = nearNode->left();
}
else {
- // Check to see if entry and exit are on the same side.
- if (exitPos_coord_on_axis >= split) {
- nearNode = nearNode->right();
- continue;
- }
-
- // Update otherwise.
- farNode = nearNode->left();
- nearNode = nearNode->right();
+ // Check to see if entry and exit are on the same side.
+ if (exitPos_coord_on_axis >= split) {
+ nearNode = nearNode->right();
+ continue;
+ }
+
+ // Update otherwise.
+ farNode = nearNode->left();
+ nearNode = nearNode->right();
}
-
+
// Update location on the traversal stack.
- tmp = exitPos;
-
+ int tmp = exitPos;
+
// ??? Increment to an unused node ???
if (++exitPos == entryPos) ++exitPos;
-
+
// Update the far node.
// Specify a new exit node.
travStack[exitPos].node = farNode;
- travStack[exitPos].t = (split - origin[axis])*
e.inverseDirection[axis];
+ travStack[exitPos].t = (split - origin[axis])* invDirection[axis];
travStack[exitPos].prev = tmp;
}
// Check to see if we found a non-empty leaf node.
if (nearNode) {
-
+
// Intersect the ray with a list of triangles.
- if (
- intersectTriangles(ray, nearNode->listBegin(),
nearNode->listSize(),
- /*travStack[exitPos].t,*/ e.hitInfo.minT(),
- &isectData,
- context, mailbox ) &&
- (isectData.rayHitTriIndex >= 0)) {
-
- if (isPickingEnabled()) {
- pickedTri = isectData.rayHitTriIndex;
- // cerr << "picked " << pickedTri << "\n";
- pickedBeginIndex = pickedEndIndex = pickedTri;
- while (pickedBeginIndex > 0 &&
- triToGroupMap->get(pickedBeginIndex-1)
- == triToGroupMap->get(pickedBeginIndex))
- pickedBeginIndex --;
- while (pickedEndIndex < tris->getLen()-1 &&
- triToGroupMap->get(pickedEndIndex+1)
- == triToGroupMap->get(pickedEndIndex))
- pickedEndIndex ++;
- // cerr << "picked begin " << pickedBeginIndex << " end " <<
pickedEndIndex << "\n";
-
- // cerr << "picked flag: " << (int)pickedFlag << std::endl;
- for (int i=pickedBeginIndex; i<=pickedEndIndex; i++)
- triFlags->set(i, pickedFlag);
- }
-
-
-
- // Check against the hit record, Note that tex coord mapper is null.
- if (e.hitInfo.hit(isectData.rayHit.t, getMaterial(), this, 0 )) {
+ if (intersectTriangles(origin, direction,
+ nearNode->listBegin(), nearNode->listSize(),
+ rays.getMinT(which), isectData)
+ && (isectData.rayHitTriIndex >= 0)) {
+
+ if (isPickingEnabled()) {
+ pickedTri = isectData.rayHitTriIndex;
+ // cerr << "picked " << pickedTri << "\n";
+ pickedBeginIndex = pickedEndIndex = pickedTri;
+ while (pickedBeginIndex > 0 &&
+ triToGroupMap->get(pickedBeginIndex-1)
+ == triToGroupMap->get(pickedBeginIndex))
+ pickedBeginIndex --;
+ while (pickedEndIndex < tris->getLen()-1 &&
+ triToGroupMap->get(pickedEndIndex+1)
+ == triToGroupMap->get(pickedEndIndex))
+ pickedEndIndex ++;
+ // cerr << "picked begin " << pickedBeginIndex << " end " <<
pickedEndIndex << "\n";
+
+ // cerr << "picked flag: " << (int)pickedFlag << std::endl;
+ for (int i=pickedBeginIndex; i<=pickedEndIndex; i++)
+ triFlags->set(i, pickedFlag);
+ }
+
+ // Check against the hit record, Note that tex coord mapper is null.
+ if (rays.hit(which, isectData.rayHit.t, getMaterial(), this, 0 )) {
// if (isectData.rayHit.t > t_epsilon) {
// e.hitInfo.set_hit(isectData.rayHit.t, material, this, 0 );
@@ -363,52 +331,51 @@
float u = isectData.rayHit.u;
float v = isectData.rayHit.v;
- e.hitInfo.scratchpad<ScratchPadInfo>().normal = (n1 * u) + (n2 *
v) + (n0 * (1.0f - u - v));
-
+ ScratchPadInfo& scratch_pad =
rays.scratchpad<ScratchPadInfo>(which);
+ scratch_pad.normal = (n1 * u) + (n2 * v) + (n0 * (1 - u - v));
+
#if SHOW_DUPLICATES
if (isectData.duplicate == 0)
- e.hitInfo.scratchpad<ScratchPadInfo>().payload =
Color(RGB(1.0,1.0,1.0));
+ scratch_pad.payload = Color(RGB(1.0,1.0,1.0));
else if (isectData.duplicate > 16)
- e.hitInfo.scratchpad<ScratchPadInfo>().payload =
Color(RGB(1.0,0.0,1.0));
+ scratch_pad.payload = Color(RGB(1.0,0.0,1.0));
else if (isectData.duplicate > 8)
- e.hitInfo.scratchpad<ScratchPadInfo>().payload =
Color(RGB(1.0,0.0,0.0));
+ scratch_pad.payload = Color(RGB(1.0,0.0,0.0));
else if (isectData.duplicate > 4)
- e.hitInfo.scratchpad<ScratchPadInfo>().payload =
Color(RGB(1.0,1.0,0.0));
+ scratch_pad.payload = Color(RGB(1.0,1.0,0.0));
else
- e.hitInfo.scratchpad<ScratchPadInfo>().payload =
Color(RGB(0.0,0.0,1.0));
-#else
- unsigned char flag;
- if ( pickedTri > 0 &&
- /*pickedBeginIndex <= isectData.rayHitTriIndex &&
- isectData.rayHitTriIndex <= pickedEndIndex*/
- (flag=triFlags->get(isectData.rayHitTriIndex))!=0)
- {
- switch(flag) {
- case PICK_HIGHLIGHT:
- e.hitInfo.scratchpad<ScratchPadInfo>().payload =
Color(RGB(1,1,1))-
- tris->get(isectData.rayHitTriIndex).payload;
- break;
- case PICK_REMOVE:
- e.hitInfo.scratchpad<ScratchPadInfo>().payload =
Color(RGB(0,0,0));
- break;
- }
- } else
- e.hitInfo.scratchpad<ScratchPadInfo>().payload =
tris->get(isectData.rayHitTriIndex).payload;
+ scratch_pad.payload = Color(RGB(0.0,0.0,1.0));
+#else
+ unsigned char flag;
+ if ( pickedTri > 0 &&
+ /*pickedBeginIndex <= isectData.rayHitTriIndex &&
+ isectData.rayHitTriIndex <= pickedEndIndex*/
+ (flag=triFlags->get(isectData.rayHitTriIndex))!=0)
+ {
+ switch(flag) {
+ case PICK_HIGHLIGHT:
+ scratch_pad.payload = Color(RGB(1,1,1))-
+ tris->get(isectData.rayHitTriIndex).payload;
+ break;
+ case PICK_REMOVE:
+ scratch_pad.payload = Color(RGB(0,0,0));
+ break;
+ }
+ } else
+ scratch_pad.payload =
tris->get(isectData.rayHitTriIndex).payload;
#endif
// Check to make sure the found hit is inside the current cell.
// if ((isectData.rayHit.t <= travStack[exitPos].t)/* &&
(isectData.rayHit.t > travStack[entryPos].t)*/)
// break;
- }
+ }
}
}
// Check to see if the hit is inside the current cell.
- if (e.hitInfo.minT() <= travStack[exitPos].t)
+ if (rays.getMinT(which) <= travStack[exitPos].t)
break;
-
-
-
- // Move to the next
+
+ // Move to the next
entryPos = exitPos;
exitPos = travStack[exitPos].prev;
nearNode = travStack[entryPos].node;
@@ -644,9 +611,8 @@
void KDTreeTexture::mapValues(const RenderContext& /*context*/,
RayPacket& rays, Color results[]) const {
- for (int i=0;i<rays.getSize();++i) {
- RayPacket::Element &e = rays.get(i);
- results[i] =
e.hitInfo.scratchpad<Kdtree::KDTree::ScratchPadInfo>().payload;
+ for (int i=rays.begin();i<rays.end();++i) {
+ results[i] = rays.scratchpad<Kdtree::KDTree::ScratchPadInfo>(i).payload;
}
}
Modified: branches/vertical/Model/Groups/KDTree.h
==============================================================================
--- branches/vertical/Model/Groups/KDTree.h (original)
+++ branches/vertical/Model/Groups/KDTree.h Thu Jan 19 15:16:23 2006
@@ -39,9 +39,8 @@
#include <Interface/Texture.h>
#include <Model/Groups/KDTreeLoader.h>
-#include <Model/Groups/RayTriangleMailbox.h>
-#include "varray.h"
+#include <Model/Groups/varray.h>
namespace Manta {
@@ -344,20 +343,14 @@
}
// This method intersects a list of triangles with the ray.
- int intersectTriangles(const Ray* ray, unsigned int listBegin,
- int listSize, float maxDist, void *userData,
- const RenderContext &context,
- RayTriangleMailbox &mailbox
- ) const;
+ int intersectTriangles(const Pointf& origin, const Vectorf& direction,
+ unsigned int listBegin, unsigned int listSize,
+ float maxDist,
+ RayTriIntersectUserData &isectData) const;
// This method is called to intersect a single ray with the kdtree.
-
- // void _intersect(const Ray* ray, RayPacket::Element &e,
- // RayTriIntersectUserData &isectData,
- // const RenderContext &context,
- // float _minDist=-1, float _maxDist=-1) const;
void intersect_node( KDTreeNode *startNode,
- const Ray* ray, RayPacket& rays, int which,
+ RayPacket& rays, int which,
RayTriIntersectUserData &isectData,
const RenderContext &context,
float minDist, float maxDist) const;
Modified: branches/vertical/Model/Groups/TransparentKDTree.cc
==============================================================================
--- branches/vertical/Model/Groups/TransparentKDTree.cc (original)
+++ branches/vertical/Model/Groups/TransparentKDTree.cc Thu Jan 19 15:16:23
2006
@@ -29,12 +29,7 @@
*/
#include <Model/Groups/TransparentKDTree.h>
-
-#include <iostream>
-#include <algorithm>
-
-#include <stdio.h>
-#include "varray.h"
+#include <Model/Groups/varray.h>
#include <Model/Intersections/AxisAlignedBox.h>
@@ -44,6 +39,12 @@
#include <SCIRun/Core/Thread/Thread.h>
#include <SCIRun/Core/Thread/Runnable.h>
+#include <sgi_stl_warnings_off.h>
+#include <iostream>
+#include <algorithm>
+#include <sgi_stl_warnings_off.h>
+
+#include <stdio.h>
using namespace Manta;
using namespace Manta::Kdtree;
@@ -53,11 +54,24 @@
using std::endl;
using std::sort;
+///////////////////////////////////////////////////////////
+
+// TODO: Alpha termination needs to be consistent.
+
+// TODO: isectBuffers is not thread safe. Needs to be moved to member
+// variable.
+
+// TODO: For intersectTrianglesTransparent isectbuf->append() can
+// allocate memory, but only as needed.
+
+///////////////////////////////////////////////////////////
+
// From Tomas Akenine-Moller's code, included below in this file.
static int
intersect_triangle3(const float orig[3],
const float dir[3],
- const float vert0[3], const float vert1[3], const float
vert2[3],
+ const float vert0[3], const float vert1[3],
+ const float vert2[3],
float *t, float *u, float *v );
static inline int
@@ -77,25 +91,25 @@
// CONSTRUCTOR CONSTRUCTOR CONSTRUCTOR CONSTRUCTOR CONSTRUCTOR
CONSTRUCTOR
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-TransparentKDTree::TransparentKDTree( KDTree *kdtree_, Material *material_,
Real sample_alpha_ ) :
- PrimitiveCommon( material_ ),
- rootNode( kdtree_->rootNode ),
- triIndices( kdtree_->triIndices ),
- tris( kdtree_->tris ),
- normals( kdtree_->normals ),
- sample_alpha( sample_alpha_ ),
- triToGroupMap(kdtree_->triToGroupMap),
- groupToNameMap(kdtree_->groupToNameMap),
- groupNames(kdtree_->groupNames),
- __pickingEnabled(kdtree_->__pickingEnabled),
- pickingEnabled(kdtree_->pickingEnabled),
- pickedTri(kdtree_->pickedTri),
- pickedBeginIndex(kdtree_->pickedBeginIndex),
- pickedEndIndex(kdtree_->pickedEndIndex),
- triFlags(kdtree_->triFlags),
- pickedFlag(kdtree_->pickedFlag)
+TransparentKDTree::TransparentKDTree( KDTree *kdtree_, Material *material_,
+ Real sample_alpha_ ) :
+ PrimitiveCommon( material_ ),
+ rootNode( kdtree_->rootNode ),
+ triIndices( kdtree_->triIndices ),
+ tris( kdtree_->tris ),
+ normals( kdtree_->normals ),
+ sample_alpha( sample_alpha_ ),
+ triToGroupMap(kdtree_->triToGroupMap),
+ groupToNameMap(kdtree_->groupToNameMap),
+ groupNames(kdtree_->groupNames),
+ __pickingEnabled(kdtree_->__pickingEnabled),
+ pickingEnabled(kdtree_->pickingEnabled),
+ pickedTri(kdtree_->pickedTri),
+ pickedBeginIndex(kdtree_->pickedBeginIndex),
+ pickedEndIndex(kdtree_->pickedEndIndex),
+ triFlags(kdtree_->triFlags),
+ pickedFlag(kdtree_->pickedFlag)
{
-
bbox.extendByBox( kdtree_->bbox );
}
@@ -104,105 +118,90 @@
// INTERSECT TRIANGLES INTERSECT TRIANGLES INTERSECT TRIANGLES INTERSECT
TRI
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
+
VArray<VArray<TransparentKDTree::Isect> *>
TransparentKDTree::isectBuffers(1024, 0);
-int TransparentKDTree::intersectTrianglesTransparent(const Ray* ray,
RayPacket::Element &e, unsigned int listBegin, int listSize, float maxDist,
void *userData, const RenderContext &context, bool isFirst) const
+int TransparentKDTree::intersectTrianglesTransparent
+ (const Pointf& origin, const Vectorf& direction,
+ ScratchPadInfo& scratch_pad,
+ unsigned int listBegin, unsigned int listSize,
+ float maxDist,
+ RayTriIntersectUserData& userData,
+ const RenderContext &context) const
{
- int i;
- RayTriIntersectUserData *ud = (RayTriIntersectUserData*)userData;
+
////////////////////////////////////////////////////////////////////////////
+ // Check to see if the thread buffers array is allocated.
+ if (isectBuffers.getLen() != (context.numProcs+1)) {
+ // One additional buffer is needed for "shootSingleRay" queries
+ // from the gui thread.
+ isectBuffers.setLen( context.numProcs+1, 0 );
+ }
+
+ // Determine the thread number.
+ int threadId = context.proc;
+ VArray<TransparentKDTree::Isect> *isectbuf = isectBuffers.get(threadId);
+
+ // Check to see if the per-thread buffer for this thread is allocated.
+ if (! isectbuf) {
+ isectbuf = new VArray<TransparentKDTree::Isect>(8);
+ isectBuffers.set(threadId, isectbuf);
+ }
+ isectbuf->setLen(0);
+
+
////////////////////////////////////////////////////////////////////////////
+ // Intersect the ray with all the triangles.
+ Real sample_t = scratch_pad.sample_t;
+
+ unsigned int listEnd = listBegin+listSize;
+
+#pragma swp
+ for (unsigned int i = listBegin; i < listEnd; i++) {
+ int triIdx = triIndices->get(i);
+ Triangle &tri = tris->get(triIdx);
+ float t, u, v;
+
+ // if (intersectTriangle3Edge( direction, origin, tri.edge1, tri.edge2,
tri[0], t, u, v )) {
+ if(intersect_triangle3_edge( origin.getDataPtr(), direction.getDataPtr(),
+ &tri[0][0],
+ &t, &u, &v,
+ tri.edge1.getDataPtr(),
+ tri.edge2.getDataPtr() ))
+ {
+ // Check to see if the t value is closer.
+ if ((t > sample_t) && (t < maxDist)) {
+ Isect &isect = isectbuf->append();
+ isect.t = t;
+ isect.u = u;
+ isect.v = v;
+ isect.triIdx = triIdx;
+ }
+ }
+ }
+
+
////////////////////////////////////////////////////////////////////////////
+ // Check to see if any triangles need to be blended.
+ if (isectbuf->getLen()) {
+
+ // sort the intersections
+ Isect *array = isectbuf->getArray();
+ std::sort(array, array+isectbuf->getLen());
+
+ // Make a copy of the hitrecord stuff and then store it back later
+ Color ray_color = scratch_pad.payload;
+ Real ray_alpha = scratch_pad.alpha;
+
+ // Check to see if this is the first triangle the ray hit.
+ if (ray_alpha == 0.0) {
+ userData.rayHit.t = array[0].t;
+ userData.rayHit.u = array[0].u;
+ userData.rayHit.v = array[0].v;
+ userData.rayHitTriIndex = array[0].triIdx;
+ }
- Vectorf direction = ray->direction();
- Pointf origin = ray->origin();
+ Real sample_alpha__ = sample_alpha;
-
////////////////////////////////////////////////////////////////////////////
- // Check to see if the thread buffers array is allocated.
- if (isectBuffers.getLen() != (context.numProcs+1)) {
- // One additional buffer is needed for "shootSingleRay"
queries from the gui thread.
- isectBuffers.setLen( context.numProcs+1, 0 );
- }
-
- // Determine the thread number.
- int threadId = context.proc;
- VArray<TransparentKDTree::Isect> *isectbuf =
isectBuffers.get(threadId);
-
- // Check to see if the per-thread buffer for this thread is allocated.
- if (! isectbuf) {
- isectbuf = new VArray<TransparentKDTree::Isect>(8);
- isectBuffers.set(threadId, isectbuf);
- }
- isectbuf->setLen(0);
-
-
////////////////////////////////////////////////////////////////////////////
- // Intersect the ray with all the triangles.
- Real &sample_t = e.hitInfo.scratchpad<ScratchPadInfo>().sample_t;
-
- int listEnd = listBegin+listSize;
-
- #pragma swp
- for (i = listBegin; i < listEnd; i++) {
- int triIdx = triIndices->get(i);
- Triangle &tri = tris->get(triIdx);
- float t, u, v;
-
- // if (intersectTriangle3Edge( direction, origin, tri.edge1,
tri.edge2, tri[0], t, u, v )) {
- if(intersect_triangle3_edge( &origin[0], &direction[0],
&tri[0][0], &t, &u, &v, &tri.edge1, &tri.edge2 )) {
-
- // Check to see if the t value is closer.
- if ((t > sample_t) && (t < maxDist)) {
- Isect &isect = isectbuf->append();
- isect.t = t;
- isect.u = u;
- isect.v = v;
- isect.triIdx = triIdx;
- }
- }
- }
-
-
////////////////////////////////////////////////////////////////////////////
- // Check to see if any triangles need to be blended.
- if (isectbuf->getLen()) {
-
- // sort the intersections
- Isect *array = isectbuf->getArray();
- std::sort(array, array+isectbuf->getLen());
-
- // Modify the hit record color directly.
- Color &ray_color =
e.hitInfo.scratchpad<ScratchPadInfo>().payload;
- Real &ray_alpha =
e.hitInfo.scratchpad<ScratchPadInfo>().alpha;
-
- // Check to see if this is the first triangle the ray hit.
- if (ray_alpha == 0.0) {
- ud->rayHit.t = array[0].t;
- ud->rayHit.u = array[0].u;
- ud->rayHit.v = array[0].v;
- ud->rayHitTriIndex = array[0].triIdx;
- }
-
- Real sample_alpha__ = sample_alpha;
-
- // combine color and opacity
- Color c;
- for (int i=0; (i<isectbuf->getLen()) && (ray_alpha <
(Real)0.95); i++) {
-
- Color *triangle_color = &tris->get( array[i].triIdx
).payload;
- unsigned char flag;
- if (pickedTri > 0 &&
- /*pickedBeginIndex <= array[i].triIdx &&
- array[i].triIdx <=
pickedEndIndex*/
- (flag = triFlags->get(array[i].triIdx)) != 0
- ) {
- switch(flag) {
- case KDTree::PICK_HIGHLIGHT:
- c = Color(RGB(1,1,1)) - *triangle_color;
- triangle_color = &c;
- break;
- case KDTree::PICK_REMOVE:
- c = Color(RGB(0,0,0));
- triangle_color = &c;
- sample_alpha__ = 0;
- break;
- }
- }
+ // combine color and opacity
+ for (int i=0; (i<isectbuf->getLen()) && (ray_alpha < (Real)0.95); i++) {
// Interpolate the normal.
Vectorf &n0 = normals[array[i].triIdx][0];
@@ -212,26 +211,52 @@
float u = array[i].u;
float v = array[i].v;
- Vectorf normal = (n1 * u) + (n2 * v) + (n0 * (1.0f - u - v));
-
+ Vectorf normal = (n1 * u) + (n2 * v) + (n0 * (1.0f - u - v));
+
Real scale = Abs(Dot( normal, direction ));
- scale *= (Real)0.75;
- scale += (Real)0.25;
-
- Color sample_color = (*triangle_color * scale);
-
- ray_color += (sample_color*sample_alpha__) * (1 -
ray_alpha);
- ray_alpha += sample_alpha__ * (1 - ray_alpha);
- }
-
- // Update sample t to the last triangle composited.
- sample_t = array[isectbuf->getLen()-1].t;
+ scale *= (Real)0.75;
+ scale += (Real)0.25;
- return 1;
- }
- else {
- return 0;
- }
+ Color triangle_color;
+ unsigned char flag;
+ if (pickedTri > 0 && (flag = triFlags->get(array[i].triIdx)) != 0) {
+ switch(flag) {
+ case KDTree::PICK_HIGHLIGHT:
+ // Create an inverted color
+ triangle_color = Color::white() -
tris->get(array[i].triIdx).payload;
+ break;
+ case KDTree::PICK_REMOVE:
+ // Just stick something in triangle_color. It doesn't
+ // matter what, since it will get multiplied by zero.
+ triangle_color = Color::black();
+ sample_alpha__ = 0;
+ break;
+ }
+ }
+ else {
+ triangle_color = tris->get( array[i].triIdx ).payload;
+ }
+
+ // Make sure you do all the scalar multiplication first so that
+ // the number of Color*Real operations are minimized.
+ Real blend = sample_alpha__ * (1 - ray_alpha);
+ ray_color += triangle_color * (scale * blend);
+ ray_alpha += blend;
+ }
+
+ // Update sample t to the last triangle composited.
+ sample_t = array[isectbuf->getLen()-1].t;
+
+ // Put the stuff back
+ scratch_pad.sample_t = sample_t;
+ scratch_pad.payload = ray_color;
+ scratch_pad.alpha = ray_alpha;
+
+ return 1;
+ }
+ else {
+ return 0;
+ }
}
///////////////////////////////////////////////////////////////////////////////
@@ -239,36 +264,33 @@
// This is the Manta interface method.
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-void TransparentKDTree::intersect(const RenderContext& context, RayPacket&
rays) const
+void TransparentKDTree::intersect(const RenderContext& context,
+ RayPacket& rays) const
{
-
- // Normalize and compute inverse directions,
- // As a side effect this also computes the sign mask for the box
intersection.
rays.normalizeDirections();
rays.computeInverseDirections();
rays.computeSigns();
-
+
RayTriIntersectUserData isectData;
-
- for(int i=0;i<rays.getSize();i++) {
-
- RayPacket::Element& e = rays.get(i);
+
+ for(int i=rays.begin();i<rays.end();++i) {
+
Real minDist, maxDist;
-
+
// Intersect the ray with the bounding box for the group.
- if (Intersection::intersectAaBox( bbox,
-
minDist, maxDist,
-
e.ray,
-
e.sign,
-
e.inverseDirection )) {
-
- // Determine the actual minimum distance.
- minDist = SCIRun::Max( minDist, (Real)T_EPSILON );
- maxDist = SCIRun::Min( maxDist, e.hitInfo.minT() );
-
- // Send the ray to the _intersect function.
- isectData.rayHitTriIndex = -1;
- _intersect( &e.ray, e, isectData, context,
(float)minDist, (float)maxDist);
+ if (Intersection::intersectAaBox( bbox,
+ minDist, maxDist,
+ rays.getRay(i),
+ rays.getSigns(i),
+ rays.getInverseDirection(i)))
+ {
+ // Determine the actual minimum distance.
+ minDist = SCIRun::Max( minDist, T_EPSILON );
+ maxDist = SCIRun::Min( maxDist, rays.getMinT(i) );
+
+ // Send the ray to the intersect_node function.
+ isectData.rayHitTriIndex = -1;
+ intersect_node( rootNode, rays, i, isectData, context,
(float)minDist, (float)maxDist);
}
}
@@ -279,11 +301,11 @@
///////////////////////////////////////////////////////////////////////////////
void TransparentKDTree::computeNormal(const RenderContext& /*context*/,
RayPacket& rays) const {
-
+
// Copy the normal out of the TransparentKDTree::ScratchPadInfo
structure.
- for (int i=0;i<rays.getSize();++i) {
- rays.get(i).normal =
rays.get(i).hitInfo.scratchpad<ScratchPadInfo>().normal;
- }
+ for (int i=rays.begin();i<rays.end();++i) {
+ rays.setNormal(i, rays.scratchpad<ScratchPadInfo>(i).normal);
+ }
}
///////////////////////////////////////////////////////////////////////////////
@@ -296,156 +318,160 @@
struct TravStackEntry {
KDTreeNode* node; //8 bytes
float t; // 4 bytes
-
// float point[3]; // 4*3=12 bytes
int prev; // 4 bytes
};
-void TransparentKDTree::_intersect(const Ray* ray, RayPacket::Element &e,
RayTriIntersectUserData &isectData, const RenderContext &context,
-
float minDist, float maxDist) const
+void TransparentKDTree::intersect_node(KDTreeNode *startNode,
+ RayPacket& rays, int which,
+ RayTriIntersectUserData &isectData,
+ const RenderContext &context,
+ float minDist, float maxDist) const
{
- // Set the ray color to black, alpha to 1.0.
- e.hitInfo.scratchpad<ScratchPadInfo>().reset();
-
- Color &ray_color = e.hitInfo.scratchpad<ScratchPadInfo>().payload;
- Real &ray_alpha = e.hitInfo.scratchpad<ScratchPadInfo>().alpha;
-
- KDTreeNode *nearNode, *farNode;
- float split;
- int axis, entryPos, exitPos;
- int tmp;
-
- Pointf origin = ray->origin();
- Vectorf direction = ray->direction();
-
+ ScratchPadInfo& scratch_pad = rays.scratchpad<ScratchPadInfo>(which);
+ // Set the ray color to black, alpha to 1.0.
+ scratch_pad.reset();
+
+ Color &ray_color = scratch_pad.payload;
+ Real &ray_alpha = scratch_pad.alpha;
+
+ KDTreeNode *nearNode = startNode;
+ KDTreeNode *farNode;
+ int entryPos = 0;
+ int exitPos = 1;
+
// Keep a stack of entry and exit positions into the traversal nodes.
#ifdef __ia64__
- // __declspec(align(128))
+ // __declspec(align(128))
#endif
- TravStackEntry travStack[128];
-
- // Initialize the first two entries on the stack.
- entryPos = 0;
- nearNode = travStack[entryPos].node = rootNode;
- travStack[entryPos].prev = 1;
- travStack[entryPos].t = minDist < 0.0f ? 0.0f : minDist;
-
- exitPos = 1;
- travStack[exitPos].node = NULL;
- travStack[exitPos].t = maxDist;
- travStack[exitPos].prev = 0;
-
- while (travStack[entryPos].prev) {
-
- // Traverse down until we find a leaf node.
- while (nearNode && nearNode->isInternal()) {
-
- // Determine the axis and the split point.
- axis = nearNode->axis();
- split = nearNode->split();
-
- // Find where along the axis the ray enters and
exits.
- float entryPos_coord_on_axis =
-
travStack[entryPos].t*direction[axis] + origin[axis];
-
- float exitPos_coord_on_axis =
-
travStack[exitPos].t*direction[axis] + origin[axis];
-
- // Check to see which side of the split the ray
enters first.
- if (entryPos_coord_on_axis <= split) {
- // Check to see if entry and exit are on the
- // same side of the split.
- if (exitPos_coord_on_axis <= split) {
- // Same side of the split, so the
original interval is ok.
- nearNode = nearNode->left();
- continue;
- }
- // Otherwise update the near and far nodes,
and then update
- // the interval below.
- farNode = nearNode->right();
- nearNode = nearNode->left();
- }
- else {
- // Check to see if entry and exit are on the
same side.
- if (exitPos_coord_on_axis >= split) {
- nearNode = nearNode->right();
- continue;
- }
- // Update otherwise.
- farNode = nearNode->left();
- nearNode = nearNode->right();
- }
-
- // Update location on the traversal stack.
- tmp = exitPos;
-
- // ??? Increment to an unused node ???
- if (++exitPos == entryPos) ++exitPos;
-
- // Specify a new exit node.
- travStack[exitPos].node = farNode;
- travStack[exitPos].t = (split - origin[axis])*
e.inverseDirection[axis];
-
- travStack[exitPos].prev = tmp;
- }
-
- // Check to see if we found a leaf node.
- if (nearNode) {
-
- bool first_leaf = (ray_alpha == 0.0);
-
- // Intersect the ray with a list of triangles.
- if (intersectTrianglesTransparent(ray, e,
-
nearNode->listBegin(), nearNode->listSize(),
-
travStack[exitPos].t, &isectData, context, first_leaf) &&
- (isectData.rayHitTriIndex >= 0)) {
-
- // If this is the first leaf, record the hit
and normal.
- if (first_leaf) {
- // record hit if picking
- if (isPickingEnabled()) {
- pickedTri =
isectData.rayHitTriIndex;
- // cerr << "picked " <<
pickedTri << "\n";
- pickedBeginIndex =
pickedEndIndex = pickedTri;
- while (pickedBeginIndex > 0 &&
-
triToGroupMap->get(pickedBeginIndex-1)
- ==
triToGroupMap->get(pickedBeginIndex))
- pickedBeginIndex --;
- while (pickedEndIndex <
tris->getLen()-1 &&
-
triToGroupMap->get(pickedEndIndex+1)
- ==
triToGroupMap->get(pickedEndIndex))
- pickedEndIndex ++;
- // cerr << "picked begin " <<
pickedBeginIndex << "end " << pickedEndIndex << "\n";
- // cerr << "picked flag: " <<
(int)pickedFlag << std::endl;
- for (int i=pickedBeginIndex;
i<=pickedEndIndex; i++)
- triFlags->set(i,
pickedFlag);
- }
-
- // Process the hit.
- e.hitInfo.hit(isectData.rayHit.t,
getMaterial(), this, 0 );
-
- // Copy the normal into the scratch
pad.
- // Used for shootOneRay type queries.
-
e.hitInfo.scratchpad<TransparentKDTree::ScratchPadInfo>().normal =
- normals[isectData.rayHitTriIndex][0];
-
- first_leaf = false;
- }
-
- // Check to see if the ray is fully
attenuated.
- if
(e.hitInfo.scratchpad<ScratchPadInfo>().alpha > 0.9) {
- break;
- }
- }
- }
-
- // Move to the next
- entryPos = exitPos;
- exitPos = travStack[exitPos].prev;
- nearNode = travStack[entryPos].node;
- }
-
- // Blend with the background.
- ray_color += (Color(RGB(0.8,0.8,0.8))) * (1.0f - ray_alpha);
+ TravStackEntry travStack[128];
+
+ // Initialize the first two entries on the stack.
+ travStack[entryPos].node = startNode;
+ travStack[entryPos].t = minDist < 0 ? 0 : minDist;
+ travStack[entryPos].prev = 1;
+
+ travStack[exitPos].node = NULL;
+ travStack[exitPos].t = maxDist;
+ travStack[exitPos].prev = 0;
+
+ Pointf origin = rays.getOrigin(which);
+ Vectorf direction = rays.getDirection(which);
+ Vectorf invDirection = rays.getInverseDirection(which);
+
+ while (travStack[entryPos].prev) {
+
+ // Traverse down until we find a leaf node.
+ while (nearNode && nearNode->isInternal()) {
+
+ // Determine the axis and the split point.
+ int axis = nearNode->axis();
+ float split = nearNode->split();
+
+ // Find where along the axis the ray enters and exits.
+ float entryPos_coord_on_axis =
+ travStack[entryPos].t*direction[axis] + origin[axis];
+
+ float exitPos_coord_on_axis =
+ travStack[exitPos].t*direction[axis] + origin[axis];
+
+ // Check to see which side of the split the ray enters first.
+ if (entryPos_coord_on_axis <= split) {
+
+ // Check to see if entry and exit are on the
+ // same side of the split.
+ if (exitPos_coord_on_axis <= split) {
+
+ // Same side of the split, so the original interval is ok.
+ nearNode = nearNode->left();
+ continue;
+ }
+
+ // Otherwise update the near and far nodes, and then update
+ // the interval below.
+ farNode = nearNode->right();
+ nearNode = nearNode->left();
+ }
+ else {
+ // Check to see if entry and exit are on the same side.
+ if (exitPos_coord_on_axis >= split) {
+ nearNode = nearNode->right();
+ continue;
+ }
+ // Update otherwise.
+ farNode = nearNode->left();
+ nearNode = nearNode->right();
+ }
+
+ // Update location on the traversal stack.
+ int tmp = exitPos;
+
+ // ??? Increment to an unused node ???
+ if (++exitPos == entryPos) ++exitPos;
+
+ // Specify a new exit node.
+ travStack[exitPos].node = farNode;
+ travStack[exitPos].t = (split - origin[axis])* invDirection[axis];
+ travStack[exitPos].prev = tmp;
+ }
+
+ // Check to see if we found a non-empty leaf node.
+ if (nearNode) {
+
+ bool first_leaf = (ray_alpha == 0);
+
+ // Intersect the ray with a list of triangles.
+ if (intersectTrianglesTransparent(origin, direction, scratch_pad,
+ nearNode->listBegin(),
+ nearNode->listSize(),
+ travStack[exitPos].t, isectData,
+ context)
+ && (isectData.rayHitTriIndex >= 0)) {
+
+ // If this is the first leaf, record the hit and normal.
+ if (first_leaf) {
+ // record hit if picking
+ if (isPickingEnabled()) {
+ pickedTri = isectData.rayHitTriIndex;
+ // cerr << "picked " << pickedTri << "\n";
+ pickedBeginIndex = pickedEndIndex = pickedTri;
+ while (pickedBeginIndex > 0 &&
+ triToGroupMap->get(pickedBeginIndex-1)
+ == triToGroupMap->get(pickedBeginIndex))
+ pickedBeginIndex --;
+ while (pickedEndIndex < tris->getLen()-1 &&
+ triToGroupMap->get(pickedEndIndex+1)
+ == triToGroupMap->get(pickedEndIndex))
+ pickedEndIndex ++;
+ // cerr << "picked begin " << pickedBeginIndex << "end " <<
pickedEndIndex << "\n";
+ // cerr << "picked flag: " << (int)pickedFlag << std::endl;
+ for (int i=pickedBeginIndex; i<=pickedEndIndex; i++)
+ triFlags->set(i, pickedFlag);
+ }
+
+ // Check against the hit record, Note that tex coord mapper is
null.
+ if (rays.hit(which, isectData.rayHit.t, getMaterial(), this, 0 )) {
+
+ // Copy the normal into the scratch pad.
+ // Used for shootOneRay type queries.
+ scratch_pad.normal = normals[isectData.rayHitTriIndex][0];
+ }
+ }
+
+ // Check to see if the ray is fully attenuated.
+ if (ray_alpha > 0.9) {
+ break;
+ }
+ }
+ }
+
+ // Move to the next
+ entryPos = exitPos;
+ exitPos = travStack[exitPos].prev;
+ nearNode = travStack[entryPos].node;
+ }
+
+ // Blend with the background.
+ ray_color += (Color(RGB(0.8,0.8,0.8))) * (1 - ray_alpha);
}
///////////////////////////////////////////////////////////////////////////////
Modified: branches/vertical/Model/Groups/TransparentKDTree.h
==============================================================================
--- branches/vertical/Model/Groups/TransparentKDTree.h (original)
+++ branches/vertical/Model/Groups/TransparentKDTree.h Thu Jan 19 15:16:23
2006
@@ -95,12 +95,26 @@
private:
Real sample_alpha;
-
+
+ // Predeclaration for the benefit of functions that want to use it.
+ class ScratchPadInfo;
+
// This method intersects a list of triangles with the ray.
- int intersectTrianglesTransparent(const Ray* ray, RayPacket::Element
&e, unsigned int listBegin, int listSize, float maxDist, void *userData,
const RenderContext &context, bool isFirst=false) const;
-
+ int intersectTrianglesTransparent(const Pointf& origin,
+ const Vectorf& direction,
+ ScratchPadInfo& scratch_pad,
+ unsigned int listBegin,
+ unsigned int listSize,
+ float maxDist,
+ RayTriIntersectUserData& userData,
+ const RenderContext &context) const;
+
// This method is called by the above method with a hansong ray.
- void _intersect(const Ray* ray, RayPacket::Element &e,
RayTriIntersectUserData &isectData, const RenderContext &context, float
_minDist=-1, float _maxDist=-1) const;
+ void intersect_node(KDTreeNode *startNode,
+ RayPacket& rays, int which,
+ RayTriIntersectUserData &isectData,
+ const RenderContext &context,
+ float minDist, float maxDist) const;
// This structure is used to order the triangle hits along the ray
// before blending.
Modified: branches/vertical/Model/Materials/AmbientOcclusion.cc
==============================================================================
--- branches/vertical/Model/Materials/AmbientOcclusion.cc (original)
+++ branches/vertical/Model/Materials/AmbientOcclusion.cc Thu Jan 19
15:16:23 2006
@@ -13,19 +13,22 @@
// TODO: sort the rays generated in generateDirections to make them more
// coherent for ray packets.
+// TODO: Try to pack as many occlusion rays into a single ray packet.
-AmbientOcclusion::AmbientOcclusion(const Color& color, float cutoff_dist,
int num_dirs)
+AmbientOcclusion::AmbientOcclusion(const Color& color, float cutoff_dist,
+ int num_dirs)
{
colortex = new Constant<Color>(color);
cutoff = cutoff_dist;
- inv_num_directions = 1.f/float(num_dirs);
+ inv_num_directions = 1.0/num_dirs;
generateDirections(num_dirs);
}
-AmbientOcclusion::AmbientOcclusion(const Texture<Color>* color, float
cutoff_dist, int num_dirs)
+AmbientOcclusion::AmbientOcclusion(const Texture<Color>* color,
+ float cutoff_dist, int num_dirs)
: colortex(color), cutoff(cutoff_dist)
{
- inv_num_directions = 1.f/float(num_directions);
+ inv_num_directions = 1.0/num_dirs;
generateDirections(num_dirs);
}
@@ -54,89 +57,101 @@
}
}
-void AmbientOcclusion::shade(const RenderContext& context, RayPacket& rays)
const
+void AmbientOcclusion::shade(const RenderContext& context,
+ RayPacket& rays) const
{
// Compute normals
rays.computeNormals(context);
rays.computeHitPositions();
- // Compute colors
- Color colors[RayPacket::MaxSize];
- colortex->mapValues(context, rays, colors);
+ // We are going to first compute the ambient values.
+ ColorArray total;
+ for(int i = rays.begin(); i < rays.end(); ++i) {
+ // for each position, compute a local coordinate frame
+ // and build a set of rays to push into a ray packet
+ Vector W(rays.getNormal(i)); // surface ONB
+ Vector U(Cross(W, Vector(1,0,0)));
+ Real squared_length = U.length2();
+ if ( squared_length < (Real)1e-6 )
+ U = Cross(W, Vector(0,1,0));
+ Vector V(Cross(W, U));
+
+ // Send out the ambient occlusion tests
+ int num_sent = 0;
+ int num_miss = 0;
+ int num_directions = static_cast<int>(directions.size());
+ while ( num_sent < num_directions ) {
+ int start = num_sent;
+ int end = start + RayPacket::MaxSize;
+ if (end > num_directions) end = num_directions;
+
+ RayPacketData occlusion_data;
+ // Should the normalized flag be set? The normals coming in
+ // should already be normalized.
+ int flag = RayPacket::NormalizedDirections | RayPacket::ConstantOrigin;
+ RayPacket occlusion_rays(occlusion_data, start, end, rays.getDepth(),
+ flag);
+
+ for ( int r = start; r < end; r++ ) {
+ Vector trans_dir = (directions[r][0]*U +
+ directions[r][1]*V +
+ directions[r][2]*W);
+ occlusion_rays.setRay(r, rays.getHitPosition(i), trans_dir);
+ // set max distance
+ occlusion_rays.resetHit(r, cutoff);
+ }
+
+ // packet is ready, test it for occlusion
+ context.scene->getObject()->intersect(context, occlusion_rays);
+
+ // count the number of occluded ones
+ for (int r = start; r < end; r++ ) {
+ if(!occlusion_rays.wasHit(r))
+ num_miss++;
+ }
+ num_sent = end;
+ }
+ for(int j=0;j<Color::NumComponents;j++)
+ total[j][i] = num_miss * (inv_num_directions * (ColorComponent)0.4);
+ }
+ // Compute the diffuse shading
RayPacketData data;
- int start = 0;
+ ShadowAlgorithm::StateBuffer stateBuffer;
+ bool firstTime = true;
+ bool done;
do {
- RayPacket shadowRays(data, 0, rays.getDepth(), 0);
- int end = context.shadowAlgorithm->computeShadows(context, activeLights,
- rays, start,
shadowRays);
- shadowRays.normalizeDirections();
- for(int i=start;i<end;i++)
- {
- RayPacket::Element& e = rays.get(i);
-
- // for each position, compute a local coordinate frame
- // and build a set of rays to push into a ray packet
- Vector W(e.normal); // surface ONB
- W.normalize();
- Vector U(Cross(W, Vector(1,0,0)));
- double squared_length = U.length2();
- if ( squared_length < 1e-6 )
- {
- U = Cross(W, Vector(0,1,0));
- U.normalize();
- }
- else
- U *= 1./sqrt(squared_length);
- Vector V(Cross(W, U));
-
- // Send out the ambient occlusion tests
- int num_sent = 0;
- float num_miss = 0.f;
- while ( num_sent < num_directions )
- {
- int start = num_sent;
- int end = start + RayPacket::MaxSize;
- if (end > num_directions) end = num_directions;
-
- RayPacketData occlusion_data;
- RayPacket occlusion_rays(occlusion_data, end-start,
rays.getDepth(), RayPacket::NormalizedDirections | RayPacket::ConstantOrigin);
-
- for ( int r = start; r < end; r++ )
- {
- RayPacket::Element& element =
occlusion_rays.get(r-start);
- Vector trans_dir = directions[r][0]*U +
directions[r][1]*V + directions[r][2]*W;
- element.ray.set(e.hitPosition, trans_dir);
- // set max distance
- element.hitInfo.reset(cutoff);
- }
- // packet is ready, test it for occlusion
- context.scene->getObject()->intersect(context,
occlusion_rays);
- // count the number of occluded ones
- for (int r = start; r < end; r++ )
- {
- RayPacket::Element& element =
occlusion_rays.get(r-start);
- if(!element.hitInfo.wasHit())
- num_miss+=1.0f;
- }
- num_sent = end;
- }
-
- // Test for shadows and diffuse lighting from regular light
sources
- Color totalLight(RGB(0,0,0));
- 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*0.6+colors[i]*(num_miss*inv_num_directions*0.4));
- }
- start = end;
- } while(start < rays.getSize());
-
+ int map[RayPacket::MaxSize];
+ RayPacket shadowRays(data, 0, 0, rays.getDepth(), 0);
+ done = context.shadowAlgorithm->computeShadows(context, activeLights,
+ rays, map, shadowRays,
+ firstTime, stateBuffer);
+ shadowRays.normalizeDirections();
+ for(int j=shadowRays.begin(); j < shadowRays.end(); j++){
+ if(!shadowRays.wasHit(j)){
+ // Not in shadow, so compute the direct and specular contributions.
+ int to = map[j];
+ Vector normal = rays.getNormal(to);
+ Vector shadowdir = shadowRays.getDirection(j);
+ ColorComponent cos_theta = Dot(shadowdir, normal);
+ Color light = shadowRays.getColor(j);
+ for(int k = 0; k < Color::NumComponents;k++)
+ total[k][to] += light[k]*cos_theta*(ColorComponent)0.6;
+ }
+ }
+
+ firstTime = false;
+ } while(!done);
+
+ // Compute diffuse colors
+ Color diffuse[RayPacket::MaxSize];
+ colortex->mapValues(context, rays, diffuse);
+
+ // Sum up diffuse/specular contributions
+ for(int i = rays.begin(); i < rays.end(); i++){
+ Color result;
+ for(int j=0;j<Color::NumComponents;j++)
+ result[j] = diffuse[i][j] * total[j][i];
+ rays.setColor(i, result);
+ }
}
Modified: branches/vertical/Model/Materials/AmbientOcclusion.h
==============================================================================
--- branches/vertical/Model/Materials/AmbientOcclusion.h (original)
+++ branches/vertical/Model/Materials/AmbientOcclusion.h Thu Jan 19
15:16:23 2006
@@ -4,7 +4,10 @@
#include <Model/Materials/LitMaterial.h>
#include <Core/Color/Color.h>
#include <Interface/Texture.h>
+
+#include <sgi_stl_warnings_off.h>
#include <vector>
+#include <sgi_stl_warnings_on.h>
namespace Manta
{
@@ -14,11 +17,12 @@
{
public:
AmbientOcclusion(const Color& color, float cutoff_dist, int num_dirs);
- AmbientOcclusion(const Texture<Color>* color, float cutoff_dist, int
num_dirs);
+ AmbientOcclusion(const Texture<Color>* color, float cutoff_dist,
+ int num_dirs);
AmbientOcclusion() { }
~AmbientOcclusion();
- void generateDirections();
+ void generateDirections(int num_directions);
// generate the directions
void shade(const RenderContext& context, RayPacket& rays) const;
@@ -26,7 +30,7 @@
const Texture<Color>* colortex;
float cutoff;
std::vector<Vector> directions;
- float inv_num_directions;
+ ColorComponent inv_num_directions;
};
}
Modified: branches/vertical/Model/Materials/CMakeLists.txt
==============================================================================
--- branches/vertical/Model/Materials/CMakeLists.txt (original)
+++ branches/vertical/Model/Materials/CMakeLists.txt Thu Jan 19 15:16:23
2006
@@ -1,7 +1,7 @@
SET (Manta_Materials_SRCS
- #Materials/AmbientOcclusion.h
- #Materials/AmbientOcclusion.cc
+ Materials/AmbientOcclusion.h
+ Materials/AmbientOcclusion.cc
Materials/Checker.h
Materials/Checker.cc
Materials/Dielectric.h
Modified: branches/vertical/Model/Materials/Dielectric.cc
==============================================================================
--- branches/vertical/Model/Materials/Dielectric.cc (original)
+++ branches/vertical/Model/Materials/Dielectric.cc Thu Jan 19 15:16:23
2006
@@ -37,9 +37,10 @@
#include <Interface/Renderer.h>
#include <Interface/Scene.h>
#include <Interface/ShadowAlgorithm.h>
-#include <Core/Math/Trig.h>
+#include <Core/Math/Expon.h>
using namespace Manta;
+using namespace SCIRun;
Dielectric::Dielectric(const Texture<Real>* n, const Texture<Real>* nt,
const Texture<Color>* sigma_a,
Modified: branches/vertical/Model/MiscObjects/CMakeLists.txt
==============================================================================
--- branches/vertical/Model/MiscObjects/CMakeLists.txt (original)
+++ branches/vertical/Model/MiscObjects/CMakeLists.txt Thu Jan 19 15:16:23
2006
@@ -1,8 +1,8 @@
SET (Manta_MiscObjects_SRCS
+ MiscObjects/CuttingPlane.h
+ MiscObjects/CuttingPlane.cc
MiscObjects/Difference.h
MiscObjects/Difference.cc
MiscObjects/Intersection.h
MiscObjects/Intersection.cc
- #MiscObjects/CuttingPlane.h
- #MiscObjects/CuttingPlane.cc
)
Modified: branches/vertical/Model/MiscObjects/CuttingPlane.cc
==============================================================================
--- branches/vertical/Model/MiscObjects/CuttingPlane.cc (original)
+++ branches/vertical/Model/MiscObjects/CuttingPlane.cc Thu Jan 19 15:16:23
2006
@@ -30,7 +30,8 @@
// Send a new ray packet with new ray origins.
RayPacketData new_data;
- RayPacket new_rays( new_data, rays.begin(), rays.end(),
rays.getDepth(), rays.getAllFlags());
+ RayPacket new_rays( new_data, rays.begin(), rays.end(),
rays.getDepth(),
+ rays.getAllFlags());
rays.normalizeDirections();
rays.computeInverseDirections();
@@ -47,50 +48,50 @@
/////////////////////////////////////////////////////////////////////////////
// Create the new rays.
- int new_i = 0, i;
- for (i=rays.begin();i<rays.end();++i) {
- RayPacket::Element &e = rays.get( i );
-
+ int new_i = 0;
+ for (int i=rays.begin();i<rays.end();++i) {
Real box_min, box_max;
-
+
+ Ray ray = rays.getRay(i);
// Check to see if the ray intersects the bounding box.
if (Intersection::intersectAaBox( bounds, box_min, box_max,
- e.ray, e.sign, e.inverseDirection )) {
+ ray, rays.getSigns(i),
+ rays.getInverseDirection(i) )) {
// Intersect the ray with the plane.
- Intersection::intersectPlane( plane_point, plane_normal,
plane_t[new_i], e.ray );
-
- RayPacket::Element &n = new_rays.get( new_i );
+ Intersection::intersectPlane( plane_point, plane_normal,
plane_t[new_i],
+ ray );
// Record which original ray this new ray maps to.
packet_map[new_i] = i;
// Check to see if the ray origin is on the front or back facing side
of
// the cutting plane (the front facing side is cut away).
- if (front_facing[new_i] = (Dot(plane_normal,
(e.ray.origin()-plane_point)) > 0.0)) {
+ front_facing[new_i] = Dot(plane_normal, (ray.origin()-plane_point)) >
0;
+ if (front_facing[new_i]) {
// If plane_t is negative, the ray can't possibly hit the cut model.
// because the ray is pointing away from the plane.
- if (plane_t[new_i] > 0.0) {
+ if (plane_t[new_i] > 0) {
// If front facing, move the new ray to the cutting plane.
-
n.ray.set(e.ray.origin()+(e.ray.direction()*plane_t[new_i]),e.ray.direction());
+ new_rays.setRay(new_i,
ray.origin()+(ray.direction()*plane_t[new_i]),
+ ray.direction());
new_rays.resetFlag(RayPacket::ConstantOrigin);
// Subtract the distance from the hit t.
- n.hitInfo.reset( e.hitInfo.minT() - plane_t[new_i] );
+ new_rays.resetHit( new_i, rays.getMinT(i) - plane_t[new_i] );
++new_i;
}
}
else {
- // Otherwise if back facing, move the hit t in the hit record to the
plane
- // (it will need to be moved back afterwards)
- n.ray = e.ray;
- //n.hitInfo.reset( plane_t[new_i] );
- n.hitInfo.reset( e.hitInfo.minT() );
+ // Otherwise if back facing, move the hit t in the hit record
+ // to the plane (it will need to be moved back afterwards)
+ new_rays.setRay(new_i, ray);
+ new_rays.resetHit( new_i, rays.getMinT(i) );
++new_i;
}
@@ -113,34 +114,32 @@
/////////////////////////////////////////////////////////////////////////////
// Map the results back to the old rays.
- for (new_i=rays.begin(); new_i<new_rays.end(); ++new_i) {
-
- RayPacket::Element &n = new_rays.get(new_i);
+ for (new_i=new_rays.begin(); new_i<new_rays.end(); ++new_i) {
// Check to see if the new ray hit something.
- if (n.hitInfo.wasHit()) {
+ if (new_rays.wasHit(new_i)) {
// Determine which old ray this maps to.
- RayPacket::Element &e = rays.get( packet_map[new_i] );
+ int old_i = packet_map[new_i];
// Check to see if the old ray is front or back facing.
if (front_facing[new_i]) {
// If so, then translate the hit t back into the old hit record.
- if (e.hitInfo.hit( n.hitInfo.minT()+plane_t[new_i],
- n.hitInfo.hitMaterial(),
- n.hitInfo.hitPrimitive(),
- n.hitInfo.hitTexCoordMapper() ))
- e.hitInfo.copyScratchpad( n.hitInfo );
+ if (rays.hit( old_i, new_rays.getMinT(new_i)+plane_t[new_i],
+ new_rays.getHitMaterial(new_i),
+ new_rays.getHitPrimitive(new_i),
+ new_rays.getHitTexCoordMapper(new_i) ))
+ rays.copyScratchpad( old_i, new_rays, new_i );
}
else {
- // Otherwise, if the original ray is back facing check to see if the
hit
- // is closer then the cutting plane.
- if ((plane_t[new_i] < 0.0) || (n.hitInfo.minT() < plane_t[new_i])) {
- if (e.hitInfo.hit( n.hitInfo.minT(),
- n.hitInfo.hitMaterial(),
- n.hitInfo.hitPrimitive(),
- n.hitInfo.hitTexCoordMapper() ))
- e.hitInfo.copyScratchpad( n.hitInfo );
+ // Otherwise, if the original ray is back facing check to see
+ // if the hit is closer then the cutting plane.
+ if ((plane_t[new_i]<0) || (new_rays.getMinT(new_i) <
plane_t[new_i])) {
+ if (rays.hit( old_i, new_rays.getMinT(new_i),
+ new_rays.getHitMaterial(new_i),
+ new_rays.getHitPrimitive(new_i),
+ new_rays.getHitTexCoordMapper(new_i) ))
+ rays.copyScratchpad( old_i, new_rays, new_i );
}
}
}
Modified: branches/vertical/Model/Primitives/Cone.cc
==============================================================================
--- branches/vertical/Model/Primitives/Cone.cc (original)
+++ branches/vertical/Model/Primitives/Cone.cc Thu Jan 19 15:16:23 2006
@@ -3,9 +3,10 @@
#include <Interface/RayPacket.h>
#include <Core/Geometry/BBox.h>
#include <Core/Util/NotFinished.h>
-#include <Core/Math/Trig.h>
+#include <Core/Math/Expon.h>
using namespace Manta;
+using namespace SCIRun;
using namespace std;
Cone::Cone(Material* mat, const Point& bottom, const Point& top, Real Rb,
Real Rt)
Modified: branches/vertical/Model/Primitives/Heightfield.h
==============================================================================
--- branches/vertical/Model/Primitives/Heightfield.h (original)
+++ branches/vertical/Model/Primitives/Heightfield.h Thu Jan 19 15:16:23
2006
@@ -8,7 +8,6 @@
namespace Manta {
- // using namespace SCIRun;
class Heightfield : public PrimitiveCommon
{
Modified: branches/vertical/Model/Primitives/Hemisphere.cc
==============================================================================
--- branches/vertical/Model/Primitives/Hemisphere.cc (original)
+++ branches/vertical/Model/Primitives/Hemisphere.cc Thu Jan 19 15:16:23
2006
@@ -9,6 +9,7 @@
// TODO: tighter bounds
using namespace Manta;
+using namespace SCIRun;
using namespace std;
Hemisphere::Hemisphere(Material* material, const Point& center, Real radius,
const Vector& normal)
Modified: branches/vertical/Model/Primitives/Sphere.cc
==============================================================================
--- branches/vertical/Model/Primitives/Sphere.cc (original)
+++ branches/vertical/Model/Primitives/Sphere.cc Thu Jan 19 15:16:23
2006
@@ -4,10 +4,11 @@
#include <Core/Geometry/BBox.h>
#include <Core/Math/MiscMath.h>
#include <Core/Math/Trig.h>
+#include <Core/Math/Expon.h>
using namespace Manta;
+using namespace SCIRun;
using namespace std;
-using SCIRun::Clamp;
Sphere::Sphere(Material* material, const Point& center, Real radius)
: PrimitiveCommon(material, this), center(center), radius(radius)
Modified: branches/vertical/Model/Textures/OakTexture.h
==============================================================================
--- branches/vertical/Model/Textures/OakTexture.h (original)
+++ branches/vertical/Model/Textures/OakTexture.h Thu Jan 19 15:16:23
2006
@@ -97,8 +97,6 @@
RayPacket &rays,
ValueType results[] ) const
{
- using SCIRun::Clamp;
- using SCIRun::Interpolate;
using SCIRun::SmoothStep;
rays.computeTextureCoordinates3( context );
for( int i = rays.begin(); i < rays.end(); i++ ) {
@@ -107,7 +105,7 @@
Point Pring = tc + ringnoise * offset;
Vector vsnoise = VectorNoise( Point( 0.5, 0.5, tc.z() *
trunkwobblefreq ) );
Pring += Vector( trunkwobble * vsnoise.x(), trunkwobble * vsnoise.y(),
0.0 );
- double r = sqrt( Pring.x() * Pring.x() + Pring.y() * Pring.y() ) *
ringfreq;
+ double r = SCIRun::Sqrt( Pring.x() * Pring.x() + Pring.y() * Pring.y()
) * ringfreq;
r += angularwobble * SmoothStep( r, 0, 5 ) * ScalarNoise( Point(
angularwobble * Pring.x(),
angularwobble * Pring.y(),
angularwobble * Pring.z() * 0.1 ) );
@@ -121,7 +119,7 @@
{
double g = 0.8 * ScalarNoise( Pgrain );
g *= ( 0.3 + 0.7 * inring );
- g = Clamp( 0.8 - g, 0.0, 1.0 );
+ g = SCIRun::Clamp( 0.8 - g, 0.0, 1.0 );
g = grainy * SmoothStep( g * g, 0.5, 1.0 );
if ( it == 0 )
inring *= 0.7;
@@ -129,8 +127,8 @@
Pgrain.multiplyBy(2.0);
amp *= 0.5;
}
- double value = Interpolate( 1.0, grain, inring * ringy );
- results[ i ] = Interpolate( value2, value1, value );
+ double value = SCIRun::Interpolate( 1.0, grain, inring * ringy );
+ results[ i ] = SCIRun::Interpolate( value2, value1, value );
}
}
}
Modified: branches/vertical/UserInterface/CameraPathAutomator.cc
==============================================================================
--- branches/vertical/UserInterface/CameraPathAutomator.cc (original)
+++ branches/vertical/UserInterface/CameraPathAutomator.cc Thu Jan 19
15:16:23 2006
@@ -70,13 +70,15 @@
interval_start( 1 ),
interval_last ( total_points-2 )
{
- eye = new Point[total_points];
- lookat = new Point[total_points];
+ eye = new Vector[total_points];
+ lookat = new Vector[total_points];
up = new Vector[total_points];
- memcpy( eye, eye_, total_points*sizeof(Point) );
- memcpy( lookat, lookat_, total_points*sizeof(Point) );
- memcpy( up, up_, total_points*sizeof(Vector) );
+ for(int i = 0; i < total_points; ++i) {
+ eye[i] = Vector(eye_[i]);
+ lookat[i] = Vector(lookat_[i]);
+ up[i] = up_[i];
+ }
}
@@ -137,8 +139,8 @@
fseek( file, SEEK_SET, 0 );
// Allocate storage for points.
- eye = new Point [total_points];
- lookat = new Point [total_points];
+ eye = new Vector[total_points];
+ lookat = new Vector[total_points];
up = new Vector[total_points];
/////////////////////////////////////////////////////////////////////////////
@@ -178,8 +180,7 @@
/////////////////////////////////////////////////////////////////////////
// Parse eye, lookat and up from the args.
- Point eye_, lookat_;
- Vector up_;
+ Vector eye_, lookat_, up_;
bool got_eye = false;
bool got_lookat = false;
@@ -187,14 +188,14 @@
for (int i=0;i<(int)args.size();++i) {
if (args[i] == "-eye") {
- if (!getPointArg(i,args,eye_)) {
+ if (!getVectorArg(i,args,eye_)) {
sprintf(error_message, "CameraPathAutomator -eye input line:
%d", line_num );
throw new IllegalArgument(error_message, i, args);
}
got_eye = true;
}
else if (args[i] == "-lookat") {
- if (!getPointArg(i,args,lookat_)) {
+ if (!getVectorArg(i,args,lookat_)) {
sprintf(error_message, "CameraPathAutomator -lookat input line:
%d", line_num );
throw new IllegalArgument(error_message, i, args);
}
@@ -257,8 +258,8 @@
int behavior = PATH_STOP;
int start = 0, last = 0;
- Real delta_t = 0.0;
- Real delta_time = 0.0;
+ Real delta_t = 0;
+ Real delta_time = 0;
for (int i=0; i<args.size(); ++i) {
if (args[i] == "-file") {
@@ -302,10 +303,10 @@
automator->set_loop_behavior( behavior );
// Check to see if either delta was specified on the command line.
- if (delta_t != 0.0) {
+ if (delta_t != 0) {
automator->set_delta_t( delta_t );
}
- if (delta_time != 0.0) {
+ if (delta_time != 0) {
automator->set_delta_time( delta_time );
}
@@ -326,8 +327,7 @@
// Implementation of the interpolator.
void CameraPathAutomator::run_automator() {
- Point current_eye, current_lookat;
- Vector current_up;
+ Vector current_eye, current_lookat, current_up;
int current_point = 0;
@@ -344,38 +344,43 @@
do {
-
/////////////////////////////////////////////////////////////////////////////
+
//////////////////////////////////////////////////////////////////////////
// Main Automator loop.
- for (current_point=first_point;(current_point<last_point) &&
(loop_behavior!=PATH_ABORT);++current_point) {
-
-
///////////////////////////////////////////////////////////////////////////
+ for (current_point=first_point;
+ (current_point<last_point) && (loop_behavior!=PATH_ABORT);
+ ++current_point) {
+
+
////////////////////////////////////////////////////////////////////////
// Sample by delta_t between the points.
- for (Real t=0.0; (t<(1.0-delta_t)) && (loop_behavior!=PATH_ABORT);
t+=delta_t) {
+ for (Real t=0; t<(1-delta_t) && loop_behavior!=PATH_ABORT; t+=delta_t)
{
// Evaluate the spline.
// NOTE: operator & is overloaded by Vector to return (Real *)
// NOTE: none of the necessary operations are defined for Points...
// so we cast to vectors for the interpolation.
-
- catmull_rom_interpolate( (Vector *)&eye[current_point], t,
*((Vector *)¤t_eye) );
- catmull_rom_interpolate( (Vector *)&lookat[current_point], t,
*((Vector *)¤t_lookat) );
- catmull_rom_interpolate( (Vector *)&up[current_point], t,
current_up );
+
+ catmull_rom_interpolate( &eye[current_point], t, current_eye);
+ catmull_rom_interpolate( &lookat[current_point], t, current_lookat);
+ catmull_rom_interpolate( &up[current_point], t, current_up );
// Send the transaction to manta.
- getMantaInterface()->addTransaction("CameraPathAutomator",
- Callback::create(this,
&CameraPathAutomator::mantaSetCamera,
- current_eye,
current_lookat, current_up ));
+ getMantaInterface()->addTransaction
+ ("CameraPathAutomator",
+ Callback::create(this, &CameraPathAutomator::mantaSetCamera,
+ Point(current_eye), Point(current_lookat),
+ current_up ));
// Record the time of this transaction before a potential sync
- double start_time = SCIRun::Time::currentSeconds();
-
+ double start_time = SCIRun::Time::currentSeconds();
+
// Check to see if this is a synchronization point.
if (sync_frames && ((transaction_number % sync_frames) == 0)) {
// Add a synchronization transaction.
- getMantaInterface()->addTransaction("CameraPathAutomator-Sync",
- Callback::create(this,
&CameraPathAutomator::mantaSynchronize,
-
transaction_number ));
+ getMantaInterface()->addTransaction
+ ("CameraPathAutomator-Sync",
+ Callback::create(this, &CameraPathAutomator::mantaSynchronize,
+ transaction_number ));
// Wait for the render thread.
synchronize_barrier.wait( 2 );
@@ -383,7 +388,7 @@
transaction_number++;
-
/////////////////////////////////////////////////////////////////////////
+
//////////////////////////////////////////////////////////////////////
// Wait for delta_time seconds.
while ((SCIRun::Time::currentSeconds()-start_time) < delta_time);
}
@@ -392,7 +397,7 @@
// Compute the average fps for this run.
int total_frames = getMantaInterface()->getCurrentFrame() - start_frame;
average_fps =
(Real)total_frames/(SCIRun::Time::currentSeconds()-start_seconds);
-
+
std::cerr << "Path complete. " << total_frames
<< " frames. Avg fps: " << average_fps << std::endl;
}
@@ -412,8 +417,10 @@
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-void CameraPathAutomator::mantaSetCamera( const Point eye_, const Point
lookat_, const Vector up_ ) {
-
+void CameraPathAutomator::mantaSetCamera( const Point eye_,
+ const Point lookat_,
+ const Vector up_ ) {
+
// Reset the current camera.
getMantaInterface()->getCamera( channel )->reset( eye_, up_, lookat_ );
}
Modified: branches/vertical/UserInterface/CameraPathAutomator.h
==============================================================================
--- branches/vertical/UserInterface/CameraPathAutomator.h (original)
+++ branches/vertical/UserInterface/CameraPathAutomator.h Thu Jan 19
15:16:23 2006
@@ -44,14 +44,18 @@
using std::string;
using std::vector;
using SCIRun::Barrier;
-
+
class CameraPathAutomator : public AutomatorUI {
private:
///////////////////////////////////////////////////////////////////////////
// Control points.
- Point *eye;
- Point *lookat;
+ //
+ // These are all vectors, because we have to do operators with
+ // them that don't exist for Points. Points passed in are
+ // converted to Vectors, so the API remains the same.
+ Vector *eye;
+ Vector *lookat;
Vector *up;
int total_points;
@@ -61,7 +65,7 @@
// Minimum time to wait between camera movements.
Real delta_time;
-
+
// Channel to apply camera changes to.
int channel;
@@ -85,32 +89,38 @@
// fps for the last complete run of this automator.
Real average_fps;
-
+
public:
// Loop Behaviors
enum { PATH_STOP, PATH_EXIT, PATH_LOOP, PATH_ABORT };
- CameraPathAutomator( MantaInterface *manta_interface_, int channel_, int
warmup_, const string &file_name,
+ CameraPathAutomator( MantaInterface *manta_interface_, int channel_,
+ int warmup_, const string &file_name,
Real delta_t_ = 0.2, Real delta_time_ = 0.2 );
-
- CameraPathAutomator( MantaInterface *manta_interface_, int channel_, int
warmup_,
- Point *eye_, Point *lookat_, Vector *up_, int
total_points_,
+
+ CameraPathAutomator( MantaInterface *manta_interface_, int channel_,
+ int warmup_, Point *eye_, Point *lookat_,
+ Vector *up_, int total_points_,
Real delta_t_ = 0.2, Real delta_time_ = 0.2 );
~CameraPathAutomator();
// Create method called by RTRT_register.
- static UserInterface *create( const vector<string> &args, MantaInterface
*manta_interface_ );
+ static UserInterface *create( const vector<string> &args,
+ MantaInterface *manta_interface_ );
// Implementation of the interpolator.
virtual void run_automator();
-
- // This method is called by the manta rendering thread to update the
camera.
- void mantaSetCamera( const Point eye_, const Point lookat_, const Vector
up_ );
+
+ // This method is called by the manta rendering thread to update
+ // the camera.
+ void mantaSetCamera( const Point eye_, const Point lookat_,
+ const Vector up_ );
// This method is called by the manta rendering thread to synchronize.
void mantaSynchronize( int issue_transaction );
- // This may be called to write the camera path to a specified file in
the correct format.
+ // This may be called to write the camera path to a specified file
+ // in the correct format.
void write_path( const string &file_name );
// Accessors.
@@ -118,7 +128,7 @@
inline Real get_delta_t() { return delta_t; };
inline void set_delta_t( Real delta_t_ ) { delta_t = delta_t_; };
-
+
inline Real get_delta_time() { return delta_time; };
inline void set_delta_time( Real delta_time_ ) { delta_time =
delta_time_; };
Modified: branches/vertical/UserInterface/XWindowUI.cc
==============================================================================
--- branches/vertical/UserInterface/XWindowUI.cc (original)
+++ branches/vertical/UserInterface/XWindowUI.cc Thu Jan 19 15:16:23
2006
@@ -11,7 +11,7 @@
#include <Core/Exceptions/InternalError.h>
#include <Core/Geometry/AffineTransform.h>
#include <Core/Math/MiscMath.h>
-#include <Core/Math/Trig.h>
+#include <Core/Math/Expon.h>
#include <Core/Thread/Runnable.h>
#include <Core/Thread/Thread.h>
#include <Core/XUtils/XHelper.h>
@@ -41,11 +41,8 @@
#define TOKEN_LOCK 2
using namespace Manta;
+using namespace SCIRun;
using namespace std;
-using SCIRun::Abs;
-using SCIRun::ErrnoException;
-using SCIRun::InternalError;
-using SCIRun::Thread;
UserInterface* XWindowUI::create(const vector<string>& args,
MantaInterface *rtrt_interface)
- [MANTA] r850 - in branches/vertical: Core/Geometry Core/Math Image Interface Model/AmbientLights Model/Cameras Model/Groups Model/Materials Model/MiscObjects Model/Primitives Model/Textures UserInterface, bigler, 01/19/2006
Archive powered by MHonArc 2.6.16.