Text archives Help
- From: aek@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r464 - in trunk: Core/Geometry Engine/Control Model/Groups Model/Primitives scenes
- Date: Tue, 2 Aug 2005 15:34:05 -0600 (MDT)
Author: aek
Date: Tue Aug 2 15:34:04 2005
New Revision: 464
Added:
trunk/Model/Groups/GriddedGroup.cc
trunk/Model/Groups/GriddedGroup.h
Modified:
trunk/Core/Geometry/BBox.h
trunk/Engine/Control/RTRT_register.cc
trunk/Model/Groups/CMakeLists.txt
trunk/Model/Groups/sub.mk
trunk/Model/Primitives/SuperEllipsoid.cc
trunk/scenes/0.cc
Log:
M Model/Primitives/SuperEllipsoid.cc
- Removed #include <iostream> left over from debugging
- Took out a TODO comment
M Core/Geometry/BBox.h
- Added method to test whether the BBox is in the default state
- Added method to extend by another BBox
- Added methods to compute area and volume of the box
A Model/Groups/GriddedGroup.cc
A Model/Groups/GriddedGroup.h
- First pass, ported grid code from cs6620 reference implementation.
Still slow and needs a ton of tuning, especially to start taking
advantage of ray packets. Sometimes fails at startup with certain
cell factors but works otherwise.
M Model/Groups/sub.mk
M Model/Groups/CMakeLists.txt
M Engine/Control/RTRT_register.cc
- Added references to GriddedGroup
M scenes/0.cc
- Sphereflake now in its own nest group, optionally an accel structure
- Changed -bv to -group and made message more intuitive, gives error
message instead of silently falling back to Group on failure
- To try grid, use: -scene "0(-size 4 -group grid(-cellfactor 21))"
Modified: trunk/Core/Geometry/BBox.h
==============================================================================
--- trunk/Core/Geometry/BBox.h (original)
+++ trunk/Core/Geometry/BBox.h Tue Aug 2 15:34:04 2005
@@ -26,7 +26,15 @@
min = Point( max_val, max_val, max_val);
max = Point(-max_val, -max_val, -max_val);
}
-
+
+ // Test whether the box is in the "uninitialized state"
+ bool isDefault() {
+ Real max_val = std::numeric_limits<Real>::max();
+ return ( min.x() == max_val && max.x() == -max_val &&
+ min.y() == max_val && max.y() == -max_val &&
+ min.z() == max_val && max.z() == -max_val );
+ }
+
Vector diagonal() const {
return max-min;
}
@@ -47,6 +55,10 @@
min = Min(min, p-v*radius);
max = Max(max, p+v*radius);
}
+ void extendByBox(const BBox& b) {
+ min = Min(min, b.min);
+ max = Max(max, b.max);
+ }
const Point& getMin() const {
return min;
@@ -60,6 +72,22 @@
i&2?min.y():max.y(),
i&1?min.z():max.z());
}
+
+ double computeVolume() const
+ {
+ return ( ( max.x() - min.x() ) *
+ ( max.y() - min.y() ) *
+ ( max.z() - min.z() ) );
+ }
+
+ double computeArea() const
+ {
+ double lenx = max.x() - min.x();
+ double leny = max.y() - min.y();
+ double lenz = max.z() - min.z();
+ return (2.0*((lenx*leny) + (leny*lenz) + (lenx*lenz)));
+ }
+
private:
BBox(const BBox&);
BBox& operator=(const BBox&);
Modified: trunk/Engine/Control/RTRT_register.cc
==============================================================================
--- trunk/Engine/Control/RTRT_register.cc (original)
+++ trunk/Engine/Control/RTRT_register.cc Tue Aug 2 15:34:04 2005
@@ -33,6 +33,7 @@
#include <Model/Cameras/OrthogonalCamera.h>
#include <Model/Cameras/FisheyeCamera.h>
#include <Model/Groups/BVH.h>
+#include <Model/Groups/GriddedGroup.h>
#include <Model/Groups/Group.h>
#include <UserInterface/PromptUI.h>
#include <UserInterface/XWindowUI.h>
@@ -102,6 +103,7 @@
// Register groups
rtrt->registerObject("group", &Group::create);
+ rtrt->registerObject("grid", &GriddedGroup::create);
rtrt->registerObject("bvh", &BVH::create);
}
}
Modified: trunk/Model/Groups/CMakeLists.txt
==============================================================================
--- trunk/Model/Groups/CMakeLists.txt (original)
+++ trunk/Model/Groups/CMakeLists.txt Tue Aug 2 15:34:04 2005
@@ -1,5 +1,6 @@
SET (Manta_Groups_SRCS
Groups/BVH.cc
+ Groups/GriddedGroup.cc
Groups/Group.cc
)
Added: trunk/Model/Groups/GriddedGroup.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Groups/GriddedGroup.cc Tue Aug 2 15:34:04 2005
@@ -0,0 +1,261 @@
+
+#include <Model/Groups/GriddedGroup.h>
+#include <Interface/RayPacket.h>
+#include <Core/Exceptions/IllegalArgument.h>
+#include <Core/Exceptions/InternalError.h>
+#include <Core/Geometry/BBox.h>
+#include <Core/Math/MinMax.h>
+#include <Core/Util/Args.h>
+#include <SCIRun/Core/Thread/Time.h>
+#include <SCIRun/Core/Math/MinMax.h>
+#include <iostream>
+
+using namespace std;
+using namespace Manta;
+using namespace SCIRun;
+
+Group *GriddedGroup::create( const vector< string > &args )
+{
+ return new GriddedGroup( args );
+}
+
+GriddedGroup::GriddedGroup( const vector< string > &args )
+{
+ bool gotCellfactor = false;
+ int argc = static_cast<int>(args.size());
+ for(int i=0; i< argc; i++){
+ string arg = args[i];
+ if(arg == "-cellfactor"){
+ if(!getDoubleArg(i, args, cellfactor))
+ throw IllegalArgument("GriddedGroup -cellfactor", i, args);
+ gotCellfactor = true;
+ } else {
+ throw IllegalArgument("BeamShadows", i, args);
+ }
+ }
+ if(!gotCellfactor)
+ throw IllegalArgument("Griddedgroup needs -cellfactor", 0, args);
+}
+
+GriddedGroup::GriddedGroup()
+{
+ cellfactor = 1.0;
+}
+
+GriddedGroup::~GriddedGroup()
+{
+}
+
+void GriddedGroup::transformToLattice(const BBox& box,
+ int& sx, int& sy, int& sz,
+ int& ex, int& ey, int& ez) const
+{
+ Vector s = (box.getMin()-min)*inv_cellsize-Vector(1.e-6,1.e-6,1.e-6);
+ sx = Floor(s.x()); sy = Floor(s.y()); sz = Floor(s.z());
+ Vector e = (box.getMax()-min)*inv_cellsize+Vector(1.e-6,1.e-6,1.e-6);
+ ex = Ceil(e.x()); ey = Ceil(e.y()); ez = Ceil(e.z());
+}
+
+void GriddedGroup::preprocess( const PreprocessContext &context )
+{
+
+ double start = Time::currentSeconds();
+ Group::preprocess(context);
+
+ const Object*const* fast_objects = &objs[0];
+
+ BBox bbox;
+ Group::computeBounds(context,bbox);
+
+ min = bbox.getMin();
+ max = bbox.getMax();
+ diag = bbox.getMax() - bbox.getMin();
+ diag = Max(Vector(1.e-4,1.e-4,1.e-4), diag);
+ min -= diag*1.e-5;
+ max += diag*1.e-5;
+ diag = max-min;
+
+ double volume = diag.x()*diag.y()*diag.z();
+ double vol3 = Cbrt(volume);
+ int numObjects = objs.size();
+ int target_numcells = static_cast<int>(numObjects*cellfactor);
+ double avgside = cbrt(static_cast<double>(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);
+ nx = SCIRun::Max(1, nx); ny = SCIRun::Max(1, ny); nz = SCIRun::Max(1, nz);
+ int totalcells = nx*ny*nz;
+ cellsize = diag/Vector(nx, ny, nz);
+ inv_cellsize = cellsize.inverse();
+ cells.resize(nx, ny, nz, 1);
+
+ cerr << "1. Initializing grid\n";
+ cells.initialize(0);
+
+ cerr << "2. Count objects\n";
+
+for(int i=0;i<static_cast<int>(objs.size());i++){
+ const Object* obj = fast_objects[i];
+
+ BBox objbox;
+ obj->computeBounds(context,objbox);
+ int sx, sy, sz, ex, ey, ez;
+ transformToLattice(objbox, sx, sy, sz, ex, ey, ez);
+ for(int x=sx;x<ex;x++){
+ for(int y=sy;y<ey;y++){
+ for(int z=sz;z<ez;z++){
+ cells(x, y, z)++;
+ }
+ }
+ }
+ }
+
+ cerr << "3. Count cells\n";
+ int sum = 0;
+ for(int i=0;i<totalcells;i++){
+ int nobj = cells[i];
+ cells[i] = sum;
+ sum += nobj;
+ }
+ cells[totalcells] = sum;
+
+ cerr << "4. Allocating " << sum << " list entries\n";
+ lists = new const Object*[sum];
+
+ Array3<int> offset(nx, ny, nz);
+ offset.initialize(0);
+ cerr << "5. Filling in lists\n";
+ for(int i=0;i<static_cast<int>(objs.size());i++){
+ const Object* obj = fast_objects[i];
+
+ BBox objbox;
+ obj->computeBounds(context,objbox);
+ int sx, sy, sz, ex, ey, ez;
+ transformToLattice(objbox, sx, sy, sz, ex, ey, ez);
+ for(int x=sx;x<ex;x++){
+ for(int y=sy;y<ey;y++){
+ for(int z=sz;z<ez;z++){
+ int start = cells(x, y, z);
+ int cur = offset(x, y, z)++;
+ lists[start+cur] = obj;
+ }
+ }
+ }
+ }
+
+ cerr << "6. verifying grid\n";
+ for(int x = 0;x < nx; x++){
+ for(int y = 0;y < ny; y++){
+ for(int z = 0;z < nz; z++){
+ int idx = cells.getIndex(x,y,z);
+ int n = cells[idx+1]-cells[idx];
+ if(n != offset(x, y, z))
+ cerr << "GriddedGroup initialization error at " << x << ", " << y
<< ", " << z << ": count is " << offset(nx, ny, nz) << ", but should be " <<
n << '\n';
+ }
+ }
+ }
+
+ double dt = Time::currentSeconds()-start;
+ cerr << "GriddedGroup: " << numObjects << " objects, targeted cells: " <<
target_numcells << ", actual cells: " << totalcells << ", " << nx << "x" <<
ny << "x" << nz << ", built in " << dt << " seconds\n";
+
+}
+
+void GriddedGroup::intersect( const RenderContext &context, RayPacket &rays
) const
+{
+
+ rays.computeInverseDirections();
+ for(int i=0; i<rays.getSize(); i++) {
+ RayPacket::Element& e = rays.get(i);
+
+
+ // Step 2
+ Vector v1 = (min-e.ray.origin())*e.inverseDirection;
+ Vector v2 = (max-e.ray.origin())*e.inverseDirection;
+ Vector vmin = Min(v1, v2);
+ Vector vmax = Max(v1, v2);
+ double tnear = vmin.maxComponent();
+ double tfar = vmax.minComponent();
+ if(tnear >= tfar)
+ return;
+ if(tfar < 1.e-6)
+ return;
+ if(tnear < 0)
+ tnear = 0;
+
+ // Step 3
+ Point p = e.ray.origin() + tnear * e.ray.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();
+ int dix = sign.x()>0?1:-1;
+ int stopx = sign.x()>0?cells.getNx():-1;
+ int diy = sign.y()>0?1:-1;
+ int stopy = sign.y()>0?cells.getNy():-1;
+ int diz = sign.z()>0?1:-1;
+ 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());
+
+ // Step 6
+ double far_x;
+ if(sign.x()>0)
+ far_x = (Lx+1)*cellsize.x() + min.x();
+ else
+ far_x = Lx*cellsize.x() + min.x();
+ double 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;
+ 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();
+
+ // Step 8
+ while(tnear < e.hitInfo.minT()){
+
+ int idx = cells.getIndex(Lx, Ly, Lz);
+ int l = cells[idx];
+ int e = cells[idx+1];
+ for(;l < e; l++){
+ const Object* obj = lists[l];
+ RayPacket subpacket(rays, i, i+1);
+ obj->intersect(context, subpacket);
+ }
+ // Step 11
+ if(tnext_x < tnext_y && tnext_x < tnext_z){
+ Lx += dix;
+ if(Lx == stopx)
+ break;
+ tnear = tnext_x;
+ tnext_x += dtdx;
+ } else if(tnext_y < tnext_z){
+ Ly += diy;
+ if(Ly == stopy)
+ break;
+ tnear = tnext_y;
+ tnext_y += dtdy;
+ } else {
+ Lz += diz;
+ if(Lz == stopz)
+ break;
+ tnear = tnext_z;
+ tnext_z += dtdz;
+ }
+ }
+ }
+}
Added: trunk/Model/Groups/GriddedGroup.h
==============================================================================
--- (empty file)
+++ trunk/Model/Groups/GriddedGroup.h Tue Aug 2 15:34:04 2005
@@ -0,0 +1,152 @@
+
+#ifndef Manta_Model_GriddedGroup_h
+#define Manta_Model_GriddedGroup_h
+
+#include <vector>
+#include <Model/Groups/Group.h>
+#include <Core/Geometry/PointVector.h>
+#include <Interface/RayPacket.h>
+
+namespace Manta {
+
+ template<typename T>
+ class Array3 {
+ public:
+ Array3() {
+ nx = ny = nz = extra = 0;
+ xidx = yidx = zidx = 0;
+ data = 0;
+ }
+ Array3(int nx, int ny, int nz, int extra = 0) {
+ xidx = yidx = zidx = 0;
+ data = 0;
+ resize(nx, ny, nz, extra);
+ }
+ ~Array3() {
+ resize(0, 0, 0);
+ }
+
+ void resize(int newnx, int newny, int newnz, int newextra = 0) {
+ if(xidx)
+ delete[] xidx;
+ if(yidx)
+ delete[] yidx;
+ if(zidx)
+ delete[] zidx;
+ if(data)
+ delete[] data;
+ nx = newnx; ny = newny; nz = newnz; extra = newextra;
+ int total = nx*ny*nz+extra;
+ if(total != 0){
+ data = new T[total];
+ allocateAndInitializeStride(xidx, nx, 1);
+ allocateAndInitializeStride(yidx, ny, nx);
+ allocateAndInitializeStride(zidx, nz, nx*ny);
+ } else {
+ xidx = yidx = zidx = 0;
+ data = 0;
+ }
+ }
+
+ void resizeZMajor(int newnx, int newny, int newnz, int newextra = 0) {
+ if(xidx)
+ delete[] xidx;
+ if(yidx)
+ delete[] yidx;
+ if(zidx)
+ delete[] zidx;
+ if(data)
+ delete[] data;
+ nx = newnx; ny = newny; nz = newnz; extra = newextra;
+ int total = nx*ny*nz+extra;
+ if(total != 0){
+ data = new T[total];
+ allocateAndInitializeStride(xidx, nx, nz*ny);
+ allocateAndInitializeStride(yidx, ny, nz);
+ allocateAndInitializeStride(zidx, nz, 1);
+ } else {
+ xidx = yidx = zidx = 0;
+ data = 0;
+ }
+ }
+
+ void initialize(const T& value) {
+ int total = nx*ny*nz+extra;
+ for(int i=0;i<total;i++)
+ data[i] = value;
+ }
+
+ T& operator()(int x, int y, int z) {
+ return data[xidx[x] + yidx[y] + zidx[z]];
+ }
+ const T& operator()(int x, int y, int z) const {
+ return data[xidx[x] + yidx[y] + zidx[z]];
+ }
+ int getIndex(int x, int y, int z) const {
+ return xidx[x] + yidx[y] + zidx[z];
+ }
+ T& operator[](int idx) {
+ return data[idx];
+ }
+ const T& operator[](int idx) const {
+ return data[idx];
+ }
+
+ int getNx() const {
+ return nx;
+ }
+ int getNy() const {
+ return ny;
+ }
+ int getNz() const {
+ return nz;
+ }
+
+
+ private:
+ Array3(const Array3&);
+ Array3& operator=(const Array3&);
+
+ int nx, ny, nz, extra;
+ int* xidx;
+ int* yidx;
+ int* zidx;
+ T* data;
+
+ void allocateAndInitializeStride(int*& idx, int num, int stride) {
+ idx = new int[num];
+ for(int i=0;i<num;i++)
+ idx[i] = stride*i;
+ }
+ };
+
+ class GriddedGroup : public Group {
+ public:
+ GriddedGroup( std::vector< string > const &args );
+ GriddedGroup();
+ virtual ~GriddedGroup();
+
+ virtual void preprocess( PreprocessContext const & );
+ virtual void intersect( RenderContext const &context, RayPacket &rays )
const;
+ static Group* create( vector< string > const &args );
+
+ private:
+ GriddedGroup(const GriddedGroup&);
+ GriddedGroup& operator=(const GriddedGroup&);
+
+ double cellfactor;
+ Point min, max;
+ Vector diag;
+ Vector cellsize;
+ Vector inv_cellsize;
+ Array3<int> cells;
+ const Object** lists;
+
+ void transformToLattice(const BBox& box,
+ int& sx, int& sy, int& sz, int& ex, int& ey, int&
ez) const;
+
+ };
+
+}
+
+#endif
Modified: trunk/Model/Groups/sub.mk
==============================================================================
--- trunk/Model/Groups/sub.mk (original)
+++ trunk/Model/Groups/sub.mk Tue Aug 2 15:34:04 2005
@@ -6,6 +6,7 @@
SRCS += \
$(SRCDIR)/BVH.cc \
+ $(SRCDIR)/GriddedGroup.cc \
$(SRCDIR)/Group.cc
PSELIBS := Packages/Manta/Core/Exceptions Packages/Manta/Core/Util \
Modified: trunk/Model/Primitives/SuperEllipsoid.cc
==============================================================================
--- trunk/Model/Primitives/SuperEllipsoid.cc (original)
+++ trunk/Model/Primitives/SuperEllipsoid.cc Tue Aug 2 15:34:04 2005
@@ -1,5 +1,3 @@
-#include <iostream>
-
#include <Model/Primitives/SuperEllipsoid.h>
#include <Interface/RayPacket.h>
#include <Core/Geometry/BBox.h>
@@ -83,7 +81,6 @@
// First check if the ray hits the bounding box and whether it could
// remotely produce a hit of interest.
- // TODO: Maybe factor this out into a common routine?
double t1 = ( -1.01 - e.ray.origin().x() ) * e.inverseDirection.x();
double t2 = ( 1.01 - e.ray.origin().x() ) * e.inverseDirection.x();
if ( t1 > t2 )
Modified: trunk/scenes/0.cc
==============================================================================
--- trunk/scenes/0.cc (original)
+++ trunk/scenes/0.cc Tue Aug 2 15:34:04 2005
@@ -9,6 +9,7 @@
#include <Model/AmbientLights/ArcAmbient.h>
#include <Model/Backgrounds/LinearBackground.h>
#include <Model/Groups/Group.h>
+#include <Model/Groups/GriddedGroup.h>
#include <Model/Lights/PointLight.h>
#include <Model/Materials/Lambertian.h>
#include <Model/Materials/MetalMaterial.h>
@@ -68,14 +69,14 @@
// Check if children should be generated
if(depth > 0){
depth--;
-
+
// Rotation matrix to new axis from +Z axis
AffineTransform mx;
mx.initWithIdentity();
mx.rotate(Vector(0,0,1), dir);
-
+
double scale = radius * (1+SCALE);
-
+
for(int n=0;n<9;n++){
Vector child_vec(mx * objset[n]);
Point child_pt(center+child_vec*scale);
@@ -96,13 +97,14 @@
group->add(new Parallelogram(matl, corner+z*2, x*2, y*2));
}
-static void make_obj(Group* world, int size)
+static void make_obj(Group* world, Group* group, int size)
{
Vector objset[9];
create_dirs(objset);
Material* matl0=new Lambertian(Color(RGBColor(.4,.4,.4)));
- create_objs(world, Point(0,0,.5), BV_RADIUS/2.0, Vector(0,0,1),
+ create_objs(group, Point(0,0,.5), BV_RADIUS/2.0, Vector(0,0,1),
size, objset, matl0);
+ world->add(group);
Vector diag1(1,1,0);
diag1.normalize();
@@ -114,7 +116,7 @@
Vector z(0,0,.4);
Point corner(-1.8,-.3,0);
make_box(world, matl1, corner, diag1, diag2, z);
-
+
Material* matl3=new MetalMaterial( Color(RGBColor(.7,.7,.7)));
world->add(new Sphere(matl3,
corner+diag1*1.25+diag2*.6+z*2+Vector(0,0,.6), .6));
double planesize=15;
@@ -129,13 +131,13 @@
world->add(obj1);
}
-extern "C"
+extern "C"
Scene* make_scene(const ReadContext& context, const vector<string>& args)
{
int scenesize=2;
double light_radius=0.8;
int argc = static_cast<int>(args.size());
- Group* world = 0;
+ Group* group = 0;
for(int i=0;i<argc;i++){
string arg = args[i];
if(arg == "-size"){
@@ -144,24 +146,28 @@
} else if(arg == "-light"){
if(!getDoubleArg(i, args, light_radius))
throw IllegalArgument("scene 0 -light", i, args);
- } else if(arg == "-bv"){
+ } else if(arg == "-group"){
string s;
if(!getStringArg(i, args, s))
- throw IllegalArgument("scene 0 -bv", i, args);
- world = context.rtrt_int->makeGroup(s);
+ throw IllegalArgument("scene 0 -group", i, args);
+ group = context.rtrt_int->makeGroup(s);
+ if ( group == 0 )
+ throw IllegalArgument("scene 0 -group", i, args);
} else {
cerr << "Valid options for scene 0:\n";
- cerr << " -size n - Sets depth of sphereflake\n";
- cerr << " -light r - Sets radius of light source for soft shadows\n";
+ cerr << " -size n - Sets depth of sphereflake\n";
+ cerr << " -light r - Sets radius of light source for soft
shadows\n";
+ cerr << " -group spec - Sets the group or acceleration structure to
use for the sphereflake\n";
throw IllegalArgument("scene 0", i, args);
}
}
- if(!world)
- world = new Group();
+ if(!group)
+ group = new Group();
+ Group* world = new Group();
NOT_FINISHED("scene 0");
- make_obj(world, scenesize);
+ make_obj(world, group, scenesize);
#if 0
Camera cam(Point(1.8,-5.53,1.25), Point(0.0,-.13,1.22),
Vector(0,0,1), 28.2);
@@ -170,13 +176,13 @@
Color bgcolor(RGB(0.1, 0.2, 0.45));
Color cdown(RGB(0.82, 0.62, 0.62));
Color cup(RGB(0.1, 0.3, 0.8));
-
+
rtrt::Plane groundplane ( Point(0, 0, 0), Vector(0, 0, 3) );
Scene* scene=new Scene(obj, cam,
bgcolor, cdown, cup, groundplane,
ambient_scale, Arc_Ambient);
-
+
scene->select_shadow_mode( Single_Soft_Shadow );
#endif
Scene* scene = new Scene();
- [MANTA] r464 - in trunk: Core/Geometry Engine/Control Model/Groups Model/Primitives scenes, aek, 08/02/2005
Archive powered by MHonArc 2.6.16.