From Mike Garrity, "There was an on again/off again thread on OSG users about
creating subclasses of osg::Array that referenced data stored an application's internal data structures. I took a stab at implementing that and ran into a couple of downcasts in Geometry.cpp. Enclosed is my take at fixing those along with a simple example of how to do this."
This commit is contained in:
parent
669e86145c
commit
be5f709bdb
@ -78,6 +78,7 @@ IF(DYNAMIC_OPENSCENEGRAPH)
|
||||
ADD_SUBDIRECTORY(osgslice)
|
||||
ADD_SUBDIRECTORY(osgspacewarp)
|
||||
ADD_SUBDIRECTORY(osgspheresegment)
|
||||
ADD_SUBDIRECTORY(osgsharedarray)
|
||||
ADD_SUBDIRECTORY(osgspotlight)
|
||||
ADD_SUBDIRECTORY(osgstereoimage)
|
||||
ADD_SUBDIRECTORY(osgteapot)
|
||||
|
7
examples/osgsharedarray/CMakeLists.txt
Normal file
7
examples/osgsharedarray/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
#this file is automatically generated
|
||||
|
||||
|
||||
SET(TARGET_SRC osgsharedarray.cpp )
|
||||
SET(TARGET_EXTERNAL_LIBRARIES ${OPENGL_LIBRARIES} )
|
||||
#### end var setup ###
|
||||
SETUP_EXAMPLE(osgsharedarray)
|
246
examples/osgsharedarray/osgsharedarray.cpp
Normal file
246
examples/osgsharedarray/osgsharedarray.cpp
Normal file
@ -0,0 +1,246 @@
|
||||
/* OpenSceneGraph example, osgsharedarray.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <osg/Array>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Geometry>
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
/** This class is an example of how to create your own subclass of osg::Array. This
|
||||
* is useful if your application has data in its own form of storage and you don't
|
||||
* want to make another copy into one of the predefined osg::Array classes.
|
||||
*
|
||||
* @note This is not really intended to be a useful subclass of osg::Array. It
|
||||
* doesn't do anything smart about memory management. It is simply intended as
|
||||
* an example you can follow to create your own subclasses of osg::Array for
|
||||
* your application's storage requirements.
|
||||
*/
|
||||
class MyArray : public osg::Array {
|
||||
public:
|
||||
/** Default ctor. Creates an empty array. */
|
||||
MyArray() :
|
||||
osg::Array(osg::Array::Vec3ArrayType,3,GL_FLOAT),
|
||||
_numElements(0),
|
||||
_ptr(NULL) {
|
||||
}
|
||||
|
||||
/** "Normal" ctor.
|
||||
*
|
||||
* @param no The number of elements in the array.
|
||||
* @param ptr Pointer to the data. This class just keeps that
|
||||
* pointer. It doesn't manage the memory.
|
||||
*/
|
||||
MyArray(unsigned int no, osg::Vec3* ptr) :
|
||||
osg::Array(osg::Array::Vec3ArrayType,3,GL_FLOAT),
|
||||
_numElements(no),
|
||||
_ptr(ptr) {
|
||||
}
|
||||
|
||||
/** Copy ctor. */
|
||||
MyArray(const MyArray& other, const osg::CopyOp& copyop) :
|
||||
osg::Array(osg::Array::Vec3ArrayType,3,GL_FLOAT),
|
||||
_numElements(other._numElements),
|
||||
_ptr(other._ptr) {
|
||||
}
|
||||
|
||||
/** What type of object would clone return? */
|
||||
virtual Object* cloneType() const {
|
||||
return new MyArray();
|
||||
}
|
||||
|
||||
/** Create a copy of the object. */
|
||||
virtual osg::Object* clone(const osg::CopyOp& copyop) const {
|
||||
return new MyArray(*this,copyop);
|
||||
}
|
||||
|
||||
/** Accept method for ArrayVisitors.
|
||||
*
|
||||
* @note This will end up in ArrayVisitor::apply(osg::Array&).
|
||||
*/
|
||||
virtual void accept(osg::ArrayVisitor& av) {
|
||||
av.apply(*this);
|
||||
}
|
||||
|
||||
/** Const accept method for ArrayVisitors.
|
||||
*
|
||||
* @note This will end up in ConstArrayVisitor::apply(const osg::Array&).
|
||||
*/
|
||||
virtual void accept(osg::ConstArrayVisitor& cav) const {
|
||||
cav.apply(*this);
|
||||
}
|
||||
|
||||
/** Accept method for ValueVisitors. */
|
||||
virtual void accept(unsigned int index, osg::ValueVisitor& vv) {
|
||||
vv.apply(_ptr[index]);
|
||||
}
|
||||
|
||||
/** Const accept method for ValueVisitors. */
|
||||
virtual void accept(unsigned int index, osg::ConstValueVisitor& cvv) const {
|
||||
cvv.apply(_ptr[index]);
|
||||
}
|
||||
|
||||
/** Compare method.
|
||||
* Return -1 if lhs element is less than rhs element, 0 if equal,
|
||||
* 1 if lhs element is greater than rhs element.
|
||||
*/
|
||||
virtual int compare(unsigned int lhs,unsigned int rhs) const {
|
||||
const osg::Vec3& elem_lhs = _ptr[lhs];
|
||||
const osg::Vec3& elem_rhs = _ptr[rhs];
|
||||
if (elem_lhs<elem_rhs) return -1;
|
||||
if (elem_rhs<elem_lhs) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Returns a pointer to the first element of the array. */
|
||||
virtual const GLvoid* getDataPointer() const {
|
||||
return _ptr;
|
||||
}
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
virtual unsigned int getNumElements() const {
|
||||
return _numElements;
|
||||
}
|
||||
|
||||
/** Returns the number of bytes of storage required to hold
|
||||
* all of the elements of the array.
|
||||
*/
|
||||
virtual unsigned int getTotalDataSize() const {
|
||||
return _numElements * sizeof(osg::Vec3);
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int _numElements;
|
||||
osg::Vec3* _ptr;
|
||||
};
|
||||
|
||||
/** The data values for the example. Simply defines a cube with
|
||||
* per-face colors and normals.
|
||||
*/
|
||||
namespace {
|
||||
|
||||
static const osg::Vec3 myVertices[] = { osg::Vec3(-1.,-1.,-1.),
|
||||
osg::Vec3( 1.,-1.,-1.),
|
||||
osg::Vec3(-1., 1.,-1.),
|
||||
osg::Vec3( 1., 1.,-1.),
|
||||
osg::Vec3(-1.,-1., 1.),
|
||||
osg::Vec3( 1.,-1., 1.),
|
||||
osg::Vec3(-1., 1., 1.),
|
||||
osg::Vec3( 1., 1., 1.)
|
||||
};
|
||||
|
||||
static const osg::Vec3 myNormals[] = { osg::Vec3( 0., 0., 1.),
|
||||
osg::Vec3( 1., 0., 0.),
|
||||
osg::Vec3( 0., 0.,-1.),
|
||||
osg::Vec3(-1., 0., 0.),
|
||||
osg::Vec3( 0., 1., 0.),
|
||||
osg::Vec3( 0.,-1., 0.)
|
||||
};
|
||||
|
||||
static const osg::Vec4 myColors[] = { osg::Vec4( 1., 0., 0., 1.),
|
||||
osg::Vec4( 0., 1., 0., 1.),
|
||||
osg::Vec4( 1., 1., 0., 1.),
|
||||
osg::Vec4( 0., 0., 1., 1.),
|
||||
osg::Vec4( 1., 0., 1., 1.),
|
||||
osg::Vec4( 0., 1., 1., 1.)
|
||||
};
|
||||
|
||||
static const unsigned short myIndices[] = { 4, 5, 7, 6,
|
||||
5, 1, 3, 7,
|
||||
1, 0, 2, 3,
|
||||
0, 4, 6, 2,
|
||||
6, 7, 3, 2,
|
||||
0, 1, 5, 4
|
||||
};
|
||||
}
|
||||
|
||||
/** Create a Geode that describes a cube using our own
|
||||
* subclass of osg::Array for the vertices. It uses
|
||||
* the "regular" array classes for all of the other
|
||||
* arrays.
|
||||
*
|
||||
* Creating your own Array class isn't really very
|
||||
* useful for a tiny amount of data like this. You
|
||||
* could just go ahead and copy the data into one of
|
||||
* the "regular" Array classes like this does for
|
||||
* normals and colors. The point of creating your
|
||||
* own subclass of Array is for use with datasets
|
||||
* that are much larger than anything you could
|
||||
* create a simple example from. In that case, you
|
||||
* might not want to create a copy of the data in
|
||||
* one of the Array classes that comes with OSG, but
|
||||
* instead reuse the copy your application already
|
||||
* has and wrap it up in a subclass of osg::Array
|
||||
* that presents the right interface for use with
|
||||
* OpenSceneGraph.
|
||||
*
|
||||
* Note that I'm only using the shared array for the
|
||||
* vertices. You could do something similar for any
|
||||
* of the Geometry node's data arrays.
|
||||
*/
|
||||
osg::Geode* createGeometry()
|
||||
{
|
||||
osg::Geode* geode = new osg::Geode();
|
||||
|
||||
// create Geometry
|
||||
osg::ref_ptr<osg::Geometry> geom(new osg::Geometry());
|
||||
|
||||
// add vertices using MyArray class
|
||||
unsigned int numVertices = sizeof(myVertices)/sizeof(myVertices[0]);
|
||||
geom->setVertexArray(new MyArray(numVertices,const_cast<osg::Vec3*>(&myVertices[0])));
|
||||
|
||||
// add normals
|
||||
unsigned int numNormals = sizeof(myNormals)/sizeof(myNormals[0]);
|
||||
geom->setNormalArray(new osg::Vec3Array(numNormals,const_cast<osg::Vec3*>(&myNormals[0])));
|
||||
geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
|
||||
|
||||
// add colors
|
||||
unsigned int numColors = sizeof(myColors)/sizeof(myColors[0]);
|
||||
osg::Vec4Array* normal_array = new osg::Vec4Array(numColors,const_cast<osg::Vec4*>(&myColors[0]));
|
||||
geom->setColorArray(normal_array);
|
||||
geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE);
|
||||
|
||||
// add PrimitiveSet
|
||||
unsigned int numIndices = sizeof(myIndices)/sizeof(myIndices[0]);
|
||||
geom->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS,
|
||||
numIndices,
|
||||
const_cast<unsigned short *>(myIndices)));
|
||||
|
||||
// Changing these flags will tickle different cases in
|
||||
// Geometry::drawImplementation. They should all work fine
|
||||
// with the shared array. Setting VertexIndices will hit
|
||||
// some other cases.
|
||||
geom->setUseVertexBufferObjects(false);
|
||||
geom->setUseDisplayList(false);
|
||||
geom->setFastPathHint(false);
|
||||
|
||||
geode->addDrawable( geom.get() );
|
||||
|
||||
return geode;
|
||||
}
|
||||
|
||||
int main(int , char **)
|
||||
{
|
||||
// construct the viewer.
|
||||
osgViewer::Viewer viewer;
|
||||
|
||||
// add model to viewer.
|
||||
viewer.setSceneData( createGeometry() );
|
||||
|
||||
// create the windows and run the threads.
|
||||
return viewer.run();
|
||||
}
|
@ -229,6 +229,8 @@ class TemplateArray : public Array, public std::vector<T>
|
||||
virtual unsigned int getTotalDataSize() const { return this->size()*sizeof(T); }
|
||||
virtual unsigned int getNumElements() const { return this->size(); }
|
||||
|
||||
typedef T ElementDataType; // expose T
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~TemplateArray() {}
|
||||
@ -315,6 +317,8 @@ class TemplateIndexArray : public IndexArray, public std::vector<T>
|
||||
|
||||
virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; }
|
||||
|
||||
typedef T ElementDataType; // expose T
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~TemplateIndexArray() {}
|
||||
|
@ -33,15 +33,13 @@ class DrawVertex
|
||||
|
||||
inline unsigned int index(unsigned int pos)
|
||||
{
|
||||
switch(_indicesType)
|
||||
if (_indices)
|
||||
{
|
||||
case(Array::ByteArrayType): return (*static_cast<const ByteArray*>(_indices))[pos];
|
||||
case(Array::ShortArrayType): return (*static_cast<const ShortArray*>(_indices))[pos];
|
||||
case(Array::IntArrayType): return (*static_cast<const IntArray*>(_indices))[pos];
|
||||
case(Array::UByteArrayType): return (*static_cast<const UByteArray*>(_indices))[pos];
|
||||
case(Array::UShortArrayType): return (*static_cast<const UShortArray*>(_indices))[pos];
|
||||
case(Array::UIntArrayType): return (*static_cast<const UIntArray*>(_indices))[pos];
|
||||
default: return 0;
|
||||
return _indices->index(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,22 +50,22 @@ class DrawVertex
|
||||
switch(_verticesType)
|
||||
{
|
||||
case(Array::Vec3ArrayType):
|
||||
apply((*(static_cast<const Vec3Array*>(_vertices)))[pos]);
|
||||
apply(static_cast<const Vec3*>(_vertices->getDataPointer())[pos]);
|
||||
break;
|
||||
case(Array::Vec2ArrayType):
|
||||
apply((*(static_cast<const Vec2Array*>(_vertices)))[pos]);
|
||||
apply(static_cast<const Vec2*>(_vertices->getDataPointer())[pos]);
|
||||
break;
|
||||
case(Array::Vec4ArrayType):
|
||||
apply((*(static_cast<const Vec4Array*>(_vertices)))[pos]);
|
||||
apply(static_cast<const Vec4*>(_vertices->getDataPointer())[pos]);
|
||||
break;
|
||||
case(Array::Vec3dArrayType):
|
||||
apply((*(static_cast<const Vec3dArray*>(_vertices)))[pos]);
|
||||
apply(static_cast<const Vec3d*>(_vertices->getDataPointer())[pos]);
|
||||
break;
|
||||
case(Array::Vec2dArrayType):
|
||||
apply((*(static_cast<const Vec2dArray*>(_vertices)))[pos]);
|
||||
apply(static_cast<const Vec2d*>(_vertices->getDataPointer())[pos]);
|
||||
break;
|
||||
case(Array::Vec4dArrayType):
|
||||
apply((*(static_cast<const Vec4dArray*>(_vertices)))[pos]);
|
||||
apply(static_cast<const Vec4d*>(_vertices->getDataPointer())[pos]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -105,39 +103,53 @@ class DrawNormal
|
||||
{
|
||||
case (Array::Vec3ArrayType):
|
||||
{
|
||||
const Vec3Array& normals = *static_cast<const Vec3Array*>(_normals);
|
||||
const Vec3* normals(static_cast<const Vec3*>(_normals->getDataPointer()));
|
||||
if (_indices) glNormal3fv(normals[_indices->index(pos)].ptr());
|
||||
else glNormal3fv(normals[pos].ptr());
|
||||
}
|
||||
break;
|
||||
case (Array::Vec3sArrayType):
|
||||
{
|
||||
const Vec3sArray& normals = *static_cast<const Vec3sArray*>(_normals);
|
||||
const Vec3s* normals(static_cast<const Vec3s*>(_normals->getDataPointer()));
|
||||
if (_indices) glNormal3sv(normals[_indices->index(pos)].ptr());
|
||||
else glNormal3sv(normals[pos].ptr());
|
||||
}
|
||||
break;
|
||||
case (Array::Vec4sArrayType):
|
||||
{
|
||||
const Vec4sArray& normals = *static_cast<const Vec4sArray*>(_normals);
|
||||
const Vec4s* normals(static_cast<const Vec4s*>(_normals->getDataPointer()));
|
||||
if (_indices) glNormal3sv(normals[_indices->index(pos)].ptr());
|
||||
else glNormal3sv(normals[pos].ptr());
|
||||
}
|
||||
break;
|
||||
case (Array::Vec3bArrayType):
|
||||
{
|
||||
const Vec3bArray& normals = *static_cast<const Vec3bArray*>(_normals);
|
||||
const Vec3b* normals(static_cast<const Vec3b*>(_normals->getDataPointer()));
|
||||
if (_indices) glNormal3bv((const GLbyte*)normals[_indices->index(pos)].ptr());
|
||||
else glNormal3bv((const GLbyte*)normals[pos].ptr());
|
||||
}
|
||||
break;
|
||||
case (Array::Vec4bArrayType):
|
||||
{
|
||||
const Vec4bArray& normals = *static_cast<const Vec4bArray*>(_normals);
|
||||
const Vec4b* normals(static_cast<const Vec4b*>(_normals->getDataPointer()));
|
||||
if (_indices) glNormal3bv((const GLbyte*)normals[_indices->index(pos)].ptr());
|
||||
else glNormal3bv((const GLbyte*)normals[pos].ptr());
|
||||
}
|
||||
break;
|
||||
case (Array::Vec3dArrayType):
|
||||
{
|
||||
const Vec3d* normals(static_cast<const Vec3d*>(_normals->getDataPointer()));
|
||||
if (_indices) glNormal3dv(normals[_indices->index(pos)].ptr());
|
||||
else glNormal3dv(normals[pos].ptr());
|
||||
}
|
||||
break;
|
||||
case (Array::Vec4dArrayType):
|
||||
{
|
||||
const Vec4d* normals(static_cast<const Vec4d*>(_normals->getDataPointer()));
|
||||
if (_indices) glNormal3dv(normals[_indices->index(pos)].ptr());
|
||||
else glNormal3dv(normals[pos].ptr());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -163,15 +175,11 @@ class DrawColor
|
||||
|
||||
inline unsigned int index(unsigned int pos)
|
||||
{
|
||||
switch(_indicesType)
|
||||
{
|
||||
case(Array::ByteArrayType): return (*static_cast<const ByteArray*>(_indices))[pos];
|
||||
case(Array::ShortArrayType): return (*static_cast<const ShortArray*>(_indices))[pos];
|
||||
case(Array::IntArrayType): return (*static_cast<const IntArray*>(_indices))[pos];
|
||||
case(Array::UByteArrayType): return (*static_cast<const UByteArray*>(_indices))[pos];
|
||||
case(Array::UShortArrayType): return (*static_cast<const UShortArray*>(_indices))[pos];
|
||||
case(Array::UIntArrayType): return (*static_cast<const UIntArray*>(_indices))[pos];
|
||||
default: return 0;
|
||||
if (_indices) {
|
||||
return _indices->index(pos);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,13 +190,19 @@ class DrawColor
|
||||
switch(_colorsType)
|
||||
{
|
||||
case(Array::Vec4ArrayType):
|
||||
apply((*static_cast<const Vec4Array*>(_colors))[pos]);
|
||||
apply(static_cast<const Vec4*>(_colors->getDataPointer())[pos]);
|
||||
break;
|
||||
case(Array::Vec4ubArrayType):
|
||||
apply((*static_cast<const Vec4ubArray*>(_colors))[pos]);
|
||||
apply(static_cast<const Vec4ub*>(_colors->getDataPointer())[pos]);
|
||||
break;
|
||||
case(Array::Vec3ArrayType):
|
||||
apply((*static_cast<const Vec3Array*>(_colors))[pos]);
|
||||
apply(static_cast<const Vec3*>(_colors->getDataPointer())[pos]);
|
||||
break;
|
||||
case(Array::Vec3dArrayType):
|
||||
apply(static_cast<const Vec3d*>(_colors->getDataPointer())[pos]);
|
||||
break;
|
||||
case(Array::Vec4dArrayType):
|
||||
apply(static_cast<const Vec4d*>(_colors->getDataPointer())[pos]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -2220,32 +2234,32 @@ void Geometry::accept(PrimitiveFunctor& functor) const
|
||||
}
|
||||
else
|
||||
{
|
||||
const Vec2Array* vec2Array = 0;
|
||||
const Vec3Array* vec3Array = 0;
|
||||
const Vec4Array* vec4Array = 0;
|
||||
const Vec2dArray* vec2dArray = 0;
|
||||
const Vec3dArray* vec3dArray = 0;
|
||||
const Vec4dArray* vec4dArray = 0;
|
||||
const Vec2* vec2Array = 0;
|
||||
const Vec3* vec3Array = 0;
|
||||
const Vec4* vec4Array = 0;
|
||||
const Vec2d* vec2dArray = 0;
|
||||
const Vec3d* vec3dArray = 0;
|
||||
const Vec4d* vec4dArray = 0;
|
||||
Array::Type type = _vertexData.array->getType();
|
||||
switch(type)
|
||||
{
|
||||
case(Array::Vec2ArrayType):
|
||||
vec2Array = static_cast<const Vec2Array*>(_vertexData.array.get());
|
||||
vec2Array = static_cast<const Vec2*>(_vertexData.array->getDataPointer());
|
||||
break;
|
||||
case(Array::Vec3ArrayType):
|
||||
vec3Array = static_cast<const Vec3Array*>(_vertexData.array.get());
|
||||
vec3Array = static_cast<const Vec3*>(_vertexData.array->getDataPointer());
|
||||
break;
|
||||
case(Array::Vec4ArrayType):
|
||||
vec4Array = static_cast<const Vec4Array*>(_vertexData.array.get());
|
||||
vec4Array = static_cast<const Vec4*>(_vertexData.array->getDataPointer());
|
||||
break;
|
||||
case(Array::Vec2dArrayType):
|
||||
vec2dArray = static_cast<const Vec2dArray*>(_vertexData.array.get());
|
||||
vec2dArray = static_cast<const Vec2d*>(_vertexData.array->getDataPointer());
|
||||
break;
|
||||
case(Array::Vec3dArrayType):
|
||||
vec3dArray = static_cast<const Vec3dArray*>(_vertexData.array.get());
|
||||
vec3dArray = static_cast<const Vec3d*>(_vertexData.array->getDataPointer());
|
||||
break;
|
||||
case(Array::Vec4dArrayType):
|
||||
vec4dArray = static_cast<const Vec4dArray*>(_vertexData.array.get());
|
||||
vec4dArray = static_cast<const Vec4d*>(_vertexData.array->getDataPointer());
|
||||
break;
|
||||
default:
|
||||
notify(WARN)<<"Warning: Geometry::accept(PrimitiveFunctor&) cannot handle Vertex Array type"<<_vertexData.array->getType()<<std::endl;
|
||||
@ -2274,22 +2288,22 @@ void Geometry::accept(PrimitiveFunctor& functor) const
|
||||
switch(type)
|
||||
{
|
||||
case(Array::Vec2ArrayType):
|
||||
functor.vertex((*vec2Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec2Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec3ArrayType):
|
||||
functor.vertex((*vec3Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec3Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec4ArrayType):
|
||||
functor.vertex((*vec4Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec4Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec2dArrayType):
|
||||
functor.vertex((*vec2Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec2dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec3dArrayType):
|
||||
functor.vertex((*vec3Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec3dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec4dArrayType):
|
||||
functor.vertex((*vec4Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec4dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -2317,22 +2331,22 @@ void Geometry::accept(PrimitiveFunctor& functor) const
|
||||
switch(type)
|
||||
{
|
||||
case(Array::Vec2ArrayType):
|
||||
functor.vertex((*vec2Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec2Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec3ArrayType):
|
||||
functor.vertex((*vec3Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec3Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec4ArrayType):
|
||||
functor.vertex((*vec4Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec4Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec2dArrayType):
|
||||
functor.vertex((*vec2Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec2dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec3dArrayType):
|
||||
functor.vertex((*vec3Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec3dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec4dArrayType):
|
||||
functor.vertex((*vec4Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec4dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -2359,22 +2373,22 @@ void Geometry::accept(PrimitiveFunctor& functor) const
|
||||
switch(type)
|
||||
{
|
||||
case(Array::Vec2ArrayType):
|
||||
functor.vertex((*vec2Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec2Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec3ArrayType):
|
||||
functor.vertex((*vec3Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec3Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec4ArrayType):
|
||||
functor.vertex((*vec4Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec4Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec2dArrayType):
|
||||
functor.vertex((*vec2dArray)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec2dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec3dArrayType):
|
||||
functor.vertex((*vec3dArray)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec3dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec4dArrayType):
|
||||
functor.vertex((*vec4dArray)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec4dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -2397,22 +2411,22 @@ void Geometry::accept(PrimitiveFunctor& functor) const
|
||||
switch(type)
|
||||
{
|
||||
case(Array::Vec2ArrayType):
|
||||
functor.vertex((*vec2Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec2Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec3ArrayType):
|
||||
functor.vertex((*vec3Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec3Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec4ArrayType):
|
||||
functor.vertex((*vec4Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec4Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec2dArrayType):
|
||||
functor.vertex((*vec2dArray)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec2dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec3dArrayType):
|
||||
functor.vertex((*vec3dArray)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec3dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec4dArrayType):
|
||||
functor.vertex((*vec4dArray)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec4dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -2435,22 +2449,22 @@ void Geometry::accept(PrimitiveFunctor& functor) const
|
||||
switch(type)
|
||||
{
|
||||
case(Array::Vec2ArrayType):
|
||||
functor.vertex((*vec2Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec2Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec3ArrayType):
|
||||
functor.vertex((*vec3Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec3Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec4ArrayType):
|
||||
functor.vertex((*vec4Array)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec4Array[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec2dArrayType):
|
||||
functor.vertex((*vec2dArray)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec2dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec3dArrayType):
|
||||
functor.vertex((*vec3dArray)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec3dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
case(Array::Vec4dArrayType):
|
||||
functor.vertex((*vec4dArray)[_vertexData.indices->index(vindex)]);
|
||||
functor.vertex(vec4dArray[_vertexData.indices->index(vindex)]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -2889,8 +2903,11 @@ class ExpandIndexedArray : public osg::ConstArrayVisitor
|
||||
|
||||
virtual ~ExpandIndexedArray() {}
|
||||
|
||||
// Create when both of the arrays are predefined templated classes. We
|
||||
// can do some optimizations in this case that aren't possible in the general
|
||||
// case.
|
||||
template <class T,class I>
|
||||
T* create(const T& array,const I& indices)
|
||||
T* create_inline(const T& array,const I& indices)
|
||||
{
|
||||
T* newArray = 0;
|
||||
|
||||
@ -2919,22 +2936,84 @@ class ExpandIndexedArray : public osg::ConstArrayVisitor
|
||||
return newArray;
|
||||
}
|
||||
|
||||
// Create when one of the arrays isn't one of the predefined templated classes. The
|
||||
// template parameter is the type of the array that will get created. This is always
|
||||
// one of the predefined classes. We could call clone to get one of the same type as
|
||||
// the input array, but the interface of the osg::Array class doesn't include a way
|
||||
// to set an element.
|
||||
template <class T>
|
||||
T* create(const T& array)
|
||||
osg::Array* create_noinline(const osg::Array& array, const osg::IndexArray& indices) {
|
||||
T* newArray = 0;
|
||||
typedef typename T::ElementDataType EDT;
|
||||
|
||||
unsigned int num_indices = indices.getNumElements();
|
||||
newArray = new T(num_indices);
|
||||
|
||||
const EDT* src = static_cast<const EDT*>(array.getDataPointer());
|
||||
|
||||
for(unsigned int i=0;i<num_indices;++i)
|
||||
{
|
||||
(*newArray)[i]= src[indices.index(i)];
|
||||
}
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
osg::Array* create_noinline(const osg::Array& array, const osg::IndexArray& indices) {
|
||||
switch (array.getType())
|
||||
{
|
||||
case(osg::Array::ByteArrayType): return create_noinline<osg::ByteArray>(array,indices);
|
||||
case(osg::Array::ShortArrayType): return create_noinline<osg::ShortArray>(array,indices);
|
||||
case(osg::Array::IntArrayType): return create_noinline<osg::IntArray>(array,indices);
|
||||
case(osg::Array::UByteArrayType): return create_noinline<osg::UByteArray>(array,indices);
|
||||
case(osg::Array::UShortArrayType): return create_noinline<osg::UShortArray>(array,indices);
|
||||
case(osg::Array::UIntArrayType): return create_noinline<osg::UIntArray>(array,indices);
|
||||
case(osg::Array::Vec4ubArrayType): return create_noinline<osg::Vec4ubArray>(array,indices);
|
||||
case(osg::Array::FloatArrayType): return create_noinline<osg::FloatArray>(array,indices);
|
||||
case(osg::Array::Vec2ArrayType): return create_noinline<osg::Vec2Array>(array,indices);
|
||||
case(osg::Array::Vec3ArrayType): return create_noinline<osg::Vec3Array>(array,indices);
|
||||
case(osg::Array::Vec4ArrayType): return create_noinline<osg::Vec4Array>(array,indices);
|
||||
case(osg::Array::Vec2dArrayType): return create_noinline<osg::Vec2dArray>(array,indices);
|
||||
case(osg::Array::Vec3dArrayType): return create_noinline<osg::Vec3dArray>(array,indices);
|
||||
case(osg::Array::Vec4dArrayType): return create_noinline<osg::Vec4dArray>(array,indices);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
template <class TA, class TI>
|
||||
osg::Array* create(const TA& array, const osg::IndexArray& indices) {
|
||||
// We know that indices.getType returned the same thing as TI, but
|
||||
// we need to determine whether it is really an instance of TI, or
|
||||
// perhaps another subclass of osg::Array that contains the same
|
||||
// type of data.
|
||||
const TI* ba(dynamic_cast<const TI*>(&indices));
|
||||
if (ba != NULL) {
|
||||
return create_inline(array,*ba);
|
||||
}
|
||||
else {
|
||||
return create_noinline(array, _indices);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
osg::Array* create(const T& array)
|
||||
{
|
||||
switch(_indices.getType())
|
||||
{
|
||||
case(osg::Array::ByteArrayType): return create(array,static_cast<const osg::ByteArray&>(_indices));
|
||||
case(osg::Array::ShortArrayType): return create(array,static_cast<const osg::ShortArray&>(_indices));
|
||||
case(osg::Array::IntArrayType): return create(array,static_cast<const osg::IntArray&>(_indices));
|
||||
case(osg::Array::UByteArrayType): return create(array,static_cast<const osg::UByteArray&>(_indices));
|
||||
case(osg::Array::UShortArrayType): return create(array,static_cast<const osg::UShortArray&>(_indices));
|
||||
case(osg::Array::UIntArrayType): return create(array,static_cast<const osg::UIntArray&>(_indices));
|
||||
default: return 0;
|
||||
case(osg::Array::ByteArrayType): return create<T, osg::ByteArray>(array, _indices);
|
||||
case(osg::Array::ShortArrayType): return create<T, osg::ShortArray>(array, _indices);
|
||||
case(osg::Array::IntArrayType): return create<T, osg::IntArray>(array, _indices);
|
||||
case(osg::Array::UByteArrayType): return create<T, osg::UByteArray>(array, _indices);
|
||||
case(osg::Array::UShortArrayType): return create<T, osg::UShortArray>(array, _indices);
|
||||
case(osg::Array::UIntArrayType): return create<T, osg::UIntArray>(array, _indices);
|
||||
default:
|
||||
return create_noinline(array, _indices);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// applys for the predefined classes go through 1-arg create to do indexing
|
||||
virtual void apply(const osg::ByteArray& array) { _targetArray = create(array); }
|
||||
virtual void apply(const osg::ShortArray& array) { _targetArray = create(array); }
|
||||
virtual void apply(const osg::IntArray& array) { _targetArray = create(array); }
|
||||
@ -2947,6 +3026,9 @@ class ExpandIndexedArray : public osg::ConstArrayVisitor
|
||||
virtual void apply(const osg::Vec3Array& array) { _targetArray = create(array); }
|
||||
virtual void apply(const osg::Vec4Array& array) { _targetArray = create(array); }
|
||||
|
||||
// other subclasses of osg::Array end up here
|
||||
virtual void apply(const osg::Array& array) { _targetArray = create_noinline(array, _indices); }
|
||||
|
||||
const osg::IndexArray& _indices;
|
||||
osg::Array* _targetArray;
|
||||
};
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <limits.h>
|
||||
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/FileUtils>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
@ -238,9 +239,34 @@ std::string osgDB::concatPaths(const std::string& left, const std::string& right
|
||||
std::string osgDB::getRealPath(const std::string& path)
|
||||
{
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
TCHAR retbuf[MAX_PATH + sizeof(TCHAR)];
|
||||
GetFullPathName(path.c_str(), sizeof(retbuf), retbuf, 0);
|
||||
// Not unicode compatible should give an error if UNICODE defined
|
||||
char retbuf[MAX_PATH + 1];
|
||||
char tempbuf1[MAX_PATH + 1];
|
||||
GetFullPathName(path.c_str(), sizeof(retbuf), retbuf, NULL);
|
||||
// Force drive letter to upper case
|
||||
if ((retbuf[1] == ':') && islower(retbuf[0]))
|
||||
retbuf[0] = _toupper(retbuf[0]);
|
||||
if (fileExists(std::string(retbuf)))
|
||||
{
|
||||
// Canonicalise the full path
|
||||
GetShortPathName(retbuf, tempbuf1, sizeof(tempbuf1));
|
||||
GetLongPathName(tempbuf1, retbuf, sizeof(retbuf));
|
||||
return std::string(retbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Canonicalise the directories
|
||||
std::string FilePath = getFilePath(retbuf);
|
||||
char tempbuf2[MAX_PATH + 1];
|
||||
if (0 == GetShortPathName(FilePath.c_str(), tempbuf1, sizeof(tempbuf1)))
|
||||
return std::string(retbuf);
|
||||
if (0 == GetLongPathName(tempbuf1, tempbuf2, sizeof(tempbuf2)))
|
||||
return std::string(retbuf);
|
||||
FilePath = std::string(tempbuf2);
|
||||
FilePath.append("\\");
|
||||
FilePath.append(getSimpleFileName(std::string(retbuf)));
|
||||
return FilePath;
|
||||
}
|
||||
#else
|
||||
char resolved_path[PATH_MAX];
|
||||
char* result = realpath(path.c_str(), resolved_path);
|
||||
|
Loading…
Reference in New Issue
Block a user