00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "VRAY_DemoMountain.h"
00030 #include <GEO/GEO_AttributeHandle.h>
00031 #include <GU/GU_Detail.h>
00032 #include <GU/GU_PrimPoly.h>
00033
00034 using namespace HDK_Sample;
00035
00036 #define MAX_SPLITS 8
00037
00038 #define UT_DEBUG 1
00039 #include <UT/UT_Counter.h>
00040 static UT_Counter theCount("Mountains");
00041 static UT_Counter theTotal("TotalMountains");
00042
00043 static VRAY_ProceduralArg theArgs[] = {
00044 VRAY_ProceduralArg("p0", "real", "-1 -1 0"),
00045 VRAY_ProceduralArg("p1", "real", " 1 -1 0"),
00046 VRAY_ProceduralArg("p2", "real", " 0 1 0"),
00047 VRAY_ProceduralArg()
00048 };
00049
00050 VRAY_Procedural *
00051 allocProcedural(const char *)
00052 {
00053 return new VRAY_DemoMountain();
00054 }
00055
00056 const VRAY_ProceduralArg *
00057 getProceduralArgs(const char *)
00058 {
00059 return theArgs;
00060 }
00061
00062 VRAY_DemoMountain::VRAY_DemoMountain(int splits)
00063 : mySplits(splits)
00064 {
00065 theCount++;
00066 theTotal++;
00067 }
00068
00069 VRAY_DemoMountain::~VRAY_DemoMountain()
00070 {
00071 theCount--;
00072 }
00073
00074 const char *
00075 VRAY_DemoMountain::getClassName()
00076 {
00077 return "VRAY_DemoMountain";
00078 }
00079
00080 int
00081 VRAY_DemoMountain::initialize(const UT_BoundingBox *)
00082 {
00083 uint seed = 0xbabecafe;
00084
00085 myP[0].assign(-1, -1, 0, seed);
00086 SYSfastRandom(seed);
00087 myP[1].assign( 1, -1, 0, seed);
00088 SYSfastRandom(seed);
00089 myP[2].assign( 0, -1, 0, seed);
00090 mySplits = 1;
00091
00092
00093 import("p0", myP[0].pos.data(), 3);
00094 import("p1", myP[1].pos.data(), 3);
00095 import("p2", myP[2].pos.data(), 3);
00096 return 1;
00097 }
00098
00099 void
00100 VRAY_DemoMountain::computeBounds(UT_BoundingBox &box, bool include_displace)
00101 {
00102 box.initBounds(myP[0].pos);
00103 box.enlargeBounds(myP[1].pos);
00104 box.enlargeBounds(myP[2].pos);
00105 if (include_displace)
00106 {
00107 fpreal bounds = 0.5 / (fpreal)mySplits;
00108 box.enlargeBounds(0, bounds);
00109 }
00110 }
00111
00112
00113 void
00114 VRAY_DemoMountain::getBoundingBox(UT_BoundingBox &box)
00115 {
00116 computeBounds(box, true);
00117 fpreal bounds = 0.5 / (fpreal)mySplits;
00118 box.initBounds(myP[0].pos);
00119 box.enlargeBounds(myP[1].pos);
00120 box.enlargeBounds(myP[2].pos);
00121 box.enlargeBounds(0, bounds);
00122 }
00123
00124 void
00125 VRAY_DemoMountain::render()
00126 {
00127 fpreal lod;
00128 UT_BoundingBox box;
00129
00130
00131
00132
00133
00134
00135 computeBounds(box, false);
00136 lod = getLevelOfDetail(box);
00137
00138 if (lod < 6 || mySplits > MAX_SPLITS)
00139 {
00140
00141 fractalRender();
00142 }
00143 else
00144 {
00145
00146 fractalSplit();
00147 }
00148 }
00149
00150 static void
00151 edgeSplit(FractalPoint &P, const FractalPoint &p0, const FractalPoint &p1,
00152 fpreal scale)
00153 {
00154 uint seed;
00155 fpreal disp;
00156
00157 seed = (p0.seed + p1.seed)/2;
00158 disp = SYSfastRandomZero(seed)*scale;
00159 P.seed = seed;
00160 P.pos = (p0.pos + p1.pos) * .5;
00161 P.pos(2) += 0.25 * disp * distance3d(p0.pos, p1.pos);
00162 }
00163
00164 void
00165 VRAY_DemoMountain::fractalSplit()
00166 {
00167 VRAY_DemoMountain *kids[4];
00168 int i;
00169 fpreal scale;
00170
00171 scale = 1.0 / (fpreal)mySplits;
00172 for (i = 0; i < 4; i++)
00173 kids[i] = new VRAY_DemoMountain(mySplits+1);
00174
00175 for (i = 0; i < 3; i++)
00176 {
00177 kids[i]->myP[0] = myP[i];
00178 edgeSplit(kids[i]->myP[1], myP[i], myP[(i+1)%3], scale);
00179 }
00180 for (i = 0; i < 3; i++)
00181 {
00182 kids[3]->myP[i] = kids[(i+1)%3]->myP[2] = kids[i]->myP[1];
00183 }
00184 for (i = 0; i < 4; i++)
00185 {
00186 openProceduralObject();
00187 addProcedural(kids[i]);
00188 closeObject();
00189 }
00190 }
00191
00192 void
00193 VRAY_DemoMountain::fractalRender()
00194 {
00195
00196 GU_Detail *gdp;
00197 GU_PrimPoly *poly;
00198 int i;
00199
00200 gdp = allocateGeometry();
00201 poly = GU_PrimPoly::build(gdp, 3);
00202
00203 #if 0
00204
00205 UT_Vector3 clr;
00206 uint seed = myP[0].seed + myP[1].seed + myP[2].seed;
00207 clr.x() = SYSfastRandom(seed);
00208 clr.y() = SYSfastRandom(seed);
00209 clr.z() = SYSfastRandom(seed);
00210 gdp->addDiffuseAttribute(GEO_PRIMITIVE_DICT);
00211 GEO_AttributeHandle Cd = gdp->getPrimAttribute("Cd");
00212 Cd.setElement(poly);
00213 Cd.setV3(clr);
00214 #endif
00215
00216 for (i = 0; i < 3; i++)
00217 {
00218 poly->getVertex(i).getPos().assign(myP[i].pos.x(),
00219 myP[i].pos.y(),
00220 myP[i].pos.z(),
00221 1);
00222 }
00223
00224
00225 openGeometryObject();
00226 addGeometry(gdp, 0);
00227 closeObject();
00228 }