1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
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"
35 //===========================================================
36 CSegRemanenceShape::CSegRemanenceShape() : _GeomTouched(true),
38 _TextureShifting(true),
44 _BBox
.setCenter(NLMISC::CVector::Null
);
45 _BBox
.setHalfSize(NLMISC::CVector(3, 3, 3));
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);
59 f
.serialCont(_Corners
);
62 f
.serial(_TextureShifting
);
63 f
.serialPtr(_AnimatedMat
);
71 f
.serial(_RollUpRatio
);
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
;
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
);
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;
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
) );
148 CAnimatedMaterial
*aniMat
= NULL
;
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
);
169 //===========================================================
170 float CSegRemanenceShape::getNumTriangles(float distance
)
172 return (float) (_NumSlices
* 2);
176 //===========================================================
177 void CSegRemanenceShape::setBBox(const NLMISC::CAABBox
&bbox
)
182 //===========================================================
183 void CSegRemanenceShape::setMaterial(const CMaterial
&mat
)
189 //===========================================================
190 void CSegRemanenceShape::setTextureShifting(bool on
/*=true*/)
192 _TextureShifting
= on
;
196 //===========================================================
197 void CSegRemanenceShape::setRollupRatio(float ratio
)
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..)
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
)
240 copyFromOther(other
);
241 (IShape
&) *this = (IShape
&) other
; // copy base part
246 //===========================================================
247 CSegRemanenceShape::~CSegRemanenceShape()
252 //===========================================================
253 void CSegRemanenceShape::copyFromOther(const CSegRemanenceShape
&other
)
255 if (&other
== this) return;
256 CMaterialBase
*otherAnimatedMat
= other
._AnimatedMat
!= NULL
? new CMaterialBase(*other
._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
;
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
)