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/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"
34 // ***************************************************************************************************************
35 CFlareShape::CFlareShape() : _Color(NLMISC::CRGBA::White
),
36 _DazzleColor(NLMISC::CRGBA::Black
),
38 _ScaleWhenDisappear(false),
43 _AttenuationRange (1.0f
),
44 _FirstFlareKeepSize(false),
45 _DazzleEnabled(false),
46 _DazzleAttenuationRange(0.f
),
47 _MaxViewDistRatio (0.9f
),
49 _OcclusionMeshNotFound(false),
50 _OcclusionTestMeshInheritScaleRot(false),
54 for (uint k
= 0; k
< MaxFlareNum
; ++k
)
58 _Pos
[k
] = k
* (1.f
/ MaxFlareNum
);
60 _DefaultPos
.setDefaultValue(CVector::Null
);
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
);
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
];
90 f
.serial(_Size
[k
], _Pos
[k
]);
92 f
.serial(_InfiniteDist
);
95 f
.serial(_MaxViewDist
, _MaxViewDistRatio
);
97 f
.serial(_DazzleEnabled
);
100 f
.serial(_DazzleColor
, _DazzleAttenuationRange
);
102 f
.serial(_InfiniteDist
);
105 f
.serial( _DistMax
);
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
) );
125 fm
->ITransformable::setPos( _DefaultPos
.getDefaultValue() );
129 // ***************************************************************************************************************
130 float CFlareShape::getNumTriangles (float distance
)
133 for (uint k
= 0; k
< MaxFlareNum
; ++k
)
135 if (_Tex
[k
]) count
+= 2;
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");
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
);
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;
205 IShape
*mesh
= sb
.addRef(_OcclusionTestMeshName
);
208 _OcclusionMeshNotFound
= true;
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());
219 return _OcclusionTestMesh
;