CSegmentArray.h
Go to the documentation of this file.
1 //==============================================================================
2 /*
3  Software License Agreement (BSD License)
4  Copyright (c) 2003-2016, CHAI3D.
5  (www.chai3d.org)
6 
7  All rights reserved.
8 
9  Redistribution and use in source and binary forms, with or without
10  modification, are permitted provided that the following conditions
11  are met:
12 
13  * Redistributions of source code must retain the above copyright
14  notice, this list of conditions and the following disclaimer.
15 
16  * Redistributions in binary form must reproduce the above
17  copyright notice, this list of conditions and the following
18  disclaimer in the documentation and/or other materials provided
19  with the distribution.
20 
21  * Neither the name of CHAI3D nor the names of its contributors may
22  be used to endorse or promote products derived from this software
23  without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  POSSIBILITY OF SUCH DAMAGE.
37 
38  \author <http://www.chai3d.org>
39  \author Francois Conti
40  \version 3.2.0 $Rev: 2015 $
41 */
42 //==============================================================================
43 
44 //------------------------------------------------------------------------------
45 #ifndef CSegmentArrayH
46 #define CSegmentArrayH
47 //------------------------------------------------------------------------------
48 #include "graphics/CGenericArray.h"
49 //------------------------------------------------------------------------------
50 
51 //------------------------------------------------------------------------------
52 namespace chai3d {
53 //------------------------------------------------------------------------------
54 
55 //==============================================================================
62 //==============================================================================
63 
64 //------------------------------------------------------------------------------
66 typedef std::shared_ptr<cSegmentArray> cSegmentArrayPtr;
67 //------------------------------------------------------------------------------
68 
69 //==============================================================================
102 //==============================================================================
104 {
105  //--------------------------------------------------------------------------
106  // CONSTRUCTOR & DESTRUCTOR:
107  //--------------------------------------------------------------------------
108 
109 public:
110 
111  //--------------------------------------------------------------------------
117  //--------------------------------------------------------------------------
118  cSegmentArray(cVertexArrayPtr a_vertexArray) : cGenericArray(a_vertexArray)
119  {
120  // clear all segments
121  clear();
122 
123  // store pointer to vertex array
124  m_vertices = a_vertexArray;
125 
126  // initialize OpenGL buffer ID
127  m_elementBuffer = 0;
128  }
129 
130 
131  //--------------------------------------------------------------------------
135  //--------------------------------------------------------------------------
137 
138 
140  void clear()
141  {
142  m_allocated.clear();
143  m_indices.clear();
144  m_freeElements.clear();
145  m_flagMarkForUpdate = true;
146  m_flagMarkForResize = true;
147  }
148 
149 
151  static cSegmentArrayPtr create(cVertexArrayPtr a_vertexArray) { return (std::make_shared<cSegmentArray>(a_vertexArray)); }
152 
153 
154  //--------------------------------------------------------------------------
155  // PUBLIC METHODS:
156  //--------------------------------------------------------------------------
157 
158 public:
159 
161  virtual unsigned int getNumVerticesPerElement() { return (2); }
162 
164  cSegmentArrayPtr copy();
165 
167  void compress();
168 
169 
170  //--------------------------------------------------------------------------
179  //--------------------------------------------------------------------------
180  int newSegment(const unsigned int a_vertexIndex0,
181  const unsigned int a_vertexIndex1)
182  {
183  int index;
184 
185  // check if there is an available slot on the free segment list
186  if (m_freeElements.size() > 0)
187  {
188  index = m_freeElements.front();
189  m_allocated[index] = true;
190  m_freeElements.pop_front();
191  setVertices(index, a_vertexIndex0, a_vertexIndex1);
192  }
193  else
194  {
195  // store new indices
196  m_indices.push_back(a_vertexIndex0);
197  m_indices.push_back(a_vertexIndex1);
198  m_allocated.push_back(true);
199 
200  m_flagMarkForResize = true;
201 
202  // store index of new segment
203  index = (int)(m_allocated.size())-1;
204  }
205 
206  // mark for update
207  m_flagMarkForUpdate = true;
208 
209  // return index to new segment
210  return (index);
211  }
212 
213 
214  //--------------------------------------------------------------------------
222  //--------------------------------------------------------------------------
223  void removeSegment(const unsigned int a_segmentIndex)
224  {
225  // sanity check
226  if (m_allocated[a_segmentIndex])
227  {
228  // disable segment
229  m_allocated[a_segmentIndex] = false;
230 
231  // reset indices to vertices
232  setVertices(a_segmentIndex, 0, 0);
233 
234  // add segment to free list
235  m_freeElements.push_back(a_segmentIndex);
236 
237  // mark for update
238  m_flagMarkForUpdate = true;
239  }
240  }
241 
242 
243  //--------------------------------------------------------------------------
252  //--------------------------------------------------------------------------
253  inline void setVertices(const unsigned int a_segmentIndex,
254  const unsigned int a_vertexIndex0,
255  const unsigned int a_vertexIndex1)
256  {
257  m_indices[2*a_segmentIndex+0] = a_vertexIndex0;
258  m_indices[2*a_segmentIndex+1] = a_vertexIndex1;
259 
260  // mark for update
261  m_flagMarkForUpdate = true;
262  }
263 
264 
265  //--------------------------------------------------------------------------
273  //--------------------------------------------------------------------------
274  inline unsigned int getVertexIndex0(const unsigned int a_segmentIndex) const
275  {
276  return (m_indices[2*a_segmentIndex+0]);
277  };
278 
279 
280  //--------------------------------------------------------------------------
288  //--------------------------------------------------------------------------
289  inline unsigned int getVertexIndex1(const unsigned int a_segmentIndex) const
290  {
291  return (m_indices[2*a_segmentIndex+1]);
292  };
293 
294 
295  //--------------------------------------------------------------------------
305  //--------------------------------------------------------------------------
306  virtual unsigned int getVertexIndex(const unsigned int a_elementIndex,
307  const unsigned int a_vertexNumber) const
308  {
309  switch (a_vertexNumber)
310  {
311  case 0: return (m_indices[2*a_elementIndex+0]);
312  case 1: return (m_indices[2*a_elementIndex+1]);
313  default: return (0);
314  }
315  }
316 
317 
318  //--------------------------------------------------------------------------
328  //--------------------------------------------------------------------------
329  cVector3d getTexCoordAtPosition(const unsigned int a_segmentIndex,
330  const cVector3d& a_localPos)
331  {
332  // get vertices of contact segments
333  cVector3d vertex0 = m_vertices->getLocalPos(getVertexIndex0(a_segmentIndex));
334  cVector3d vertex1 = m_vertices->getLocalPos(getVertexIndex1(a_segmentIndex));
335 
336  // project desired point on segment
337  cVector3d point = cProjectPointOnSegment(a_localPos, vertex0, vertex1);
338 
339  // compute weights based on position of contact point
340  double c0, c1;
341 
342  double distance01 = cDistance(vertex0, vertex1);
343  if (distance01 < C_SMALL)
344  {
345  c0 = 1.0;
346  c1 = 0.0;
347  }
348  else
349  {
350  double distanceP0 = cDistance(vertex0, point);
351  c1 = distanceP0 / distance01;
352  c0 = 1.0 - c1;
353  }
354 
355  cVector3d texCoord;
356 
357  if (m_vertices->getUseTexCoordData())
358  {
359  // retrieve the texture coordinate for each segment vertex
360  cVector3d texCoord0 = m_vertices->getTexCoord(getVertexIndex0(a_segmentIndex));
361  cVector3d texCoord1 = m_vertices->getTexCoord(getVertexIndex1(a_segmentIndex));
362 
363  // compute the exact texture coordinate at the contact point
364  texCoord = cAdd( cMul(c0, texCoord0), cMul(c1, texCoord1));
365  }
366  else
367  {
368  texCoord.set(0.0, 0.0, 0.0);
369  }
370 
371  // return result
372  return (texCoord);
373  }
374 
375 
376  //--------------------------------------------------------------------------
380  //--------------------------------------------------------------------------
381  inline void render()
382  {
383 #ifdef C_USE_OPENGL
384  unsigned int numSegments = getNumElements();
385 
386  // allocate object and buffers if needed
387  if (m_elementBuffer == 0)
388  {
389  glGenBuffers(1, &m_elementBuffer);
390  }
391 
392  // bind buffer
393  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementBuffer);
394 
395  // update buffer size if needed
397  {
398  glBufferData(GL_ELEMENT_ARRAY_BUFFER, 2 * numSegments * sizeof(unsigned int), &(m_indices[0]), GL_STATIC_DRAW);
399  m_flagMarkForResize = true;
400  }
401 
402  // update data if needed
404  {
405  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementBuffer);
406  glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 2 * numSegments * sizeof(unsigned int), &(m_indices[0]));
407 
408  m_flagMarkForUpdate = false;
409  }
410 
411  // render object
412  m_vertices->renderInitialize();
413 
414  glEnableClientState(GL_VERTEX_ARRAY);
415  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementBuffer);
416  glDrawElements( GL_LINES, 2 * numSegments, GL_UNSIGNED_INT, (void*)0);
417  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
418 
419  m_vertices->renderFinalize();
420 #endif
421  }
422 
424  virtual bool computeCollision(const unsigned int a_elementIndex,
425  cGenericObject* a_object,
426  cVector3d& a_segmentPointA,
427  cVector3d& a_segmentPointB,
428  cCollisionRecorder& a_recorder,
429  cCollisionSettings& a_settings) const;
430 };
431 
432 //------------------------------------------------------------------------------
433 } // namespace chai3d
434 //------------------------------------------------------------------------------
435 
436 //------------------------------------------------------------------------------
437 #endif
438 //------------------------------------------------------------------------------
439 
440 
This class implements a 3D vector.
Definition: CVector3d.h:88
const double C_SMALL
Small value near zero.
Definition: CConstants.h:103
double cDistance(const cVector3d &a_point1, const cVector3d &a_point2)
This function computes the Euclidean distance between two points.
Definition: CMaths.h:953
virtual unsigned int getVertexIndex(const unsigned int a_elementIndex, const unsigned int a_vertexNumber) const
Definition: CSegmentArray.h:306
std::shared_ptr< cSegmentArray > cSegmentArrayPtr
Definition: CSegmentArray.h:65
~cSegmentArray()
Definition: CSegmentArray.h:136
Implements an abstract class for describing elements composed of vertices.
cVector3d cAdd(const cVector3d &a_vector1, const cVector3d &a_vector2)
This function computes the addition of two vectors.
Definition: CMaths.h:708
std::vector< unsigned int > m_indices
Element indices to vertices.
Definition: CGenericArray.h:230
std::vector< bool > m_allocated
Element allocation flags.
Definition: CGenericArray.h:233
cVector3d cProjectPointOnSegment(const cVector3d &a_point, const cVector3d &a_segmentPointA, const cVector3d &a_segmentPointB)
This function computes the projection of a point onto a segment.
Definition: CGeometry.h:299
std::list< unsigned int > m_freeElements
List of free elements.
Definition: CGenericArray.h:259
void setVertices(const unsigned int a_segmentIndex, const unsigned int a_vertexIndex0, const unsigned int a_vertexIndex1)
Definition: CSegmentArray.h:253
void compress()
This method compresses the array by removing non used segments.
Definition: CSegmentArray.cpp:296
cSegmentArray(cVertexArrayPtr a_vertexArray)
Definition: CSegmentArray.h:118
void render()
Definition: CSegmentArray.h:381
void set(const double &a_x, const double &a_y, const double &a_z)
This method initializes this vector with components x, y, and z passed as arguments.
Definition: CVector3d.h:298
void clear()
This method clears all segments from array.
Definition: CSegmentArray.h:140
static cSegmentArrayPtr create(cVertexArrayPtr a_vertexArray)
Shared cSegmentArray allocator.
Definition: CSegmentArray.h:151
This class implements a base class for all 2D or 3D objects in CHAI3D.
Definition: CGenericObject.h:112
This class implements a collision detection recorder that stores all collision events that are report...
Definition: CCollisionBasics.h:185
cVector3d cMul(const double &a_value, const cVector3d &a_vector)
This function computes the multiplication of a vector by a scalar.
Definition: CMaths.h:824
bool m_flagMarkForUpdate
If true then element data has been modified.
Definition: CGenericArray.h:236
cVector3d getTexCoordAtPosition(const unsigned int a_segmentIndex, const cVector3d &a_localPos)
Definition: CSegmentArray.h:329
This structure stores the collision settings that are passed to a collision detector when querying fo...
Definition: CCollisionBasics.h:242
virtual unsigned int getNumElements()
This method returns the number of allocated elements.
Definition: CGenericArray.h:145
GLuint m_elementBuffer
OpenGL Buffer for storing elements.
Definition: CGenericArray.h:249
int newSegment(const unsigned int a_vertexIndex0, const unsigned int a_vertexIndex1)
Definition: CSegmentArray.h:180
virtual bool computeCollision(const unsigned int a_elementIndex, cGenericObject *a_object, cVector3d &a_segmentPointA, cVector3d &a_segmentPointB, cCollisionRecorder &a_recorder, cCollisionSettings &a_settings) const
This method checks if the given line segment intersects a selected segment from this array...
Definition: CSegmentArray.cpp:73
std::shared_ptr< cVertexArray > cVertexArrayPtr
Definition: CVertexArray.h:107
This class implements an array of 3D segments.
Definition: CSegmentArray.h:103
virtual unsigned int getNumVerticesPerElement()
This method returns the number of vertices that compose a segment.
Definition: CSegmentArray.h:161
unsigned int getVertexIndex1(const unsigned int a_segmentIndex) const
Definition: CSegmentArray.h:289
Definition: CAudioBuffer.cpp:56
This class implements an abstract class for describing geometrical elements composed of vertices...
Definition: CGenericArray.h:90
void removeSegment(const unsigned int a_segmentIndex)
Definition: CSegmentArray.h:223
bool m_flagMarkForResize
If true then element array size has changed.
Definition: CGenericArray.h:239
unsigned int getVertexIndex0(const unsigned int a_segmentIndex) const
Definition: CSegmentArray.h:274
cVertexArrayPtr m_vertices
Vertex array that contains all vertices used to describe the elements of this array.
Definition: CGenericArray.h:227
cSegmentArrayPtr copy()
This method create a copy of all segment data and returns a new segment array.
Definition: CSegmentArray.cpp:259