New getPrimitive function.
This searches for the primitive found in an OSG intersection query.
This commit is contained in:
@@ -1136,6 +1136,13 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\simgear\scene\util\NodeAndDrawableVisitor.hxx">
|
RelativePath="..\..\simgear\scene\util\NodeAndDrawableVisitor.hxx">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\simgear\scene\util\PrimitiveUtils.cxx">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\simgear\scene\util\PrimitiveUtils.hxx">
|
||||||
|
</File>
|
||||||
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\simgear\scene\util\QuadTreeBuilder.cxx">
|
RelativePath="..\..\simgear\scene\util\QuadTreeBuilder.cxx">
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ include_HEADERS = \
|
|||||||
SGTextureStateAttributeVisitor.hxx \
|
SGTextureStateAttributeVisitor.hxx \
|
||||||
SGUpdateVisitor.hxx \
|
SGUpdateVisitor.hxx \
|
||||||
NodeAndDrawableVisitor.hxx \
|
NodeAndDrawableVisitor.hxx \
|
||||||
|
PrimitiveUtils.hxx \
|
||||||
QuadTreeBuilder.hxx \
|
QuadTreeBuilder.hxx \
|
||||||
RenderConstants.hxx \
|
RenderConstants.hxx \
|
||||||
StateAttributeFactory.hxx \
|
StateAttributeFactory.hxx \
|
||||||
@@ -28,6 +29,7 @@ libsgutil_a_SOURCES = \
|
|||||||
SGStateAttributeVisitor.cxx \
|
SGStateAttributeVisitor.cxx \
|
||||||
SGTextureStateAttributeVisitor.cxx \
|
SGTextureStateAttributeVisitor.cxx \
|
||||||
NodeAndDrawableVisitor.cxx \
|
NodeAndDrawableVisitor.cxx \
|
||||||
|
PrimitiveUtils.cxx \
|
||||||
StateAttributeFactory.cxx \
|
StateAttributeFactory.cxx \
|
||||||
QuadTreeBuilder.cxx
|
QuadTreeBuilder.cxx
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,323 @@
|
|||||||
|
/* -*-c++-*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Tim Moore
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PrimitiveUtils.hxx"
|
||||||
|
|
||||||
|
using namespace osg;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class GetPrimitive : public PrimitiveFunctor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
simgear::Primitive result;
|
||||||
|
GetPrimitive(unsigned int primitiveIndex)
|
||||||
|
: _primitiveIndex(primitiveIndex), _primitivesSeen(0),
|
||||||
|
_vertexArrayPtr(0), _modeCache(0)
|
||||||
|
{
|
||||||
|
result.numVerts = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setVertexArray(unsigned int,const Vec2*)
|
||||||
|
{
|
||||||
|
notify(WARN)<<"GetPrimitive does not support Vec2* vertex arrays"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setVertexArray(unsigned int count,const Vec3* vertices)
|
||||||
|
{
|
||||||
|
_vertexArrayPtr = vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setVertexArray(unsigned int,const Vec4* )
|
||||||
|
{
|
||||||
|
notify(WARN)<<"GetPrimitive does not support Vec4* vertex arrays"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setVertexArray(unsigned int,const Vec2d*)
|
||||||
|
{
|
||||||
|
notify(WARN)<<"GetPrimitive does not support Vec2d* vertex arrays"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setVertexArray(unsigned int,const Vec3d*)
|
||||||
|
{
|
||||||
|
notify(WARN)<<"GetPrimitive does not support Vec3d* vertex arrays"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setVertexArray(unsigned int,const Vec4d* )
|
||||||
|
{
|
||||||
|
notify(WARN)<<"GetPrimitive does not support Vec4d* vertex arrays"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawArrays(GLenum mode_, GLint first, GLsizei count)
|
||||||
|
{
|
||||||
|
if (_primitiveIndex < _primitivesSeen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int numPrims = getNumPrims(mode_, count);
|
||||||
|
if (_primitivesSeen + numPrims < _primitiveIndex) {
|
||||||
|
_primitivesSeen += numPrims;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int primInSet = _primitiveIndex - _primitivesSeen;
|
||||||
|
switch (mode_) {
|
||||||
|
case GL_POINTS:
|
||||||
|
result.numVerts = 1;
|
||||||
|
result.vertices[0] = _vertexArrayPtr[first + primInSet];
|
||||||
|
break;
|
||||||
|
case GL_LINES:
|
||||||
|
result.numVerts = 2;
|
||||||
|
result.vertices[0] = _vertexArrayPtr[first + primInSet * 2];
|
||||||
|
result.vertices[1] = _vertexArrayPtr[first + primInSet * 2 + 1];
|
||||||
|
break;
|
||||||
|
case GL_TRIANGLES:
|
||||||
|
result.numVerts = 3;
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
result.vertices[i] = _vertexArrayPtr[first + primInSet * 3 + i];
|
||||||
|
break;
|
||||||
|
case GL_QUADS:
|
||||||
|
result.numVerts = 4;
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
|
result.vertices[i] = _vertexArrayPtr[first + primInSet * 4 + i];
|
||||||
|
break;
|
||||||
|
case GL_LINE_STRIP:
|
||||||
|
result.numVerts = 2;
|
||||||
|
result.vertices[0] = _vertexArrayPtr[first + primInSet];
|
||||||
|
result.vertices[1] = _vertexArrayPtr[first + primInSet + 1];
|
||||||
|
break;
|
||||||
|
case GL_LINE_LOOP:
|
||||||
|
result.numVerts = 2;
|
||||||
|
if (primInSet < numPrims - 1) {
|
||||||
|
result.vertices[0] = _vertexArrayPtr[first + primInSet];
|
||||||
|
result.vertices[1] = _vertexArrayPtr[first + primInSet + 1];
|
||||||
|
} else {
|
||||||
|
result.vertices[0] = _vertexArrayPtr[first + count - 1];
|
||||||
|
result.vertices[1] = _vertexArrayPtr[first];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GL_TRIANGLE_STRIP:
|
||||||
|
result.numVerts = 3;
|
||||||
|
result.vertices[0] = _vertexArrayPtr[first + primInSet];
|
||||||
|
if (primInSet % 2) {
|
||||||
|
result.vertices[1] = _vertexArrayPtr[first + primInSet + 2];
|
||||||
|
result.vertices[2] = _vertexArrayPtr[first + primInSet + 1];
|
||||||
|
} else {
|
||||||
|
result.vertices[1] = _vertexArrayPtr[first + primInSet + 1];
|
||||||
|
result.vertices[2] = _vertexArrayPtr[first + primInSet + 2];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GL_TRIANGLE_FAN:
|
||||||
|
case GL_POLYGON:
|
||||||
|
result.numVerts = 3;
|
||||||
|
result.vertices[0] = _vertexArrayPtr[first];
|
||||||
|
result.vertices[1] = _vertexArrayPtr[first + 1 + primInSet];
|
||||||
|
result.vertices[2] = _vertexArrayPtr[first + 1 + primInSet + 1];
|
||||||
|
break;
|
||||||
|
case GL_QUAD_STRIP:
|
||||||
|
result.numVerts = 4;
|
||||||
|
result.vertices[0] = _vertexArrayPtr[first + primInSet / 2];
|
||||||
|
result.vertices[1] = _vertexArrayPtr[first + primInSet / 2 + 1];
|
||||||
|
result.vertices[2] = _vertexArrayPtr[first + primInSet / 2 + 3];
|
||||||
|
result.vertices[3] = _vertexArrayPtr[first + primInSet / 2 + 2];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_primitivesSeen += numPrims;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class IndexType>
|
||||||
|
void drawElementsTemplate(GLenum mode_, GLsizei count,
|
||||||
|
const IndexType* indices)
|
||||||
|
{
|
||||||
|
if (_primitiveIndex < _primitivesSeen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int numPrims = getNumPrims(mode_, count);
|
||||||
|
if (_primitivesSeen + numPrims < _primitiveIndex) {
|
||||||
|
_primitivesSeen += numPrims;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int primInSet = _primitiveIndex - _primitivesSeen;
|
||||||
|
switch (mode_) {
|
||||||
|
case GL_POINTS:
|
||||||
|
result.numVerts = 1;
|
||||||
|
result.vertices[0] = _vertexArrayPtr[indices[primInSet]];
|
||||||
|
break;
|
||||||
|
case GL_LINES:
|
||||||
|
result.numVerts = 2;
|
||||||
|
result.vertices[0] = _vertexArrayPtr[indices[primInSet * 2]];
|
||||||
|
result.vertices[1] = _vertexArrayPtr[indices[primInSet * 2 + 1]];
|
||||||
|
break;
|
||||||
|
case GL_TRIANGLES:
|
||||||
|
result.numVerts = 3;
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
result.vertices[i] = _vertexArrayPtr[indices[primInSet * 3 + i]];
|
||||||
|
break;
|
||||||
|
case GL_QUADS:
|
||||||
|
result.numVerts = 4;
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
|
result.vertices[i] = _vertexArrayPtr[indices[primInSet * 4 + i]];
|
||||||
|
break;
|
||||||
|
case GL_LINE_STRIP:
|
||||||
|
result.numVerts = 2;
|
||||||
|
result.vertices[0] = _vertexArrayPtr[indices[primInSet]];
|
||||||
|
result.vertices[1] = _vertexArrayPtr[indices[primInSet + 1]];
|
||||||
|
break;
|
||||||
|
case GL_LINE_LOOP:
|
||||||
|
result.numVerts = 2;
|
||||||
|
if (primInSet < numPrims - 1) {
|
||||||
|
result.vertices[0] = _vertexArrayPtr[indices[primInSet]];
|
||||||
|
result.vertices[1] = _vertexArrayPtr[indices[primInSet + 1]];
|
||||||
|
} else {
|
||||||
|
result.vertices[0] = _vertexArrayPtr[indices[count - 1]];
|
||||||
|
result.vertices[1] = _vertexArrayPtr[indices[0]];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GL_TRIANGLE_STRIP:
|
||||||
|
result.numVerts = 3;
|
||||||
|
result.vertices[0] = _vertexArrayPtr[indices[primInSet]];
|
||||||
|
if (primInSet % 2) {
|
||||||
|
result.vertices[1] = _vertexArrayPtr[indices[primInSet + 2]];
|
||||||
|
result.vertices[2] = _vertexArrayPtr[indices[primInSet + 1]];
|
||||||
|
} else {
|
||||||
|
result.vertices[1] = _vertexArrayPtr[indices[primInSet + 1]];
|
||||||
|
result.vertices[2] = _vertexArrayPtr[indices[primInSet + 2]];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GL_TRIANGLE_FAN:
|
||||||
|
case GL_POLYGON:
|
||||||
|
result.numVerts = 3;
|
||||||
|
result.vertices[0] = _vertexArrayPtr[indices[0]];
|
||||||
|
result.vertices[1] = _vertexArrayPtr[indices[1 + primInSet]];
|
||||||
|
result.vertices[2] = _vertexArrayPtr[indices[1 + primInSet + 1]];
|
||||||
|
break;
|
||||||
|
case GL_QUAD_STRIP:
|
||||||
|
result.numVerts = 4;
|
||||||
|
result.vertices[0] = _vertexArrayPtr[indices[primInSet / 2]];
|
||||||
|
result.vertices[1] = _vertexArrayPtr[indices[primInSet / 2 + 1]];
|
||||||
|
result.vertices[2] = _vertexArrayPtr[indices[primInSet / 2 + 3]];
|
||||||
|
result.vertices[3] = _vertexArrayPtr[indices[primInSet / 2 + 2]];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_primitivesSeen += numPrims;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawElements(GLenum mode_, GLsizei count, const GLubyte* indices)
|
||||||
|
{
|
||||||
|
drawElementsTemplate(mode_, count, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawElements(GLenum mode_, GLsizei count, const GLushort* indices)
|
||||||
|
{
|
||||||
|
drawElementsTemplate(mode_, count, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawElements(GLenum mode_,GLsizei count,const GLuint* indices)
|
||||||
|
{
|
||||||
|
drawElementsTemplate(mode_, count, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void begin(GLenum mode)
|
||||||
|
{
|
||||||
|
_modeCache = mode;
|
||||||
|
_vertexCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void vertex(const Vec2& vert)
|
||||||
|
{
|
||||||
|
_vertexCache.push_back(osg::Vec3(vert[0],vert[1],0.0f));
|
||||||
|
}
|
||||||
|
void vertex(const Vec3& vert)
|
||||||
|
{
|
||||||
|
_vertexCache.push_back(vert);
|
||||||
|
}
|
||||||
|
void vertex(const Vec4& vert)
|
||||||
|
{
|
||||||
|
_vertexCache.push_back(osg::Vec3(vert[0],vert[1],vert[2])/vert[3]);
|
||||||
|
}
|
||||||
|
void vertex(float x,float y)
|
||||||
|
{
|
||||||
|
_vertexCache.push_back(osg::Vec3(x,y,0.0f));
|
||||||
|
}
|
||||||
|
void vertex(float x,float y,float z)
|
||||||
|
{
|
||||||
|
_vertexCache.push_back(osg::Vec3(x,y,z));
|
||||||
|
}
|
||||||
|
void vertex(float x,float y,float z,float w)
|
||||||
|
{
|
||||||
|
_vertexCache.push_back(osg::Vec3(x,y,z)/w);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void end()
|
||||||
|
{
|
||||||
|
if (!_vertexCache.empty()) {
|
||||||
|
const Vec3* oldVert = _vertexArrayPtr;
|
||||||
|
setVertexArray(_vertexCache.size(), &_vertexCache.front());
|
||||||
|
drawArrays(_modeCache, 0, _vertexCache.size());
|
||||||
|
_vertexArrayPtr = oldVert;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int getNumPrims(GLenum mode, int count)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case GL_POINTS:
|
||||||
|
return count;
|
||||||
|
case GL_LINES:
|
||||||
|
return count / 2;
|
||||||
|
case GL_TRIANGLES:
|
||||||
|
return count / 3;
|
||||||
|
case GL_QUADS:
|
||||||
|
return count / 4;
|
||||||
|
case GL_LINE_STRIP:
|
||||||
|
return count - 1;
|
||||||
|
case GL_LINE_LOOP:
|
||||||
|
return count;
|
||||||
|
case GL_TRIANGLE_STRIP:
|
||||||
|
return count - 2;
|
||||||
|
case GL_TRIANGLE_FAN:
|
||||||
|
case GL_POLYGON:
|
||||||
|
return count - 2;
|
||||||
|
case GL_QUAD_STRIP:
|
||||||
|
return (count - 2) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsigned _primitiveIndex;
|
||||||
|
unsigned _primitivesSeen;
|
||||||
|
const Vec3* _vertexArrayPtr;
|
||||||
|
GLenum _modeCache;
|
||||||
|
std::vector<Vec3> _vertexCache;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace simgear
|
||||||
|
{
|
||||||
|
Primitive getPrimitive(Drawable* drawable, unsigned primitiveIndex)
|
||||||
|
{
|
||||||
|
GetPrimitive getPrim(primitiveIndex);
|
||||||
|
drawable->accept(getPrim);
|
||||||
|
return getPrim.result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/* -*-c++-*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Tim Moore
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SIMGEAR_PRIMITIVEUTILS_HXX
|
||||||
|
#define SIMGEAR_PRIMITIVEUTILS_HXX 1
|
||||||
|
|
||||||
|
#include <osg/Vec3>
|
||||||
|
#include <osg/Drawable>
|
||||||
|
|
||||||
|
namespace simgear
|
||||||
|
{
|
||||||
|
struct Primitive
|
||||||
|
{
|
||||||
|
int numVerts;
|
||||||
|
osg::Vec3 vertices[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a drawable and a primitive index (as returned from OSG
|
||||||
|
* intersection queries), get the coordinates of the primitives
|
||||||
|
* vertices.
|
||||||
|
*/
|
||||||
|
Primitive getPrimitive(osg::Drawable* drawable, unsigned primitiveIndex);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user