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 #include <UT/UT_DSOVersion.h>
00029
00030 #include <RE/RE_Render.h>
00031
00032 #include <GEO/GEO_Primitive.h>
00033 #include <GEO/GEO_PrimPoly.h>
00034
00035 #include <GU/GU_Detail.h>
00036 #include <GU/GU_PrimGroupClosure.h>
00037
00038 #include <GR/GR_Detail.h>
00039 #include <GR/GR_RenderHook.h>
00040 #include <GR/GR_RenderTable.h>
00041
00042
00043 namespace HDK_Sample {
00044 class GR_SimpleNoise : public GR_RenderHook
00045 {
00046 public:
00047 GR_SimpleNoise() {}
00048 virtual ~GR_SimpleNoise() {}
00049
00050 int getWireMask(GU_Detail * ,
00051 const GR_DisplayOption * ) const
00052 {
00053
00054
00055 return ~GEOPRIMPOLY;
00056 }
00057
00058 virtual void renderWire(GU_Detail *gdp,
00059 RE_Render &ren,
00060 const GR_AttribOffset &ptinfo,
00061 const GR_DisplayOption *dopt,
00062 float lod,
00063 const GU_PrimGroupClosure *hidden_geometry);
00064
00065 int getShadedMask(GU_Detail * ,
00066 const GR_DisplayOption * ) const
00067 {
00068
00069
00070 return ~GEOPRIMPOLY;
00071 }
00072
00073 virtual void renderShaded(GU_Detail *gdp,
00074 RE_Render &ren,
00075 const GR_AttribOffset &ptinfo,
00076 const GR_DisplayOption *dopt,
00077 float lod,
00078 const GU_PrimGroupClosure *hidden_geometry);
00079
00080 virtual const char *getName() const { return "GR_SimpleNoise"; }
00081
00082 protected:
00083
00084 void fillLineArray(UT_Vector3 *line, int step, unsigned seed);
00085
00086
00087 void fillReversedLineArray(UT_Vector3 *line, int step,
00088 GEO_Point *pt1, GEO_Point *pt2);
00089
00090
00091 void renderLine(RE_Render &ren,
00092 GEO_Point *pt1, GEO_Point *pt2,
00093 float lod);
00094
00095
00096 void renderQuad(RE_Render &ren, const UT_Vector3 &nml,
00097 UT_Vector3 *left, UT_Vector3 *right,
00098 UT_Vector3 *top, UT_Vector3 *bot,
00099 int step);
00100 };
00101 }
00102 using namespace HDK_Sample;
00103
00104 void
00105 GR_SimpleNoise::fillLineArray(UT_Vector3 *line, int step, unsigned seed)
00106 {
00107
00108 UT_Vector3 mid;
00109 float dist;
00110
00111 if (step < 2)
00112 return;
00113
00114 dist = distance3d(line[0], line[step]);
00115
00116 dist *= 0.1;
00117
00118 mid = line[0];
00119 mid += line[step];
00120 mid /= 2.0f;
00121
00122 mid.x() += dist * (UTrandom(seed) - 0.5f);
00123 mid.y() += dist * (UTrandom(seed) - 0.5f);
00124 mid.z() += dist * (UTrandom(seed) - 0.5f);
00125
00126 step >>= 1;
00127 line[step] = mid;
00128
00129 if (step > 1)
00130 {
00131 fillLineArray(line, step, seed);
00132 fillLineArray(&line[step], step, seed + step);
00133 }
00134 }
00135
00136 void
00137 GR_SimpleNoise::fillReversedLineArray(UT_Vector3 *line, int step,
00138 GEO_Point *pt1, GEO_Point *pt2)
00139 {
00140 int n1, n2, i;
00141 unsigned seed;
00142 GEO_Point *tmp;
00143 bool reverse = false;
00144 UT_Vector3 v3;
00145
00146 n1 = pt1->getNum();
00147 n2 = pt2->getNum();
00148
00149 if (n1 > n2)
00150 {
00151 reverse = true;
00152 tmp = pt1;
00153 pt1 = pt2;
00154 pt2 = tmp;
00155
00156 n1 = pt1->getNum();
00157 n2 = pt2->getNum();
00158 }
00159
00160 line[0] = pt1->getPos();
00161 line[step] = pt2->getPos();
00162
00163
00164 seed = UTwang_inthash(n1) ^ n2;
00165
00166 fillLineArray(line, step, seed);
00167
00168
00169 if (reverse)
00170 {
00171 for (i = 0; i < step / 2; i++)
00172 {
00173 v3 = line[i];
00174 line[i] = line[step - i];
00175 line[step - i] = v3;
00176 }
00177 }
00178
00179 }
00180
00181 void
00182 GR_SimpleNoise::renderLine(RE_Render &ren,
00183 GEO_Point *pt1, GEO_Point *pt2,
00184 float lod)
00185 {
00186
00187 if (pt1->getNum() > pt2->getNum())
00188 {
00189 GR_SimpleNoise::renderLine(ren, pt2, pt1, lod);
00190 return;
00191 }
00192
00193 unsigned seed;
00194
00195 UT_Vector3 linearray[33];
00196 int i;
00197 int step;
00198
00199 step = (int)UTrint(lod * 2);
00200 if (step > 5)
00201 step = 5;
00202 step = 1 << step;
00203
00204 linearray[0] = pt1->getPos();
00205 linearray[step] = pt2->getPos();
00206
00207 seed = UTwang_inthash(pt1->getNum()) ^ pt2->getNum();
00208
00209 fillLineArray(linearray, step, seed);
00210
00211 ren.beginLine();
00212
00213 for (i = 0; i <= step; i++)
00214 {
00215 ren.vertex3DW(linearray[i].x(), linearray[i].y(), linearray[i].z());
00216 }
00217
00218 ren.endLine();
00219 }
00220
00221 void
00222 GR_SimpleNoise::renderQuad(RE_Render &ren, const UT_Vector3 &nml,
00223 UT_Vector3 *left, UT_Vector3 *right,
00224 UT_Vector3 *top, UT_Vector3 *bot,
00225 int step)
00226 {
00227 int i, j;
00228 float u, v, ustep, vstep, mixfactor;
00229 float n[3];
00230
00231 n[0] = -nml.x();
00232 n[1] = -nml.y();
00233 n[2] = -nml.z();
00234
00235
00236 UT_Vector3 lr, tb;
00237 UT_Vector3 v3;
00238
00239 ustep = vstep = 1.0f / (float) step;
00240
00241 u = 0.0f;
00242 for (i = 0; i < step; i++)
00243 {
00244 ren.beginQuadStrip();
00245
00246 v = 0.0f;
00247 for (j = 0; j <= step; j++)
00248 {
00249 tb = bot[i] * (1.0f - v) + top[i] * v;
00250 lr = left[j] * (1.0f - u) + right[j] * u;
00251
00252
00253
00254 if (fabs(u - 0.5f) > fabs(v - 0.5f))
00255 {
00256
00257 mixfactor = fabs(u - 0.5f) * 2;
00258 }
00259 else
00260 {
00261 mixfactor = 1.0f - fabs(v - 0.5f) * 2;
00262 }
00263
00264 v3 = tb * (1.0f - mixfactor) + lr * mixfactor;
00265
00266 ren.n3DW(n);
00267 ren.vertex3DW(v3.x(), v3.y(), v3.z());
00268
00269 tb = bot[i+1] * (1.0f - v) + top[i+1] * v;
00270 lr = left[j] * (1.0f - u - ustep) + right[j] * (u + ustep);
00271
00272 if (fabs(u + ustep - 0.5f) > fabs(v - 0.5f))
00273 {
00274
00275 mixfactor = fabs(u + ustep - 0.5f) * 2;
00276 }
00277 else
00278 {
00279 mixfactor = 1.0f - fabs(v - 0.5f) * 2;
00280 }
00281 v3 = tb * (1.0f - mixfactor) + lr * mixfactor;
00282
00283 ren.n3DW(n);
00284 ren.vertex3DW(v3.x(), v3.y(), v3.z());
00285
00286 v += vstep;
00287 }
00288
00289 ren.endQuadStrip();
00290
00291 u += ustep;
00292 }
00293 }
00294
00295 void
00296 GR_SimpleNoise::renderWire(GU_Detail *gdp,
00297 RE_Render &ren,
00298 const GR_AttribOffset & ,
00299 const GR_DisplayOption * ,
00300 float lod,
00301 const GU_PrimGroupClosure *hidden_geometry)
00302 {
00303 int i, nprim, nvtx, j, lj;
00304 GEO_Primitive *prim;
00305
00306 nprim = gdp->primitives().entries();
00307 for (i = 0; i < nprim; i++)
00308 {
00309 prim = gdp->primitives()(i);
00310
00311
00312 if (hidden_geometry && hidden_geometry->containsPrim(prim))
00313 continue;
00314
00315
00316 if (!(prim->getPrimitiveId() & GEOPRIMPOLY))
00317 continue;
00318
00319 nvtx = prim->getVertexCount();
00320 if (((GEO_PrimPoly *)prim)->isClosed())
00321 {
00322 j = 0;
00323 lj = nvtx-1;
00324 }
00325 else
00326 {
00327 j = 1;
00328 lj = 0;
00329 }
00330 for (; j < nvtx; j++)
00331 {
00332 renderLine(ren,
00333 prim->getVertex(lj).getPt(),
00334 prim->getVertex(j).getPt(),
00335 lod);
00336 lj = j;
00337 }
00338 }
00339 }
00340
00341 void
00342 GR_SimpleNoise::renderShaded(GU_Detail *gdp,
00343 RE_Render &ren,
00344 const GR_AttribOffset & ,
00345 const GR_DisplayOption * ,
00346 float lod,
00347 const GU_PrimGroupClosure *hidden_geometry)
00348 {
00349 int i, nprim, nvtx;
00350 GEO_Primitive *prim;
00351
00352 nprim = gdp->primitives().entries();
00353 for (i = 0; i < nprim; i++)
00354 {
00355 prim = gdp->primitives()(i);
00356
00357
00358 if (hidden_geometry && hidden_geometry->containsPrim(prim))
00359 continue;
00360
00361
00362 if (!(prim->getPrimitiveId() & GEOPRIMPOLY))
00363 continue;
00364
00365 nvtx = prim->getVertexCount();
00366
00367 if (nvtx != 4 ||
00368 !((GEO_PrimPoly *)prim)->isClosed())
00369 {
00370 continue;
00371 }
00372
00373 UT_Vector3 top[33], bot[33], left[33], right[33];
00374 int step;
00375 UT_Vector3 nml;
00376
00377 nml = ((GEO_PrimPoly *)prim)->computeNormal();
00378
00379 step = (int)UTrint(lod * 2);
00380 if (step > 5)
00381 step = 5;
00382 step = 1 << step;
00383
00384 fillReversedLineArray(bot, step,
00385 prim->getVertex(0).getPt(),
00386 prim->getVertex(1).getPt());
00387 fillReversedLineArray(top, step,
00388 prim->getVertex(3).getPt(),
00389 prim->getVertex(2).getPt());
00390 fillReversedLineArray(left, step,
00391 prim->getVertex(0).getPt(),
00392 prim->getVertex(3).getPt());
00393 fillReversedLineArray(right, step,
00394 prim->getVertex(1).getPt(),
00395 prim->getVertex(2).getPt());
00396
00397 renderQuad(ren, nml, left, right, top, bot, step);
00398 }
00399 }
00400
00401 void
00402 newRenderHook(GR_RenderTable *table)
00403 {
00404 GR_SimpleNoise *hook = new GR_SimpleNoise;
00405
00406 table->addHook(hook);
00407 }