00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "lux.h"
00025 #include "texture.h"
00026 #include "paramset.h"
00027 #include "error.h"
00028 #include "blender_texlib.h"
00029
00030 namespace lux {
00031 template <class T>
00032
00033 class BlenderMusgraveTexture3D : public Texture<T> {
00034 public:
00035
00036
00037 virtual ~BlenderMusgraveTexture3D() {
00038 delete mapping;
00039 }
00040
00041 BlenderMusgraveTexture3D(
00042 boost::shared_ptr<Texture<T> > c1,
00043 boost::shared_ptr<Texture<T> > c2,
00044 float mg_H,
00045 float mg_lacunarity,
00046 float mg_octaves,
00047 float mg_gain,
00048 float mg_offset,
00049 float noiseSize,
00050 float ns_outscale,
00051 short sType,
00052 short noiseBasis,
00053 float bright,
00054 float contrast,
00055 TextureMapping3D *map) : mapping(map) {
00056 tex.type = TEX_MUSGRAVE;
00057
00058 tex.mg_H = mg_H;
00059 tex.mg_lacunarity = mg_lacunarity;
00060 tex.mg_octaves = mg_octaves;
00061 tex.mg_gain = mg_gain;
00062 tex.mg_offset = mg_offset;
00063
00064 tex.noisesize = noiseSize;
00065 tex.ns_outscale = ns_outscale;
00066 tex.stype = sType;
00067 tex.noisebasis = noiseBasis;
00068
00069 tex.bright = bright;
00070 tex.contrast = contrast;
00071 tex1 = c1;
00072 tex2 = c2;
00073 }
00074
00075 virtual T Evaluate(const TsPack *tspack, const DifferentialGeometry &dg) const {
00076 Vector dpdx, dpdy;
00077 Point P = mapping->Map(dg, &dpdx, &dpdy);
00078
00079 blender::TexResult texres;
00080 int resultType = multitex(&tex, &P.x, &texres);
00081
00082 if(resultType & TEX_RGB)
00083 texres.tin = (0.35 * texres.tr + 0.45 * texres.tg
00084 + 0.2 * texres.tb);
00085 else
00086 texres.tr = texres.tg = texres.tb = texres.tin;
00087
00088 T t1 = tex1->Evaluate(tspack, dg), t2 = tex2->Evaluate(tspack, dg);
00089 return (1.f - texres.tin) * t1 + texres.tin * t2;
00090 }
00091 virtual void SetPower(float power, float area) {
00092
00093 tex1->SetPower(power, area);
00094 tex2->SetPower(power, area);
00095 }
00096 virtual void SetIlluminant() {
00097
00098 tex1->SetIlluminant();
00099 tex2->SetIlluminant();
00100 }
00101 static Texture<float> *CreateFloatTexture(const Transform &tex2world, const TextureParams &tp);
00102 static Texture<SWCSpectrum> *CreateSWCSpectrumTexture(const Transform &tex2world, const TextureParams &tp);
00103
00104 private:
00105
00106
00107 TextureMapping3D *mapping;
00108 boost::shared_ptr<Texture<T> > tex1, tex2;
00109 blender::Tex tex;
00110 };
00111
00112 template <class T> Texture<float> *BlenderMusgraveTexture3D<T>::CreateFloatTexture(
00113 const Transform &tex2world,
00114 const TextureParams &tp) {
00115
00116 TextureMapping3D *map = new IdentityMapping3D(tex2world);
00117
00118 IdentityMapping3D *imap = (IdentityMapping3D*) map;
00119 imap->Apply3DTextureMappingOptions(tp);
00120
00121 boost::shared_ptr<Texture<float> > tex1 = tp.GetFloatTexture("tex1", 1.f);
00122 boost::shared_ptr<Texture<float> > tex2 = tp.GetFloatTexture("tex2", 0.f);
00123
00124
00125 short type = TEX_MFRACTAL;
00126 string noiseType = tp.FindString("type");
00127 if ((noiseType == "multifractal") || (noiseType == ""))
00128 type = TEX_MFRACTAL;
00129 else if (noiseType == "ridged_multifractal")
00130 type = TEX_RIDGEDMF;
00131 else if (noiseType == "hybrid_multifractal")
00132 type = TEX_HYBRIDMF;
00133 else if (noiseType == "hetero_terrain")
00134 type = TEX_HTERRAIN;
00135 else if (noiseType == "fbm")
00136 type = TEX_FBM;
00137 else {
00138 std::stringstream ss;
00139 ss << "Unknown noise type '" << noiseType << "'";
00140 luxError(LUX_BADTOKEN, LUX_ERROR, ss.str().c_str());
00141 }
00142
00143
00144 short basis = TEX_BLENDER;
00145 string noiseBasis = tp.FindString("noisebasis");
00146 if ((noiseBasis == "blender_original") || (noiseBasis == ""))
00147 basis = TEX_BLENDER;
00148 else if (noiseBasis == "original_perlin")
00149 basis = TEX_STDPERLIN;
00150 else if (noiseBasis == "improved_perlin")
00151 basis = TEX_NEWPERLIN;
00152 else if (noiseBasis == "voronoi_f1")
00153 basis = TEX_VORONOI_F1;
00154 else if (noiseBasis == "voronoi_f2")
00155 basis = TEX_VORONOI_F2;
00156 else if (noiseBasis == "voronoi_f3")
00157 basis = TEX_VORONOI_F3;
00158 else if (noiseBasis == "voronoi_f4")
00159 basis = TEX_VORONOI_F4;
00160 else if (noiseBasis == "voronoi_f2f1")
00161 basis = TEX_VORONOI_F2F1;
00162 else if (noiseBasis == "voronoi_crackle")
00163 basis = TEX_VORONOI_CRACKLE;
00164 else if (noiseBasis == "cell_noise")
00165 basis = TEX_CELLNOISE;
00166 else {
00167 std::stringstream ss;
00168 ss << "Unknown noise basis '" << noiseBasis << "'";
00169 luxError(LUX_BADTOKEN, LUX_ERROR, ss.str().c_str());
00170 }
00171
00172 return new BlenderMusgraveTexture3D<float>(
00173 tex1,
00174 tex2,
00175 tp.FindFloat("h", 1.0f),
00176 tp.FindFloat("lacu", 2.0f),
00177 tp.FindFloat("octs", 2.0f),
00178 tp.FindFloat("gain", 1.0f),
00179 tp.FindFloat("offset", 1.0f),
00180 tp.FindFloat("noisesize", 0.250f),
00181 tp.FindFloat("outscale", 1.0f),
00182 type,
00183 basis,
00184 tp.FindFloat("bright", 1.0f),
00185 tp.FindFloat("contrast", 1.0f),
00186 map);
00187 }
00188
00189 template <class T> Texture<SWCSpectrum> *BlenderMusgraveTexture3D<T>::CreateSWCSpectrumTexture(
00190 const Transform &tex2world,
00191 const TextureParams &tp) {
00192
00193 TextureMapping3D *map = new IdentityMapping3D(tex2world);
00194
00195 IdentityMapping3D *imap = (IdentityMapping3D*) map;
00196 imap->Apply3DTextureMappingOptions(tp);
00197
00198 boost::shared_ptr<Texture<SWCSpectrum> > tex1 = tp.GetSWCSpectrumTexture("tex1", 1.f);
00199 boost::shared_ptr<Texture<SWCSpectrum> > tex2 = tp.GetSWCSpectrumTexture("tex2", 0.f);
00200
00201
00202 short type = TEX_MFRACTAL;
00203 string noiseType = tp.FindString("type");
00204 if ((noiseType == "multifractal") || (noiseType == ""))
00205 type = TEX_MFRACTAL;
00206 else if (noiseType == "ridged_multifractal")
00207 type = TEX_RIDGEDMF;
00208 else if (noiseType == "hybrid_multifractal")
00209 type = TEX_HYBRIDMF;
00210 else if (noiseType == "hetero_terrain")
00211 type = TEX_HTERRAIN;
00212 else if (noiseType == "fbm")
00213 type = TEX_FBM;
00214 else {
00215 std::stringstream ss;
00216 ss << "Unknown noise type '" << noiseType << "'";
00217 luxError(LUX_BADTOKEN, LUX_ERROR, ss.str().c_str());
00218 }
00219
00220
00221 short basis = TEX_BLENDER;
00222 string noiseBasis = tp.FindString("noisebasis");
00223 if ((noiseBasis == "blender_original") || (noiseBasis == ""))
00224 basis = TEX_BLENDER;
00225 else if (noiseBasis == "original_perlin")
00226 basis = TEX_STDPERLIN;
00227 else if (noiseBasis == "improved_perlin")
00228 basis = TEX_NEWPERLIN;
00229 else if (noiseBasis == "voronoi_f1")
00230 basis = TEX_VORONOI_F1;
00231 else if (noiseBasis == "voronoi_f2")
00232 basis = TEX_VORONOI_F2;
00233 else if (noiseBasis == "voronoi_f3")
00234 basis = TEX_VORONOI_F3;
00235 else if (noiseBasis == "voronoi_f4")
00236 basis = TEX_VORONOI_F4;
00237 else if (noiseBasis == "voronoi_f2f1")
00238 basis = TEX_VORONOI_F2F1;
00239 else if (noiseBasis == "voronoi_crackle")
00240 basis = TEX_VORONOI_CRACKLE;
00241 else if (noiseBasis == "cell_noise")
00242 basis = TEX_CELLNOISE;
00243 else {
00244 std::stringstream ss;
00245 ss << "Unknown noise basis '" << noiseBasis << "'";
00246 luxError(LUX_BADTOKEN, LUX_ERROR, ss.str().c_str());
00247 }
00248
00249 return new BlenderMusgraveTexture3D<SWCSpectrum>(
00250 tex1,
00251 tex2,
00252 tp.FindFloat("h", 1.0f),
00253 tp.FindFloat("lacu", 2.0f),
00254 tp.FindFloat("octs", 2.0f),
00255 tp.FindFloat("gain", 1.0f),
00256 tp.FindFloat("offset", 1.0f),
00257 tp.FindFloat("noisesize", 0.250f),
00258 tp.FindFloat("outscale", 1.0f),
00259 type,
00260 basis,
00261 tp.FindFloat("bright", 1.0f),
00262 tp.FindFloat("contrast", 1.0f),
00263 map);
00264 }
00265
00266 }