Merge branch 'main/rendor-staging' into fixes
[ryzomcore.git] / nel / src / 3d / flare_shape.cpp
blob1c4b864cd5b9ad965352a3a54810919bded42148
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/flare_shape.h"
20 #include "nel/3d/flare_model.h"
21 #include "nel/3d/scene.h"
22 #include "nel/3d/driver.h"
23 #include "nel/3d/mesh.h"
24 #include "nel/3d/shape_bank.h"
27 #ifdef DEBUG_NEW
28 #define new DEBUG_NEW
29 #endif
31 namespace NL3D {
34 // ***************************************************************************************************************
35 CFlareShape::CFlareShape() : _Color(NLMISC::CRGBA::White),
36 _DazzleColor(NLMISC::CRGBA::Black),
37 _SizeDisappear(0.f),
38 _ScaleWhenDisappear(false),
39 _AngleDisappear(0.f),
40 _Persistence(1),
41 _Spacing(1),
42 _Attenuable(false),
43 _AttenuationRange (1.0f),
44 _FirstFlareKeepSize(false),
45 _DazzleEnabled(false),
46 _DazzleAttenuationRange(0.f),
47 _MaxViewDistRatio (0.9f),
48 _InfiniteDist(false),
49 _OcclusionMeshNotFound(false),
50 _OcclusionTestMeshInheritScaleRot(false),
51 _LookAtMode(true)
53 // init default pos
54 for (uint k = 0; k < MaxFlareNum; ++k)
56 _Tex [k] = NULL;
57 _Size[k] = 1.f;
58 _Pos[k] = k * (1.f / MaxFlareNum);
60 _DefaultPos.setDefaultValue(CVector::Null);
61 setDistMax(1000);
65 // ***************************************************************************************************************
66 void CFlareShape::serial(NLMISC::IStream &f)
68 // Version 4 : - added occlusion test mesh, size reduction, angle modification when object is occluded
69 // - added lookat mode for first flare
70 sint ver = f.serialVersion(5);
71 f.serial(_Color, _Persistence, _Spacing);
72 f.serial(_Attenuable);
73 if (_Attenuable)
75 f.serial(_AttenuationRange);
77 f.serial(_FirstFlareKeepSize);
78 if (f.isReading() && ver <= 4)
80 _FirstFlareKeepSize = false;
82 for (uint k = 0; k < MaxFlareNum; ++k)
84 ITexture *tex = _Tex[k];
85 f.serialPolyPtr(tex);
86 if (f.isReading())
88 _Tex[k] = tex;
90 f.serial(_Size[k], _Pos[k]);
92 f.serial(_InfiniteDist);
93 if (!_InfiniteDist)
95 f.serial(_MaxViewDist, _MaxViewDistRatio);
97 f.serial(_DazzleEnabled);
98 if (_DazzleEnabled)
100 f.serial(_DazzleColor, _DazzleAttenuationRange);
102 f.serial(_InfiniteDist);
103 if (ver >= 2)
105 f.serial( _DistMax );
107 if (ver >= 4)
109 f.serial(_OcclusionTestMeshName);
110 f.serial(_ScaleWhenDisappear);
111 f.serial(_SizeDisappear);
112 f.serial(_AngleDisappear);
113 f.serial(_OcclusionTestMeshInheritScaleRot);
114 f.serial(_LookAtMode);
118 // ***************************************************************************************************************
119 CTransformShape *CFlareShape::createInstance(CScene &scene)
121 CFlareModel *fm = NLMISC::safe_cast<CFlareModel *>(scene.createModel(FlareModelClassId) );
122 fm->Shape = this;
123 fm->_Scene = &scene;
124 // set default pos
125 fm->ITransformable::setPos( _DefaultPos.getDefaultValue() );
126 return fm;
129 // ***************************************************************************************************************
130 float CFlareShape::getNumTriangles (float distance)
132 float count = 0;
133 for (uint k = 0; k < MaxFlareNum; ++k)
135 if (_Tex[k]) count += 2;
137 return count;
140 // ***************************************************************************************************************
141 bool CFlareShape::clip(const std::vector<CPlane> &pyramid, const CMatrix &worldMatrix)
143 // compute flare pos in world basis :
144 const NLMISC::CVector pos = worldMatrix.getPos();
145 for (std::vector<NLMISC::CPlane>::const_iterator it = pyramid.begin(); it != pyramid.end(); ++it)
147 if ((*it) * pos > _Size[0])
149 //nlwarning("clipped");
150 return false;
153 return true;
156 // ***************************************************************************************************************
157 void CFlareShape::getAABBox(NLMISC::CAABBox &bbox) const
159 // the flare himself is a point
160 bbox.setCenter(CVector::Null);
161 bbox.setHalfSize(CVector::Null);
164 // ***************************************************************************************************************
165 void CFlareShape::flushTextures (IDriver &driver, uint selectedTexture)
167 // Flush each texture
168 for (uint tex=0; tex<MaxFlareNum; tex++)
170 if (_Tex[tex] != NULL)
172 // Select the good texture
173 _Tex[tex]->selectTexture (selectedTexture);
175 // Flush texture
176 driver.setupTexture (*_Tex[tex]);
181 // ***************************************************************************************************************
182 void CFlareShape::setOcclusionTestMeshName(const std::string &shapeName)
184 if (shapeName == _OcclusionTestMeshName) return;
185 _OcclusionTestMeshName = shapeName;
186 _OcclusionTestMesh = NULL;
190 // ***************************************************************************************************************
191 CMesh *CFlareShape::getOcclusionTestMesh(CShapeBank &sb)
193 if (_OcclusionTestMesh) return _OcclusionTestMesh;
194 if (_OcclusionMeshNotFound) return NULL;
195 if (_OcclusionTestMeshName.empty()) return NULL;
196 if (sb.getPresentState(_OcclusionTestMeshName)!=CShapeBank::Present)
198 sb.load(_OcclusionTestMeshName);
199 if (sb.getPresentState(_OcclusionTestMeshName)!=CShapeBank::Present)
201 _OcclusionMeshNotFound = true;
202 return NULL;
205 IShape *mesh = sb.addRef(_OcclusionTestMeshName);
206 if (!mesh)
208 _OcclusionMeshNotFound = true;
209 return NULL;
211 _OcclusionTestMesh = dynamic_cast<CMesh *>(mesh);
212 if (!_OcclusionTestMesh)
214 _OcclusionMeshNotFound = true;
215 nlwarning("%s is not a mesh. Mesh required for occlusion testing", _OcclusionTestMeshName.c_str());
216 sb.release(mesh);
217 return NULL;
219 return _OcclusionTestMesh;
224 } // NL3D