1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
4 
5 #include "CMetaTriangleSelector.h"
6 
7 namespace irr
8 {
9 namespace scene
10 {
11 
12 //! constructor
CMetaTriangleSelector()13 CMetaTriangleSelector::CMetaTriangleSelector()
14 {
15 	#ifdef _DEBUG
16 	setDebugName("CMetaTriangleSelector");
17 	#endif
18 }
19 
20 
21 //! destructor
~CMetaTriangleSelector()22 CMetaTriangleSelector::~CMetaTriangleSelector()
23 {
24 	removeAllTriangleSelectors();
25 }
26 
27 
28 //! Returns amount of all available triangles in this selector
getTriangleCount() const29 s32 CMetaTriangleSelector::getTriangleCount() const
30 {
31 	s32 count = 0;
32 	for (u32 i=0; i<TriangleSelectors.size(); ++i)
33 		count += TriangleSelectors[i]->getTriangleCount();
34 
35 	return count;
36 }
37 
38 
39 //! Gets all triangles.
getTriangles(core::triangle3df * triangles,s32 arraySize,s32 & outTriangleCount,const core::matrix4 * transform) const40 void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
41 		s32& outTriangleCount, const core::matrix4* transform) const
42 {
43 	s32 outWritten = 0;
44 	for (u32 i=0; i<TriangleSelectors.size(); ++i)
45 	{
46 		s32 t = 0;
47 		TriangleSelectors[i]->getTriangles(triangles + outWritten,
48 				arraySize - outWritten, t, transform);
49 		outWritten += t;
50 		if (outWritten==arraySize)
51 			break;
52 	}
53 
54 	outTriangleCount = outWritten;
55 }
56 
57 
58 //! Gets all triangles which lie within a specific bounding box.
getTriangles(core::triangle3df * triangles,s32 arraySize,s32 & outTriangleCount,const core::aabbox3d<f32> & box,const core::matrix4 * transform) const59 void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
60 		s32& outTriangleCount, const core::aabbox3d<f32>& box,
61 		const core::matrix4* transform) const
62 {
63 	s32 outWritten = 0;
64 	for (u32 i=0; i<TriangleSelectors.size(); ++i)
65 	{
66 		s32 t = 0;
67 		TriangleSelectors[i]->getTriangles(triangles + outWritten,
68 				arraySize - outWritten, t, box, transform);
69 		outWritten += t;
70 		if (outWritten==arraySize)
71 			break;
72 	}
73 
74 	outTriangleCount = outWritten;
75 }
76 
77 
78 //! Gets all triangles which have or may have contact with a 3d line.
getTriangles(core::triangle3df * triangles,s32 arraySize,s32 & outTriangleCount,const core::line3d<f32> & line,const core::matrix4 * transform) const79 void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
80 		s32& outTriangleCount, const core::line3d<f32>& line,
81 		const core::matrix4* transform) const
82 {
83 	s32 outWritten = 0;
84 	for (u32 i=0; i<TriangleSelectors.size(); ++i)
85 	{
86 		s32 t = 0;
87 		TriangleSelectors[i]->getTriangles(triangles + outWritten,
88 				arraySize - outWritten, t, line, transform);
89 		outWritten += t;
90 		if (outWritten==arraySize)
91 			break;
92 	}
93 
94 	outTriangleCount = outWritten;
95 }
96 
97 
98 //! Adds a triangle selector to the collection of triangle selectors
99 //! in this metaTriangleSelector.
addTriangleSelector(ITriangleSelector * toAdd)100 void CMetaTriangleSelector::addTriangleSelector(ITriangleSelector* toAdd)
101 {
102 	if (!toAdd)
103 		return;
104 
105 	TriangleSelectors.push_back(toAdd);
106 	toAdd->grab();
107 }
108 
109 
110 //! Removes a specific triangle selector which was added before	from the collection.
removeTriangleSelector(ITriangleSelector * toRemove)111 bool CMetaTriangleSelector::removeTriangleSelector(ITriangleSelector* toRemove)
112 {
113 	for (u32 i=0; i<TriangleSelectors.size(); ++i)
114 	{
115 		if (toRemove == TriangleSelectors[i])
116 		{
117 			TriangleSelectors[i]->drop();
118 			TriangleSelectors.erase(i);
119 			return true;
120 		}
121 	}
122 
123 	return false;
124 }
125 
126 
127 //! Removes all triangle selectors from the collection.
removeAllTriangleSelectors()128 void CMetaTriangleSelector::removeAllTriangleSelectors()
129 {
130 	for (u32 i=0; i<TriangleSelectors.size(); ++i)
131 		TriangleSelectors[i]->drop();
132 
133 	TriangleSelectors.clear();
134 }
135 
136 
137 //! Return the scene node associated with a given triangle.
getSceneNodeForTriangle(u32 triangleIndex) const138 ISceneNode* CMetaTriangleSelector::getSceneNodeForTriangle(u32 triangleIndex) const
139 {
140 	u32 totalTriangles = 0;
141 
142 	for (u32 i=0; i<TriangleSelectors.size(); ++i)
143 	{
144 		totalTriangles += TriangleSelectors[i]->getTriangleCount();
145 
146 		if(totalTriangles > triangleIndex)
147 			return TriangleSelectors[i]->getSceneNodeForTriangle(0);
148 	}
149 
150 	// For lack of anything more sensible, return the first selector.
151 	return TriangleSelectors[0]->getSceneNodeForTriangle(0);
152 }
153 
154 
155 /* Return the number of TriangleSelectors that are inside this one,
156 Only useful for MetaTriangleSelector others return 1
157 */
getSelectorCount() const158 u32 CMetaTriangleSelector::getSelectorCount() const
159 {
160 	return TriangleSelectors.size();
161 }
162 
163 
164 /* Returns the TriangleSelector based on index based on getSelectorCount
165 Only useful for MetaTriangleSelector others return 'this'
166 */
getSelector(u32 index)167 ITriangleSelector* CMetaTriangleSelector::getSelector(u32 index)
168 {
169 	if (index >= TriangleSelectors.size())
170 		return 0;
171 	return TriangleSelectors[index];
172 }
173 
174 
175 /* Returns the TriangleSelector based on index based on getSelectorCount
176 Only useful for MetaTriangleSelector others return 'this'
177 */
getSelector(u32 index) const178 const ITriangleSelector* CMetaTriangleSelector::getSelector(u32 index) const
179 {
180 	if (index >= TriangleSelectors.size())
181 		return 0;
182 	return TriangleSelectors[index];
183 }
184 
185 
186 } // end namespace scene
187 } // end namespace irr
188 
189