0024520: Implementing affine transformations in ray-tracing
[occt.git] / src / OpenGl / OpenGl_SceneGeometry.hxx
1 // Created on: 2013-08-27
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _OpenGl_SceneGeometry_Header
17 #define _OpenGl_SceneGeometry_Header
18
19 #include <BVH_Geometry.hxx>
20 #include <BVH_Triangulation.hxx>
21 #include <NCollection_StdAllocator.hxx>
22 #include <OpenGl_PrimitiveArray.hxx>
23 #include <OpenGl_Structure.hxx>
24
25 namespace OpenGl_Raytrace
26 {
27   //! Checks to see if the group contains ray-trace geometry.
28   Standard_Boolean IsRaytracedGroup (const OpenGl_Group* theGroup);
29
30   //! Checks to see if the element contains ray-trace geometry.
31   Standard_Boolean IsRaytracedElement (const OpenGl_ElementNode* theNode);
32
33   //! Checks to see if the structure contains ray-trace geometry.
34   Standard_Boolean IsRaytracedStructure (const OpenGl_Structure* theStructure);
35 }
36
37 //! Stores properties of surface material.
38 class OpenGl_RaytraceMaterial
39 {
40 public:
41
42   //! Ambient reflection coefficient.
43   BVH_Vec4f Ambient;
44
45   //! Diffuse reflection coefficient.
46   BVH_Vec4f Diffuse;
47
48   //! Glossy reflection coefficient.
49   BVH_Vec4f Specular;
50
51   //! Material emission.
52   BVH_Vec4f Emission;
53
54   //! Specular reflection coefficient.
55   BVH_Vec4f Reflection;
56
57   //! Specular refraction coefficient.
58   BVH_Vec4f Refraction;
59
60   //! Material transparency.
61   BVH_Vec4f Transparency;
62
63 public:
64
65   //! Creates new default material.
66   OpenGl_RaytraceMaterial();
67
68   //! Creates new material with specified properties.
69   OpenGl_RaytraceMaterial (const BVH_Vec4f& theAmbient,
70                            const BVH_Vec4f& theDiffuse,
71                            const BVH_Vec4f& theSpecular);
72
73   //! Creates new material with specified properties.
74   OpenGl_RaytraceMaterial (const BVH_Vec4f& theAmbient,
75                            const BVH_Vec4f& theDiffuse,
76                            const BVH_Vec4f& theSpecular,
77                            const BVH_Vec4f& theEmission,
78                            const BVH_Vec4f& theTranspar);
79
80   //! Creates new material with specified properties.
81   OpenGl_RaytraceMaterial (const BVH_Vec4f& theAmbient,
82                            const BVH_Vec4f& theDiffuse,
83                            const BVH_Vec4f& theSpecular,
84                            const BVH_Vec4f& theEmission,
85                            const BVH_Vec4f& theTranspar,
86                            const BVH_Vec4f& theReflection,
87                            const BVH_Vec4f& theRefraction);
88
89   //! Returns packed (serialized) representation of material.
90   const Standard_ShortReal* Packed()
91   {
92     return reinterpret_cast<Standard_ShortReal*> (this);
93   }
94 };
95
96 //! Stores properties of OpenGL light source.
97 class OpenGl_RaytraceLight
98 {
99 public:
100
101   //! Diffuse intensity (in terms of OpenGL).
102   BVH_Vec4f Diffuse;
103
104   //! Position of light source (in terms of OpenGL).
105   BVH_Vec4f Position;
106
107 public:
108
109   //! Creates new light source.
110   OpenGl_RaytraceLight (const BVH_Vec4f& theDiffuse,
111                         const BVH_Vec4f& thePosition);
112
113   //! Returns packed (serialized) representation of light source.
114   const Standard_ShortReal* Packed()
115   {
116     return reinterpret_cast<Standard_ShortReal*> (this);
117   }
118 };
119
120 //! Triangulation of single OpenGL primitive array.
121 class OpenGl_TriangleSet : public BVH_Triangulation<Standard_ShortReal, 4>
122 {
123 public:
124
125   //! Value of invalid material index to return in case of errors.
126   static const Standard_Integer INVALID_MATERIAL = -1;
127
128 public:
129
130   //! Creates new OpenGL element triangulation.
131   OpenGl_TriangleSet (const OpenGl_PrimitiveArray* theArray = NULL)
132   : BVH_Triangulation<Standard_ShortReal, 4>(),
133     myArray (theArray)
134    {
135      //
136    }
137
138   //! Releases resources of OpenGL element triangulation.
139   ~OpenGl_TriangleSet()
140   {
141     //
142   }
143
144   //! Returns associated OpenGl structure.
145   const OpenGl_PrimitiveArray* AssociatedPArray() const
146   {
147     return myArray;
148   }
149
150   //! Returns material index of triangle set.
151   Standard_Integer MaterialIndex() const
152   {
153     if (Elements.size() == 0)
154       return INVALID_MATERIAL;
155
156     return Elements.front().w();
157   }
158
159   //! Sets material index for entire triangle set.
160   void SetMaterialIndex (Standard_Integer aMatID)
161   {
162     for (Standard_Size anIdx = 0; anIdx < Elements.size(); ++anIdx)
163       Elements[anIdx].w() = aMatID;
164   }
165
166   //! Returns AABB of primitive set.
167   BVH_BoxNt Box() const
168   {
169     const BVH_Transform<Standard_ShortReal, 4>* aTransform = 
170       dynamic_cast<const BVH_Transform<Standard_ShortReal, 4>* > (Properties().operator->());
171  
172     BVH_BoxNt aBox = BVH_PrimitiveSet<Standard_ShortReal, 4>::Box(); 
173  
174     if (aTransform)
175     {
176       return aTransform->Apply (aBox);
177     }
178  
179     return aBox;
180   }
181
182 public:
183
184   BVH_Array4f Normals; //!< Array of vertex normals.
185  
186 private:
187
188   const OpenGl_PrimitiveArray* myArray; //!< Reference to associated OpenGl structure.
189
190 };
191
192 //! Stores geometry of ray-tracing scene.
193 class OpenGl_RaytraceGeometry : public BVH_Geometry<Standard_ShortReal, 4>
194 {
195 public:
196
197   //! Value of invalid offset to return in case of errors.
198   static const Standard_Integer INVALID_OFFSET = -1;
199
200 public:
201
202   //! Array of properties of light sources.
203   std::vector<OpenGl_RaytraceLight,
204     NCollection_StdAllocator<OpenGl_RaytraceLight> > Sources;
205
206   //! Array of 'front' material properties.
207   std::vector<OpenGl_RaytraceMaterial,
208     NCollection_StdAllocator<OpenGl_RaytraceMaterial> > Materials;
209
210   //! Global ambient from all light sources.
211   BVH_Vec4f Ambient;
212
213 public:
214
215   //! Creates uninitialized ray-tracing geometry.
216   OpenGl_RaytraceGeometry()
217   : BVH_Geometry<Standard_ShortReal, 4>(),
218     myHighLevelTreeDepth (0),
219     myBottomLevelTreeDepth (0)
220   {
221     //
222   }
223
224   //! Releases resources of ray-tracing geometry.
225   ~OpenGl_RaytraceGeometry()
226   {
227     //
228   }
229
230   //! Clears ray-tracing geometry.
231   void Clear();
232
233   //! Clears only ray-tracing materials.
234   void ClearMaterials()
235   {
236     std::vector<OpenGl_RaytraceMaterial,
237       NCollection_StdAllocator<OpenGl_RaytraceMaterial> > anEmptyMaterials;
238  
239     Materials.swap (anEmptyMaterials);
240   }
241
242 public:
243
244   //! Performs post-processing of high-level scene BVH.
245   Standard_Boolean ProcessAcceleration();
246
247   //! Returns offset of bottom-level BVH for given leaf node.
248   //! If the node index is not valid the function returns -1.
249   //! @note Can be used after processing acceleration structure.
250   Standard_Integer AccelerationOffset (Standard_Integer theNodeIdx);
251
252   //! Returns offset of triangulation vertices for given leaf node.
253   //! If the node index is not valid the function returns -1.
254   //! @note Can be used after processing acceleration structure.
255   Standard_Integer VerticesOffset (Standard_Integer theNodeIdx);
256
257   //! Returns offset of triangulation elements for given leaf node.
258   //! If the node index is not valid the function returns -1.
259   //! @note Can be used after processing acceleration structure.
260   Standard_Integer ElementsOffset (Standard_Integer theNodeIdx);
261
262   //! Returns triangulation data for given leaf node.
263   //! If the node index is not valid the function returns NULL.
264   //! @note Can be used after processing acceleration structure.
265   OpenGl_TriangleSet* TriangleSet (Standard_Integer theNodeIdx);
266
267   //! Returns depth of high-level scene BVH from last build.
268   Standard_Integer HighLevelTreeDepth() const
269   {
270     return myHighLevelTreeDepth;
271   }
272
273   //! Returns maximum depth of bottom-level scene BVHs from last build.
274   Standard_Integer BottomLevelTreeDepth() const
275   {
276     return myBottomLevelTreeDepth;
277   }
278
279 protected:
280
281   Standard_Integer myHighLevelTreeDepth;   //!< Depth of high-level scene BVH from last build
282   Standard_Integer myBottomLevelTreeDepth; //!< Maximum depth of bottom-level scene BVHs from last build
283
284 };
285
286 #endif