00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "std3d.h"
00026
00027 #include "3d/seg_remanence_shape.h"
00028 #include "3d/seg_remanence.h"
00029 #include "3d/driver.h"
00030 #include "3d/scene.h"
00031
00032
00033
00034
00035 namespace NL3D
00036 {
00037
00038
00039
00040 CSegRemanenceShape::CSegRemanenceShape() : _GeomTouched(true),
00041 _MatTouched(true),
00042 _TextureShifting(true),
00043 _NumSlices(8),
00044 _SliceTime(0.05f),
00045 _RollUpRatio(1.f),
00046 _AnimatedMat(NULL)
00047 {
00048 _BBox.setCenter(NLMISC::CVector::Null);
00049 _BBox.setHalfSize(NLMISC::CVector(3, 3, 3));
00050 setNumCorners(2);
00051 }
00052
00053
00054 void CSegRemanenceShape::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00055 {
00056 sint ver = f.serialVersion(1);
00057 f.serial(_NumSlices);
00058 f.serial(_SliceTime);
00059 f.serialCont(_Corners);
00060 f.serial(_Mat);
00061 f.serial(_BBox);
00062 f.serial(_TextureShifting);
00063 f.serialPtr(_AnimatedMat);
00064 if (f.isReading())
00065 {
00066 _GeomTouched = true;
00067 _MatTouched = true;
00068 }
00069 if (ver >= 1)
00070 {
00071 f.serial(_RollUpRatio);
00072 }
00073 }
00074
00075
00076 void CSegRemanenceShape::setSliceTime(float sliceTime)
00077 {
00078 nlassert(sliceTime > 0);
00079 _SliceTime = sliceTime;
00080 }
00081
00082
00083 void CSegRemanenceShape::setCorner(uint corner, const NLMISC::CVector &value)
00084 {
00085 nlassert(corner < _Corners.size());
00086 _Corners[corner] = value;
00087 }
00088
00089
00090 void CSegRemanenceShape::setNumSlices(uint32 numSlices)
00091 {
00092 nlassert(numSlices >= 2);
00093 _NumSlices = numSlices;
00094 _GeomTouched = true;
00095 }
00096
00097
00098 NLMISC::CVector CSegRemanenceShape::getCorner(uint corner) const
00099 {
00100 nlassert(corner < _Corners.size());
00101 return _Corners[corner];
00102 }
00103
00104
00105 void CSegRemanenceShape::setNumCorners(uint numCorners)
00106 {
00107 nlassert(numCorners >= 2);
00108 _Corners.resize(numCorners);
00109 std::fill(_Corners.begin(), _Corners.end(), NLMISC::CVector::Null);
00110 _GeomTouched = true;
00111 }
00112
00113
00114 void CSegRemanenceShape::render(IDriver *drv, CTransformShape *trans, bool opaquePass)
00115 {
00116 if ((!opaquePass && _Mat.getBlend())
00117 || (opaquePass && !_Mat.getBlend())
00118 )
00119 {
00120 CSegRemanence *sr = NLMISC::safe_cast<CSegRemanence *>(trans);
00121 if (!sr->isStarted()) return;
00122 setupVBnPB();
00123 setupMaterial();
00124
00125 drv->setupModelMatrix(NLMISC::CMatrix::Identity);
00126
00127 sr->render(drv, _VB, _PB, _Mat);
00128 }
00129 }
00130
00131
00132
00133 void CSegRemanenceShape::flushTextures(IDriver &driver)
00134 {
00135 _Mat.flushTextures(driver);
00136 }
00137
00138
00139 CTransformShape *CSegRemanenceShape::createInstance(CScene &scene)
00140 {
00141 CSegRemanence *sr = NLMISC::safe_cast<CSegRemanence *>(scene.createModel(NL3D::SegRemanenceShapeId) );
00142 sr->Shape = this;
00143 CAnimatedMaterial *aniMat = NULL;
00144 if (_AnimatedMat)
00145 {
00146 aniMat = new CAnimatedMaterial(_AnimatedMat);
00147 aniMat->setMaterial(&_Mat);
00148 }
00149 sr->setAnimatedMaterial(aniMat);
00150 sr->setupFromShape();
00151
00152 sr->setLoadBalancingGroup("Fx");
00153 return sr;
00154 }
00155
00156
00157
00158 float CSegRemanenceShape::getNumTriangles(float distance)
00159 {
00160 return (float) (_NumSlices * 2);
00161 }
00162
00163
00164
00165 void CSegRemanenceShape::setupVBnPB()
00166 {
00167 if (!_GeomTouched) return;
00168
00169 uint numCorners = _Corners.size();
00170 _VB.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag);
00171 _VB.setNumVertices(numCorners * (_NumSlices + 1));
00172 uint k, l;
00173
00174
00175 for(l = 0; l < numCorners; ++l)
00176 {
00177 for(k = 0; k <= _NumSlices; ++k)
00178 {
00179
00180 _VB.setTexCoord((_NumSlices + 1) * l + k, 0, (float) k / _NumSlices, (float) l / (numCorners - 1));
00181 }
00182 }
00183
00184 _PB.setNumTri(2 * (numCorners - 1) * _NumSlices);
00185
00186 for(l = 0; l < numCorners - 1; ++l)
00187 {
00188 for(k = 0; k < _NumSlices; ++k)
00189 {
00190 _PB.setTri(2 * (l * _NumSlices + k), (_NumSlices + 1) * l + k, (_NumSlices + 1) * (l + 1) + k + 1, (_NumSlices + 1) * (l + 1) + k);
00191 _PB.setTri(2 * (l * _NumSlices + k) + 1, (_NumSlices + 1) * l + k, (_NumSlices + 1) * l + k + 1, (_NumSlices + 1) * (l + 1) + k + 1);
00192 }
00193 }
00194 _GeomTouched = false;
00195 }
00196
00197
00198 void CSegRemanenceShape::setBBox(const NLMISC::CAABBox &bbox)
00199 {
00200 _BBox = bbox;
00201 }
00202
00203
00204 void CSegRemanenceShape::setMaterial(const CMaterial &mat)
00205 {
00206 _Mat = mat;
00207 _MatTouched = true;
00208 }
00209
00210
00211 void CSegRemanenceShape::setTextureShifting(bool on )
00212 {
00213 _TextureShifting = on;
00214 _MatTouched = true;
00215 }
00216
00217
00218 void CSegRemanenceShape::setRollupRatio(float ratio)
00219 {
00220 nlassert(ratio > 0);
00221 _RollUpRatio = ratio;
00222 }
00223
00224
00225 void CSegRemanenceShape::setupMaterial()
00226 {
00227 if (!_MatTouched) return;
00228 _Mat.enableUserTexMat(0);
00229 _Mat.getTexture(0)->setWrapS(ITexture::Clamp);
00230 _Mat.setDoubleSided(true);
00231 _Mat.setLighting(false);
00232 _MatTouched = false;
00233 }
00234
00235
00236 void CSegRemanenceShape::setAnimatedMaterial(const std::string &name)
00237 {
00238 nlassert(!name.empty());
00239 nlassert(_AnimatedMat == NULL);
00240 _AnimatedMat = new CMaterialBase;
00241 _AnimatedMat->Name = name;
00242 }
00243
00244
00245
00246
00247 CSegRemanenceShape::CSegRemanenceShape(const CSegRemanenceShape &other) : IShape(other), _AnimatedMat(NULL)
00248 {
00249 copyFromOther(other);
00250 }
00251
00252
00253 CSegRemanenceShape &CSegRemanenceShape::operator = (const CSegRemanenceShape &other)
00254 {
00255 if (&other != this)
00256 {
00257 copyFromOther(other);
00258 (IShape &) *this = (IShape &) other;
00259 }
00260 return *this;
00261 }
00262
00263
00264 CSegRemanenceShape::~CSegRemanenceShape()
00265 {
00266 delete _AnimatedMat;
00267 }
00268
00269
00270 void CSegRemanenceShape::copyFromOther(const CSegRemanenceShape &other)
00271 {
00272 if (&other == this) return;
00273 CMaterialBase *otherAnimatedMat = other._AnimatedMat != NULL ? new CMaterialBase(*other._AnimatedMat)
00274 : NULL;
00275 delete _AnimatedMat;
00276 _AnimatedMat = otherAnimatedMat;
00277
00278 _GeomTouched = other._GeomTouched;
00279 _MatTouched = other._MatTouched;
00280 _TextureShifting = other._TextureShifting;
00281 _NumSlices = other._NumSlices;
00282 _SliceTime = other._SliceTime;
00283 _Corners = other._Corners;
00284 _Mat = other._Mat;
00285 _VB = other._VB;
00286 _PB = other._PB;
00287 _BBox = other._BBox;
00288 _RollUpRatio = other._RollUpRatio;
00289 }
00290
00291 }
00292