00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __GU_PrimVolumeCache__
00020 #define __GU_PrimVolumeCache__
00021
00022 #include "GU_API.h"
00023
00024 #include <UT/UT_Vector3.h>
00025 #include <UT/UT_Vector4.h>
00026 #include <UT/UT_RefArray.h>
00027 #include <UT/UT_VoxelArray.h>
00028 #include <UT/UT_EnvControl.h>
00029 #include <UT/UT_ThreadedAlgorithm.h>
00030
00031 #include "GU_Detail.h"
00032 #include "GU_DisplayCache.h"
00033
00034 class UT_Ramp;
00035 class GEO_PrimVolume;
00036
00037 class GU_API GU_PrimVolumeCacheLight
00038 {
00039 public:
00040 bool operator==(const GU_PrimVolumeCacheLight &l) const
00041 {
00042
00043
00044 if (myIsInfinite &&
00045 myIsInfinite == l.myIsInfinite)
00046 return true;
00047 return (myOrg == l.myOrg) &&
00048 (myDir == l.myDir) &&
00049 (myCd == l.myCd) &&
00050 (myIsAmbient == l.myIsAmbient) &&
00051 (myIsInfinite == l.myIsInfinite) &&
00052 (myShadow == l.myShadow);
00053 }
00054
00055 void setOrg(const UT_Vector3 &org) { myOrg = org; }
00056 void setDir(const UT_Vector3 &dir) { myDir = dir; }
00057 void setCd(const UT_Vector3 &cd) { myCd = cd; }
00058 void setShadowIntensity(float shadow) { myShadow = shadow; }
00059 void setIsAmbient(bool isamb) { myIsAmbient = isamb; }
00060 void setIsInfinite(bool isinfinite) { myIsInfinite = isinfinite; }
00061
00062 const UT_Vector3 &getOrg() const { return myOrg; }
00063 const UT_Vector3 &getDir() const { return myDir; }
00064 const UT_Vector3 &getCd() const { return myCd; }
00065 float getShadow() const { return myShadow; }
00066
00067 bool isAmbient() const { return myIsAmbient; }
00068 bool isInfinite() const { return myIsInfinite; }
00069
00070 float getDistance(const UT_Vector3 &pos) const;
00071
00072 protected:
00073 UT_Vector3 myOrg, myDir;
00074 UT_Vector3 myCd;
00075 float myShadow;
00076 bool myIsAmbient, myIsInfinite;
00077 };
00078
00079
00080 class GU_PrimVolumeCacheParms;
00081 class GU_PrimVolume;
00082
00083 class GU_API GU_PrimVolumeTexture
00084 {
00085 public:
00086 GU_PrimVolumeTexture() {}
00087 virtual ~GU_PrimVolumeTexture() {}
00088
00089 virtual void refresh(const UT_VoxelArrayV4 *voxels) = 0;
00090 };
00091
00092 class GU_API GU_PrimVolumeCacheRamp
00093 {
00094 public:
00095 GU_PrimVolumeCacheRamp(UT_Ramp *ramp, bool periodic);
00096 ~GU_PrimVolumeCacheRamp();
00097
00098 void eval(float &rval, float val) const;
00099 void eval(UT_Vector4 &rval, float val) const;
00100
00101 protected:
00102 UT_Ramp *myRamp;
00103 bool myPeriodic;
00104 };
00105
00106 class GU_API GU_PrimVolumeCacheSampler
00107 {
00108 public:
00109 GU_PrimVolumeCacheSampler(const GEO_Detail *gdp, const GU_PrimVolume *vol);
00110 ~GU_PrimVolumeCacheSampler();
00111
00112 GU_PrimVolumeCacheRamp *buildRampFromAttribute(
00113 const GEO_Detail *gdp,
00114 const char *attribname) const;
00115 int findCollationIndex(const GEO_Detail *gdp,
00116 const GU_PrimVolume *vol) const;
00117 const GEO_PrimVolume *selectVolumeFromAttribute(
00118 const GEO_Detail *gdp,
00119 const char *attribname,
00120 int collateidx) const;
00121 void selectVolumesFromAttribute(
00122 const GEO_PrimVolume *vol[3],
00123 const GEO_Detail *gdp,
00124 const char *attribname,
00125 int collateidx) const;
00126 void getRangeFromAttribute(
00127 const GEO_Detail *gdp,
00128 const char *attribname,
00129 float &rmin, float &rscale) const;
00130 float getFloatFromAttribute(
00131 const GEO_Detail *gdp,
00132 const char *attribname,
00133 float def) const;
00134
00135 float getDensity(int x, int y, int z) const;
00136 UT_Vector4 getDiffuse(int x, int y, int z) const;
00137
00138 void getDensityProbe(UT_VoxelProbeF &probe) const;
00139 void getEmitProbe(UT_VoxelProbeF &probe) const;
00140 void getEmitCdProbe(UT_VoxelProbeV4 &probe) const;
00141 const UT_VoxelArrayF *getDensityArray() const;
00142
00143 const GEO_PrimVolume *densityField() const { return myDensityField; }
00144 void setDensityField(const GEO_PrimVolume *densityfield);
00145
00146 void hardenFields(const UT_VoxelArray<UT_Vector4> &refvol,
00147 const GEO_PrimVolume *vol);
00148
00149 UT_VoxelArrayReadHandleF hardenScalar(const UT_VoxelArrayV4 &refvol,
00150 const GEO_PrimVolume *vol,
00151 const GEO_PrimVolume *field,
00152 GU_PrimVolumeCacheRamp *ramp,
00153 float rmin, float rinvscale);
00154 UT_VoxelArrayReadHandleV4 hardenVector(const UT_VoxelArrayV4 &refvol,
00155 const GEO_PrimVolume *vol,
00156 const GEO_PrimVolume *field,
00157 GU_PrimVolumeCacheRamp *ramp,
00158 float rmin, float rinvscale);
00159 UT_VoxelArrayReadHandleV4 hardenVectorMulti(const UT_VoxelArrayV4 &refvol,
00160 const GEO_PrimVolume *vol,
00161 const GEO_PrimVolume *field[3],
00162 GU_PrimVolumeCacheRamp *ramp,
00163 float rmin, float rinvscale);
00164
00165 THREADED_METHOD6_CONST(GU_PrimVolumeCacheSampler,
00166 dst->numTiles() > 1,
00167 doHardenAligned,
00168 UT_VoxelArrayF *, dst,
00169 const UT_VoxelArrayF *, src,
00170 const UT_Matrix4 &, xform,
00171 GU_PrimVolumeCacheRamp *, ramp,
00172 float, rmin,
00173 float, rinvscale)
00174 void doHardenAlignedPartial(UT_VoxelArrayF *dst,
00175 const UT_VoxelArrayF *src,
00176 const UT_Matrix4 &xform,
00177 GU_PrimVolumeCacheRamp *ramp,
00178 float rmin, float rinvscale,
00179 const UT_JobInfo &info) const;
00180 THREADED_METHOD6_CONST(GU_PrimVolumeCacheSampler,
00181 dst->numTiles() > 1,
00182 doHardenUnaligned,
00183 UT_VoxelArrayF *, dst,
00184 const UT_VoxelArrayF *, src,
00185 const UT_Matrix4 &, xform,
00186 GU_PrimVolumeCacheRamp *, ramp,
00187 float, rmin,
00188 float, rinvscale)
00189 void doHardenUnalignedPartial(UT_VoxelArrayF *dst,
00190 const UT_VoxelArrayF *src,
00191 const UT_Matrix4 &xform,
00192 GU_PrimVolumeCacheRamp *ramp,
00193 float rmin, float rinvscale,
00194 const UT_JobInfo &info) const;
00195 THREADED_METHOD6_CONST(GU_PrimVolumeCacheSampler,
00196 dst->numTiles() > 1,
00197 doHardenVectorAligned,
00198 UT_VoxelArrayV4 *, dst,
00199 const UT_VoxelArrayF *, src,
00200 const UT_Matrix4 &, xform,
00201 GU_PrimVolumeCacheRamp *, ramp,
00202 float, rmin,
00203 float, rinvscale)
00204 void doHardenVectorAlignedPartial(UT_VoxelArrayV4 *dst,
00205 const UT_VoxelArrayF *src,
00206 const UT_Matrix4 &xform,
00207 GU_PrimVolumeCacheRamp *ramp,
00208 float rmin, float rinvscale,
00209 const UT_JobInfo &info) const;
00210 THREADED_METHOD6_CONST(GU_PrimVolumeCacheSampler,
00211 dst->numTiles() > 1,
00212 doHardenVectorUnaligned,
00213 UT_VoxelArrayV4 *, dst,
00214 const UT_VoxelArrayF *, src,
00215 const UT_Matrix4 &, xform,
00216 GU_PrimVolumeCacheRamp *, ramp,
00217 float, rmin,
00218 float, rinvscale)
00219 void doHardenVectorUnalignedPartial(UT_VoxelArrayV4 *dst,
00220 const UT_VoxelArrayF *src,
00221 const UT_Matrix4 &xform,
00222 GU_PrimVolumeCacheRamp *ramp,
00223 float rmin, float rinvscale,
00224 const UT_JobInfo &info) const;
00225 THREADED_METHOD7_CONST(GU_PrimVolumeCacheSampler,
00226 dst->numTiles() > 1,
00227 doHardenVectorAxisAligned,
00228 UT_VoxelArrayV4 *, dst,
00229 const UT_VoxelArrayF *, src,
00230 int, axis,
00231 const UT_Matrix4 &, xform,
00232 GU_PrimVolumeCacheRamp *, ramp,
00233 float, rmin,
00234 float, rinvscale)
00235 void doHardenVectorAxisAlignedPartial(UT_VoxelArrayV4 *dst,
00236 const UT_VoxelArrayF *src,
00237 int axis,
00238 const UT_Matrix4 &xform,
00239 GU_PrimVolumeCacheRamp *ramp,
00240 float rmin, float rinvscale,
00241 const UT_JobInfo &info) const;
00242 THREADED_METHOD7_CONST(GU_PrimVolumeCacheSampler,
00243 dst->numTiles() > 1,
00244 doHardenVectorAxisUnaligned,
00245 UT_VoxelArrayV4 *, dst,
00246 const UT_VoxelArrayF *, src,
00247 int, axis,
00248 const UT_Matrix4 &, xform,
00249 GU_PrimVolumeCacheRamp *, ramp,
00250 float, rmin,
00251 float, rinvscale)
00252 void doHardenVectorAxisUnalignedPartial(UT_VoxelArrayV4 *dst,
00253 const UT_VoxelArrayF *src,
00254 int axis,
00255 const UT_Matrix4 &xform,
00256 GU_PrimVolumeCacheRamp *ramp,
00257 float rmin, float rinvscale,
00258 const UT_JobInfo &info) const;
00259
00260 THREADED_METHOD2_CONST(GU_PrimVolumeCacheSampler,
00261 dst->numTiles() > 1,
00262 applyAmbientLight,
00263 UT_VoxelArrayV4 *, dst,
00264 const UT_Vector4, cd)
00265 void applyAmbientLightPartial(UT_VoxelArrayV4 *dst,
00266 const UT_Vector4 &cd,
00267 const UT_JobInfo &info) const;
00268
00269 bool hasEmission() const;
00270 float getEmissionScale() const { return myEmissionScale; }
00271 float getShadowScale() const { return myShadowScale; }
00272
00273 protected:
00274 float myDensityMin, myDensityInvRange;
00275 const GEO_PrimVolume *myDensityField;
00276 GU_PrimVolumeCacheRamp *myDensityRamp;
00277 float myShadowScale;
00278
00279
00280 float myDiffuseMin, myDiffuseInvRange;
00281 const GEO_PrimVolume *myDiffuseField[3];
00282 GU_PrimVolumeCacheRamp *myDiffuseRamp;
00283
00284 float myEmissionScale;
00285 float myEmissionMin, myEmissionInvRange;
00286 const GEO_PrimVolume *myEmissionField;
00287 GU_PrimVolumeCacheRamp *myEmissionRamp;
00288
00289
00290 float myEmissionCdMin, myEmissionCdInvRange;
00291 const GEO_PrimVolume *myEmissionCdField[3];
00292 GU_PrimVolumeCacheRamp *myEmissionCdRamp;
00293
00294 UT_VoxelArrayReadHandleF myDensityHandle;
00295 UT_VoxelArrayReadHandleV4 myDiffuseHandle;
00296 UT_VoxelArrayReadHandleF myEmissionHandle;
00297 UT_VoxelArrayReadHandleV4 myEmissionCdHandle;
00298 };
00299
00300 class GU_API GU_PrimVolumeCache : public GU_DisplayCache
00301 {
00302 public:
00303 GU_PrimVolumeCache(void);
00304 virtual ~GU_PrimVolumeCache(void);
00305
00306
00307 int refresh(GU_PrimVolumeCacheParms &parms);
00308
00309
00310 UT_VoxelArrayV4 *getShadedVoxels() const { return myVoxels; }
00311 GU_PrimVolumeTexture *getTexture() const { return myTexture; }
00312 void setTexture(GU_PrimVolumeTexture *tex)
00313 { myTexture = tex; }
00314
00315 GU_Detail *getIsoSurface() const { return myIsoSurf; }
00316
00317 UT_Vector3 getIsoCd() const { return myIsoCd; }
00318
00319
00320 protected:
00321 void lightVoxelsFromLight(const GU_PrimVolumeCacheSampler &sampler,
00322 const GU_PrimVolumeCacheLight &light,
00323 const UT_Vector3 &cd,
00324 float shadowdensity);
00325
00326 void rainbowVoxels(const GU_PrimVolumeCacheSampler &sampler);
00327
00328 THREADED_METHOD2(GU_PrimVolumeCache, myVoxels->numTiles() > 1,
00329 computeAlphaVoxels,
00330 const GU_PrimVolumeCacheSampler &, sampler,
00331 float, lightdensity)
00332 void computeAlphaVoxelsPartial(
00333 const GU_PrimVolumeCacheSampler &sampler,
00334 float lightdensity,
00335 const UT_JobInfo &info);
00336
00337
00338
00339 int getMaxRes(GU_PrimVolumeCacheParms &parms,
00340 int axis) const;
00341
00342
00343
00344 bool indexToPos(int x, int y, int z, UT_Vector3 &pos) const;
00345 bool posToIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
00346
00347 UT_VoxelArrayV4 *myVoxels;
00348 UT_RefArray<GU_PrimVolumeCacheLight> myLightList;
00349 GU_PrimVolumeTexture *myTexture;
00350 GU_Detail *myIsoSurf;
00351 float myOldLOD;
00352 UT_Vector3 myIsoCd;
00353
00354 UT_Vector3 myCacheRes;
00355 UT_Matrix4 myCacheXform;
00356 UT_Matrix4 myCacheIXform;
00357 const UT_VoxelArrayV4 *myCacheVolume;
00358 };
00359
00360 class GU_API GU_PrimVolumeCacheParms : public GU_CacheParms
00361 {
00362 public:
00363 GU_PrimVolumeCacheParms(void)
00364 : myMaxResW(0), myMaxResH(0), myMaxResD(0),
00365 myCachedFlag(true)
00366 {}
00367 virtual ~GU_PrimVolumeCacheParms(void) {}
00368
00369 void setVolume(const GU_PrimVolume *vol) { myVolume = vol; }
00370 const GU_PrimVolume *getVolume() const { return myVolume; }
00371
00372 void setLights(UT_RefArray<GU_PrimVolumeCacheLight> &lightlist)
00373 { myLightList = lightlist; }
00374 const UT_RefArray<GU_PrimVolumeCacheLight> &getLights() const
00375 { return myLightList; }
00376
00377 void setMaxResolution(int w, int h, int d)
00378 { myMaxResW = w; myMaxResH = h; myMaxResD = d; }
00379 void getMaxResolution(int &w, int &h, int &d) const
00380 { w = myMaxResW; h = myMaxResH; d = myMaxResD; }
00381
00382 void setCached(bool b) { myCachedFlag = b; }
00383 bool isCached() const { return myCachedFlag; }
00384 private:
00385 UT_RefArray<GU_PrimVolumeCacheLight> myLightList;
00386 const GU_PrimVolume *myVolume;
00387 int myMaxResW;
00388 int myMaxResH;
00389 int myMaxResD;
00390 bool myCachedFlag;
00391 };
00392
00393 #endif
00394