Merge branch 'main/rendor-staging' into fixes
[ryzomcore.git] / nel / src / 3d / seg_remanence_shape.cpp
blobeb546177ca38e286514d2381caa83e5c80e26fff
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "std3d.h"
19 #include "nel/3d/seg_remanence_shape.h"
20 #include "nel/3d/seg_remanence.h"
21 #include "nel/3d/driver.h"
22 #include "nel/3d/scene.h"
24 #include "nel/misc/bsphere.h"
27 #ifdef DEBUG_NEW
28 #define new DEBUG_NEW
29 #endif
31 namespace NL3D
35 //===========================================================
36 CSegRemanenceShape::CSegRemanenceShape() : _GeomTouched(true),
37 _MatTouched(true),
38 _TextureShifting(true),
39 _NumSlices(8),
40 _SliceTime(0.05f),
41 _RollUpRatio(1.f),
42 _AnimatedMat(NULL)
44 _BBox.setCenter(NLMISC::CVector::Null);
45 _BBox.setHalfSize(NLMISC::CVector(3, 3, 3));
46 setNumCorners(2);
49 //===========================================================
50 void CSegRemanenceShape::serial(NLMISC::IStream &f)
52 // version 2 : added default tracks
53 // version 1 : rollup ratio
54 // version 0 : base version
56 sint ver = f.serialVersion(2);
57 f.serial(_NumSlices);
58 f.serial(_SliceTime);
59 f.serialCont(_Corners);
60 f.serial(_Mat);
61 f.serial(_BBox);
62 f.serial(_TextureShifting);
63 f.serialPtr(_AnimatedMat);
64 if (f.isReading())
66 _GeomTouched = true;
67 _MatTouched = true;
69 if (ver >= 1)
71 f.serial(_RollUpRatio);
73 if (ver >= 2)
75 f.serial(_DefaultPos);
76 f.serial(_DefaultRotQuat);
77 f.serial(_DefaultScale);
81 //===========================================================
82 void CSegRemanenceShape::setSliceTime(float sliceTime)
84 nlassert(sliceTime > 0);
85 _SliceTime = sliceTime;
88 //===========================================================
89 void CSegRemanenceShape::setCorner(uint corner, const NLMISC::CVector &value)
91 nlassert(corner < _Corners.size());
92 _Corners[corner] = value;
95 //===========================================================
96 void CSegRemanenceShape::setNumSlices(uint32 numSlices)
98 nlassert(numSlices >= 2);
99 _NumSlices = numSlices;
100 _GeomTouched = true;
103 //===========================================================
104 NLMISC::CVector CSegRemanenceShape::getCorner(uint corner) const
106 nlassert(corner < _Corners.size());
107 return _Corners[corner];
110 //===========================================================
111 void CSegRemanenceShape::setNumCorners(uint numCorners)
113 nlassert(numCorners >= 2);
114 _Corners.resize(numCorners);
115 std::fill(_Corners.begin(), _Corners.end(), NLMISC::CVector::Null);
116 _GeomTouched = true;
119 //===========================================================
120 void CSegRemanenceShape::render(IDriver *drv, CTransformShape *trans, bool opaquePass)
122 if ((!opaquePass && _Mat.getBlend())
123 || (opaquePass && !_Mat.getBlend())
126 CSegRemanence *sr = NLMISC::safe_cast<CSegRemanence *>(trans);
127 #ifndef DEBUG_SEG_REMANENCE_DISPLAY
128 if (!sr->isStarted()) return;
129 #endif
130 setupMaterial();
132 sr->render(drv, _Mat);
137 //===========================================================
138 void CSegRemanenceShape::flushTextures(IDriver &driver, uint selectedTexture)
140 _Mat.flushTextures(driver, selectedTexture);
143 //===========================================================
144 CTransformShape *CSegRemanenceShape::createInstance(CScene &scene)
146 CSegRemanence *sr = NLMISC::safe_cast<CSegRemanence *>(scene.createModel(NL3D::SegRemanenceShapeId) );
147 sr->Shape = this;
148 CAnimatedMaterial *aniMat = NULL;
149 if (_AnimatedMat)
151 aniMat = new CAnimatedMaterial(_AnimatedMat);
152 aniMat->setMaterial(&_Mat);
154 sr->setAnimatedMaterial(aniMat);
155 sr->setupFromShape();
156 // SegRemanence are added to the "Fx" Load Balancing Group.
157 sr->setLoadBalancingGroup("Fx");
159 sr->ITransformable::setPos( _DefaultPos.getDefaultValue() );
160 sr->ITransformable::setRotQuat( _DefaultRotQuat.getDefaultValue() );
161 sr->ITransformable::setScale( _DefaultScale.getDefaultValue() );
163 sr->setSliceTime(_SliceTime);
165 return sr;
169 //===========================================================
170 float CSegRemanenceShape::getNumTriangles(float distance)
172 return (float) (_NumSlices * 2);
176 //===========================================================
177 void CSegRemanenceShape::setBBox(const NLMISC::CAABBox &bbox)
179 _BBox = bbox;
182 //===========================================================
183 void CSegRemanenceShape::setMaterial(const CMaterial &mat)
185 _Mat = mat;
186 _MatTouched = true;
189 //===========================================================
190 void CSegRemanenceShape::setTextureShifting(bool on /*=true*/)
192 _TextureShifting = on;
193 _MatTouched = true;
196 //===========================================================
197 void CSegRemanenceShape::setRollupRatio(float ratio)
199 nlassert(ratio > 0);
200 _RollUpRatio = ratio;
203 //===========================================================
204 void CSegRemanenceShape::setupMaterial()
206 if (!_MatTouched) return;
207 _Mat.enableUserTexMat(0);
208 if (_Mat.getTexture(0))
210 _Mat.getTexture(0)->setWrapS(ITexture::Clamp);
211 _Mat.getTexture(0)->setWrapT(ITexture::Clamp);
213 _Mat.setDoubleSided(true);
214 _Mat.setLighting(false); // lighting not supported (the vb has no normals anyway..)
215 _MatTouched = false;
218 //===========================================================
219 void CSegRemanenceShape::setAnimatedMaterial(const std::string &name)
221 nlassert(!name.empty());
222 nlassert(_AnimatedMat == NULL);
223 _AnimatedMat = new CMaterialBase;
224 _AnimatedMat->Name = name;
229 //===========================================================
230 CSegRemanenceShape::CSegRemanenceShape(const CSegRemanenceShape &other) : IShape(other), _AnimatedMat(NULL)
232 copyFromOther(other);
235 //===========================================================
236 CSegRemanenceShape &CSegRemanenceShape::operator = (const CSegRemanenceShape &other)
238 if (&other != this)
240 copyFromOther(other);
241 (IShape &) *this = (IShape &) other; // copy base part
243 return *this;
246 //===========================================================
247 CSegRemanenceShape::~CSegRemanenceShape()
249 delete _AnimatedMat;
252 //===========================================================
253 void CSegRemanenceShape::copyFromOther(const CSegRemanenceShape &other)
255 if (&other == this) return;
256 CMaterialBase *otherAnimatedMat = other._AnimatedMat != NULL ? new CMaterialBase(*other._AnimatedMat)
257 : NULL;
258 delete _AnimatedMat;
259 _AnimatedMat = otherAnimatedMat;
261 _GeomTouched = other._GeomTouched;
262 _MatTouched = other._MatTouched;
263 _TextureShifting = other._TextureShifting;
264 _NumSlices = other._NumSlices;
265 _SliceTime = other._SliceTime;
266 _Corners = other._Corners;
267 _Mat = other._Mat;
268 _BBox = other._BBox;
269 _RollUpRatio = other._RollUpRatio;
274 //===========================================================
275 bool CSegRemanenceShape::clip(const std::vector<CPlane> &pyramid, const CMatrix &worldMatrix)
277 // Speed Clip: clip just the sphere.
278 NLMISC::CBSphere localSphere(_BBox.getCenter(), _BBox.getRadius());
279 NLMISC::CBSphere worldSphere;
281 // transform the sphere in WorldMatrix (with nearly good scale info).
282 localSphere.applyTransform(worldMatrix, worldSphere);
284 // if out of only plane, entirely out.
285 for(sint i=0;i<(sint)pyramid.size();i++)
287 // We are sure that pyramid has normalized plane normals.
288 // if SpherMax OUT return false.
289 float d= pyramid[i]*worldSphere.Center;
290 if(d>worldSphere.Radius)
291 return false;
293 return true;