Merge branch 'master' of https://github.com/openscenegraph/OpenSceneGraph
This commit is contained in:
@@ -26,13 +26,15 @@ FOREACH( mylibfolder
|
||||
osgTerrain
|
||||
osgWidget
|
||||
osgPresentation
|
||||
osgWrappers/serializers
|
||||
osgWrappers/deprecated-dotosg
|
||||
osgPlugins
|
||||
)
|
||||
|
||||
ADD_SUBDIRECTORY(${mylibfolder})
|
||||
|
||||
ENDFOREACH()
|
||||
|
||||
IF(BUILD_OSG_PLUGINS)
|
||||
ADD_SUBDIRECTORY(osgWrappers/serializers)
|
||||
ADD_SUBDIRECTORY(osgWrappers/deprecated-dotosg)
|
||||
ADD_SUBDIRECTORY(osgPlugins)
|
||||
ENDIF(BUILD_OSG_PLUGINS)
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ void GLBufferObject::compileBuffer()
|
||||
|
||||
void GLBufferObject::deleteGLObject()
|
||||
{
|
||||
OSG_INFO<<"GLBufferObject::deleteGLObject() "<<_glObjectID<<std::endl;
|
||||
OSG_DEBUG<<"GLBufferObject::deleteGLObject() "<<_glObjectID<<std::endl;
|
||||
if (_glObjectID!=0)
|
||||
{
|
||||
_extensions->glDeleteBuffers(1, &_glObjectID);
|
||||
@@ -1104,7 +1104,7 @@ void BufferObject::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
|
||||
void BufferObject::releaseGLObjects(State* state) const
|
||||
{
|
||||
OSG_INFO<<"BufferObject::releaseGLObjects("<<state<<")"<<std::endl;
|
||||
OSG_DEBUG<<"BufferObject::releaseGLObjects("<<state<<")"<<std::endl;
|
||||
if (state)
|
||||
{
|
||||
unsigned int contextID = state->getContextID();
|
||||
@@ -1260,7 +1260,7 @@ void BufferData::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
|
||||
void BufferData::releaseGLObjects(State* state) const
|
||||
{
|
||||
OSG_INFO<<"BufferData::releaseGLObjects("<<state<<")"<<std::endl;
|
||||
OSG_DEBUG<<"BufferData::releaseGLObjects("<<state<<")"<<std::endl;
|
||||
if (_bufferObject.valid())
|
||||
{
|
||||
_bufferObject->releaseGLObjects(state);
|
||||
@@ -1369,7 +1369,7 @@ PixelBufferObject::PixelBufferObject(osg::Image* image):
|
||||
setTarget(GL_PIXEL_UNPACK_BUFFER_ARB);
|
||||
setUsage(GL_STREAM_DRAW_ARB);
|
||||
|
||||
OSG_INFO<<"Constructing PixelBufferObject for image="<<image<<std::endl;
|
||||
OSG_DEBUG<<"Constructing PixelBufferObject for image="<<image<<std::endl;
|
||||
|
||||
if (image) setBufferData(0, image);
|
||||
}
|
||||
|
||||
@@ -477,8 +477,9 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
isGLExtensionSupported(contextID,"GL_EXT_texture_cube_map") ||
|
||||
(glVersion >= 1.3f));
|
||||
|
||||
isClipControlSupported = isGLExtensionSupported(contextID,"GL_ARB_clip_control") ||
|
||||
(glVersion >= 4.5f);
|
||||
isClipControlSupported = validContext &&
|
||||
(isGLExtensionSupported(contextID,"GL_ARB_clip_control") ||
|
||||
(glVersion >= 4.5f));
|
||||
|
||||
|
||||
isGlslSupported = validContext &&
|
||||
@@ -561,45 +562,47 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
setGLExtensionFuncPtr(glUniformMatrix3fv, "glUniformMatrix3fv", "glUniformMatrix3fvARB", validContext);
|
||||
setGLExtensionFuncPtr(glUniformMatrix4fv, "glUniformMatrix4fv", "glUniformMatrix4fvARB", validContext);
|
||||
setGLExtensionFuncPtr(glValidateProgram, "glValidateProgram", "glValidateProgramARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib1d, "glVertexAttrib1d", validContext);
|
||||
|
||||
setGLExtensionFuncPtr(glVertexAttrib1d, "glVertexAttrib1d", "glVertexAttrib1dARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib1dv, "glVertexAttrib1dv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib1f, "glVertexAttrib1f", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib1fv, "glVertexAttrib1fv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib1s, "glVertexAttrib1s", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib1f, "glVertexAttrib1f", "glVertexAttrib1fARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib1fv, "glVertexAttrib1fv", "glVertexAttrib1fvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib1s, "glVertexAttrib1s", "glVertexAttrib1sARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib1sv, "glVertexAttrib1sv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib2d, "glVertexAttrib2d", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib2dv, "glVertexAttrib2dv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib2dv, "glVertexAttrib2dv", "glVertexAttrib2dvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib2f, "glVertexAttrib2f", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib2fv, "glVertexAttrib2fv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib2fv, "glVertexAttrib2fv", "glVertexAttrib2fvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib2s, "glVertexAttrib2s", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib2sv, "glVertexAttrib2sv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib3d, "glVertexAttrib3d", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib3dv, "glVertexAttrib3dv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib3dv, "glVertexAttrib3dv", "glVertexAttrib3dvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib3f, "glVertexAttrib3f", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib3fv, "glVertexAttrib3fv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib3fv, "glVertexAttrib3fv", "glVertexAttrib3fvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib3s, "glVertexAttrib3s", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib3sv, "glVertexAttrib3sv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4Nbv, "glVertexAttrib4Nbv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4Niv, "glVertexAttrib4Niv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4Nsv, "glVertexAttrib4Nsv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4Nub, "glVertexAttrib4Nub", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4Nubv, "glVertexAttrib4Nubv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4Nubv, "glVertexAttrib4Nubv", "glVertexAttrib4NubvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4Nuiv, "glVertexAttrib4Nuiv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4Nusv, "glVertexAttrib4Nusv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4bv, "glVertexAttrib4bv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4d, "glVertexAttrib4d", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4dv, "glVertexAttrib4dv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4dv, "glVertexAttrib4dv", "glVertexAttrib4dvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4f, "glVertexAttrib4f", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4fv, "glVertexAttrib4fv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4fv, "glVertexAttrib4fv", "glVertexAttrib4fvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4iv, "glVertexAttrib4iv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4s, "glVertexAttrib4s", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4sv, "glVertexAttrib4sv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4ubv, "glVertexAttrib4ubv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4ubv, "glVertexAttrib4ubv", "glVertexAttrib4ubvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4uiv, "glVertexAttrib4uiv", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4usv, "glVertexAttrib4usv", validContext);
|
||||
|
||||
setGLExtensionFuncPtr(glVertexAttribPointer, "glVertexAttribPointer","glVertexAttribPointerARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttribIPointer, "glVertexAttribIPointer","glVertexAttribIPointerARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttribLPointer, "glVertexAttribLPointer","glVertexAttribPointerARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttribLPointer, "glVertexAttribLPointer","glVertexAttribLPointerARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttribDivisor, "glVertexAttribDivisor", validContext);
|
||||
|
||||
// v1.5-only ARB entry points, in case they're needed for fallback
|
||||
@@ -717,7 +720,6 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
|
||||
isVBOSupported = validContext && (OSG_GLES2_FEATURES || OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID,"GL_ARB_vertex_buffer_object"));
|
||||
isPBOSupported = validContext && (OSG_GLES2_FEATURES || OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID,"GL_ARB_pixel_buffer_object"));
|
||||
isUniformBufferObjectSupported = validContext && osg::isGLExtensionSupported(contextID, "GL_ARB_uniform_buffer_object");
|
||||
isTBOSupported = validContext && osg::isGLExtensionSupported(contextID,"GL_ARB_texture_buffer_object");
|
||||
isVAOSupported = validContext && (OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID, "GL_ARB_vertex_array_object", "GL_OES_vertex_array_object"));
|
||||
isTransformFeedbackSupported = validContext && osg::isGLExtensionSupported(contextID, "GL_ARB_transform_feedback2");
|
||||
@@ -736,7 +738,6 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
setGLExtensionFuncPtr(glBlendFuncSeparatei, "glBlendFuncSeparatei", "glBlendFuncSeparateiARB", validContext);
|
||||
|
||||
|
||||
// Vertex Array extensions
|
||||
isSecondaryColorSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_secondary_color");
|
||||
isFogCoordSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_fog_coord");
|
||||
isMultiTexSupported = validContext && isGLExtensionSupported(contextID,"GL_ARB_multitexture");
|
||||
@@ -764,40 +765,15 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
setGLExtensionFuncPtr(glMultiTexCoord4fv, "glMultiTexCoord4fv","glMultiTexCoord4fvARB", validContext);
|
||||
|
||||
|
||||
setGLExtensionFuncPtr(glMultiTexCoord1d, "glMultiTexCoord1d","glMultiTexCoorddfARB", validContext);
|
||||
setGLExtensionFuncPtr(glMultiTexCoord1d, "glMultiTexCoord1d","glMultiTexCoord1dARB", validContext);
|
||||
setGLExtensionFuncPtr(glMultiTexCoord1dv, "glMultiTexCoord1dv","glMultiTexCoord1dvARB", validContext);
|
||||
setGLExtensionFuncPtr(glMultiTexCoord2dv, "glMultiTexCoord2dv","glMultiTexCoord2dvARB", validContext);
|
||||
setGLExtensionFuncPtr(glMultiTexCoord3dv, "glMultiTexCoord3dv","glMultiTexCoord3dvARB", validContext);
|
||||
setGLExtensionFuncPtr(glMultiTexCoord4dv, "glMultiTexCoord4dv","glMultiTexCoord4dvARB", validContext);
|
||||
|
||||
setGLExtensionFuncPtr(glVertexAttrib1s, "glVertexAttrib1s","glVertexAttrib1sARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib1f, "glVertexAttrib1f","glVertexAttrib1fARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib1d, "glVertexAttrib1d","glVertexAttrib1dARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib1fv, "glVertexAttrib1fv","glVertexAttrib1fvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib2fv, "glVertexAttrib2fv","glVertexAttrib2fvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib3fv, "glVertexAttrib3fv","glVertexAttrib3fvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4fv, "glVertexAttrib4fv","glVertexAttrib4fvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib2dv, "glVertexAttrib2dv","glVertexAttrib2dvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib3dv, "glVertexAttrib3dv","glVertexAttrib3dvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4dv, "glVertexAttrib4dv","glVertexAttrib4dvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4ubv, "glVertexAttrib4ubv","glVertexAttrib4ubvARB", validContext);
|
||||
setGLExtensionFuncPtr(glVertexAttrib4Nubv, "glVertexAttrib4Nubv","glVertexAttrib4NubvARB", validContext);
|
||||
|
||||
setGLExtensionFuncPtr(glGenBuffers, "glGenBuffers","glGenBuffersARB", validContext);
|
||||
setGLExtensionFuncPtr(glBindBuffer, "glBindBuffer","glBindBufferARB", validContext);
|
||||
setGLExtensionFuncPtr(glBufferData, "glBufferData","glBufferDataARB", validContext);
|
||||
setGLExtensionFuncPtr(glBufferSubData, "glBufferSubData","glBufferSubDataARB", validContext);
|
||||
setGLExtensionFuncPtr(glDeleteBuffers, "glDeleteBuffers","glDeleteBuffersARB", validContext);
|
||||
setGLExtensionFuncPtr(glIsBuffer, "glIsBuffer","glIsBufferARB", validContext);
|
||||
setGLExtensionFuncPtr(glGetBufferSubData, "glGetBufferSubData","glGetBufferSubDataARB", validContext);
|
||||
setGLExtensionFuncPtr(glMapBuffer, "glMapBuffer","glMapBufferARB", validContext);
|
||||
setGLExtensionFuncPtr(glUnmapBuffer, "glUnmapBuffer","glUnmapBufferARB", validContext);
|
||||
setGLExtensionFuncPtr(glGetBufferParameteriv, "glGetBufferParameteriv","glGetBufferParameterivARB", validContext);
|
||||
setGLExtensionFuncPtr(glGetBufferPointerv, "glGetBufferPointerv","glGetBufferPointervARB", validContext);
|
||||
|
||||
setGLExtensionFuncPtr(glGenOcclusionQueries, "glGenOcclusionQueries","glGenOcclusionQueriesNV", validContext);
|
||||
setGLExtensionFuncPtr(glDeleteOcclusionQueries, "glDeleteOcclusionQueries","glDeleteOcclusionQueriesNV", validContext);
|
||||
setGLExtensionFuncPtr(glIsOcclusionQuery, "glIsOcclusionQuery","_glIsOcclusionQueryNV", validContext);
|
||||
setGLExtensionFuncPtr(glIsOcclusionQuery, "glIsOcclusionQuery","glIsOcclusionQueryNV", validContext);
|
||||
setGLExtensionFuncPtr(glBeginOcclusionQuery, "glBeginOcclusionQuery","glBeginOcclusionQueryNV", validContext);
|
||||
setGLExtensionFuncPtr(glEndOcclusionQuery, "glEndOcclusionQuery","glEndOcclusionQueryNV", validContext);
|
||||
setGLExtensionFuncPtr(glGetOcclusionQueryiv, "glGetOcclusionQueryiv","glGetOcclusionQueryivNV", validContext);
|
||||
@@ -822,9 +798,7 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
|
||||
// function pointers
|
||||
setGLExtensionFuncPtr(glSampleMaski, "glSampleMaski", validContext);
|
||||
// protect against buggy drivers (maybe not necessary)
|
||||
isSampleMaskiSupported = glSampleMaski!=0;
|
||||
|
||||
isSampleMaskiSupported = validContext && (isOpenGL32upported || isGLExtensionSupported(contextID,"ARB_texture_multisample"));
|
||||
|
||||
|
||||
// old styple Vertex/Fragment Programs
|
||||
@@ -859,33 +833,36 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
isTextureCompressionS3TCSupported = validContext && (isGLExtensionSupported(contextID,"GL_EXT_texture_compression_s3tc") || isGLExtensionSupported(contextID, "GL_S3_s3tc"));
|
||||
isTextureCompressionPVRTC2BPPSupported = validContext && isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc");
|
||||
isTextureCompressionPVRTC4BPPSupported = isTextureCompressionPVRTC2BPPSupported;//covered by same extension
|
||||
isTextureCompressionETCSupported = isGLExtensionSupported(contextID,"GL_OES_compressed_ETC1_RGB8_texture");
|
||||
isTextureCompressionETC2Supported = isGLExtensionSupported(contextID,"GL_ARB_ES3_compatibility");
|
||||
isTextureCompressionRGTCSupported = isGLExtensionSupported(contextID,"GL_EXT_texture_compression_rgtc");
|
||||
isTextureCompressionPVRTCSupported = isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc");
|
||||
isTextureCompressionETCSupported = validContext && isGLExtensionSupported(contextID,"GL_OES_compressed_ETC1_RGB8_texture");
|
||||
isTextureCompressionETC2Supported = validContext && isGLExtensionSupported(contextID,"GL_ARB_ES3_compatibility");
|
||||
isTextureCompressionRGTCSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_texture_compression_rgtc");
|
||||
isTextureCompressionPVRTCSupported = validContext && isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc");
|
||||
|
||||
isTextureMirroredRepeatSupported = builtInSupport ||
|
||||
isGLExtensionOrVersionSupported(contextID,"GL_IBM_texture_mirrored_repeat", 1.4f) ||
|
||||
isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_mirrored_repeat", 1.4f);
|
||||
isTextureMirroredRepeatSupported = validContext &&
|
||||
(builtInSupport ||
|
||||
isGLExtensionOrVersionSupported(contextID,"GL_IBM_texture_mirrored_repeat", 1.4f) ||
|
||||
isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_mirrored_repeat", 1.4f));
|
||||
|
||||
isTextureEdgeClampSupported = builtInSupport ||
|
||||
isTextureEdgeClampSupported = validContext &&
|
||||
(builtInSupport ||
|
||||
isGLExtensionOrVersionSupported(contextID,"GL_EXT_texture_edge_clamp", 1.2f) ||
|
||||
isGLExtensionOrVersionSupported(contextID,"GL_SGIS_texture_edge_clamp", 1.2f);
|
||||
isGLExtensionOrVersionSupported(contextID,"GL_SGIS_texture_edge_clamp", 1.2f));
|
||||
|
||||
|
||||
isTextureBorderClampSupported = OSG_GL3_FEATURES ||
|
||||
((OSG_GL1_FEATURES || OSG_GL2_FEATURES) && isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_border_clamp", 1.3f)) ||
|
||||
(OSG_GLES2_FEATURES && isGLExtensionSupported(contextID,"GL_EXT_texture_border_clamp"));
|
||||
isTextureBorderClampSupported = validContext &&
|
||||
(OSG_GL3_FEATURES ||
|
||||
((OSG_GL1_FEATURES || OSG_GL2_FEATURES) && isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_border_clamp", 1.3f)) ||
|
||||
(OSG_GLES2_FEATURES && isGLExtensionSupported(contextID,"GL_EXT_texture_border_clamp")));
|
||||
|
||||
isGenerateMipMapSupported = builtInSupport || isGLExtensionOrVersionSupported(contextID,"GL_SGIS_generate_mipmap", 1.4f);
|
||||
isGenerateMipMapSupported = validContext && (builtInSupport || isGLExtensionOrVersionSupported(contextID,"GL_SGIS_generate_mipmap", 1.4f));
|
||||
preferGenerateMipmapSGISForPowerOfTwo = (radeonHardwareDetected||fireGLHardwareDetected) ? false : true;
|
||||
isTextureMultisampledSupported = isGLExtensionSupported(contextID,"GL_ARB_texture_multisample");
|
||||
isShadowSupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_shadow");
|
||||
isShadowAmbientSupported = isGLExtensionSupported(contextID,"GL_ARB_shadow_ambient");
|
||||
isClientStorageSupported = isGLExtensionSupported(contextID,"GL_APPLE_client_storage");
|
||||
isNonPowerOfTwoTextureNonMipMappedSupported = builtInSupport || isGLExtensionSupported(contextID,"GL_OES_texture_npot") || isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_non_power_of_two", 2.0) || isGLExtensionSupported(contextID,"GL_APPLE_texture_2D_limited_npot");
|
||||
isNonPowerOfTwoTextureMipMappedSupported = builtInSupport || isNonPowerOfTwoTextureNonMipMappedSupported;
|
||||
isTextureIntegerEXTSupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_EXT_texture_integer");
|
||||
isTextureMultisampledSupported = validContext && (isGLExtensionSupported(contextID,"GL_ARB_texture_multisample"));
|
||||
isShadowSupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_shadow"));
|
||||
isShadowAmbientSupported = validContext && (isGLExtensionSupported(contextID,"GL_ARB_shadow_ambient"));
|
||||
isClientStorageSupported = validContext && (isGLExtensionSupported(contextID,"GL_APPLE_client_storage"));
|
||||
isNonPowerOfTwoTextureMipMappedSupported = validContext && (builtInSupport || isGLExtensionSupported(contextID, "GL_OES_texture_npot") || isGLExtensionOrVersionSupported(contextID, "GL_ARB_texture_non_power_of_two", 2.0));
|
||||
isNonPowerOfTwoTextureNonMipMappedSupported = validContext && (isNonPowerOfTwoTextureMipMappedSupported || isGLExtensionSupported(contextID, "GL_APPLE_texture_2D_limited_npot"));
|
||||
isTextureIntegerEXTSupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_EXT_texture_integer"));
|
||||
|
||||
if (rendererString.find("GeForce FX")!=std::string::npos)
|
||||
{
|
||||
@@ -914,19 +891,15 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
setGLExtensionFuncPtr(glGetCompressedTexImage,"glGetCompressedTexImage","glGetCompressedTexImageARB", validContext);;
|
||||
setGLExtensionFuncPtr(glTexImage2DMultisample, "glTexImage2DMultisample", "glTexImage2DMultisampleARB", validContext);
|
||||
|
||||
setGLExtensionFuncPtr(glTexParameterIiv, "glTexParameterIiv", "glTexParameterIivARB", validContext);
|
||||
setGLExtensionFuncPtr(glTexParameterIuiv, "glTexParameterIuiv", "glTexParameterIuivARB", validContext);
|
||||
|
||||
|
||||
if (glTexParameterIiv == NULL) setGLExtensionFuncPtr(glTexParameterIiv, "glTexParameterIivEXT", validContext);
|
||||
if (glTexParameterIuiv == NULL) setGLExtensionFuncPtr(glTexParameterIuiv, "glTexParameterIuivEXT", validContext);
|
||||
setGLExtensionFuncPtr(glTexParameterIiv, "glTexParameterIiv", "glTexParameterIivARB", "glTexParameterIivEXT", validContext);
|
||||
setGLExtensionFuncPtr(glTexParameterIuiv, "glTexParameterIuiv", "glTexParameterIuivARB", "glTexParameterIuivEXT", validContext);
|
||||
|
||||
setGLExtensionFuncPtr(glBindImageTexture, "glBindImageTexture", "glBindImageTextureARB", validContext);
|
||||
|
||||
isTextureMaxLevelSupported = (glVersion >= 1.2f);
|
||||
|
||||
isTextureStorageEnabled = isTexStorage2DSupported();
|
||||
if ( (ptr = getenv("OSG_GL_TEXTURE_STORAGE")) != 0 && isTexStorage2DSupported())
|
||||
isTextureStorageEnabled = validContext && ((glVersion >= 4.2f) || isGLExtensionSupported(contextID, "GL_ARB_texture_storage"));
|
||||
if ( (ptr = getenv("OSG_GL_TEXTURE_STORAGE")) != 0 && isTextureStorageEnabled)
|
||||
{
|
||||
if (strcmp(ptr,"OFF")==0 || strcmp(ptr,"DISABLE")==0 ) isTextureStorageEnabled = false;
|
||||
else isTextureStorageEnabled = true;
|
||||
@@ -934,10 +907,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
|
||||
|
||||
// Texture3D extensions
|
||||
isTexture3DFast = OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture3D");
|
||||
isTexture3DFast = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture3D"));
|
||||
|
||||
if (isTexture3DFast) isTexture3DSupported = true;
|
||||
else isTexture3DSupported = (glVersion >= 1.2f);
|
||||
else isTexture3DSupported = validContext && (glVersion >= 1.2f);
|
||||
|
||||
maxTexture3DSize = 0;
|
||||
if (validContext) glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &maxTexture3DSize);
|
||||
@@ -950,7 +923,7 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
|
||||
|
||||
// Texture2DArray extensions
|
||||
isTexture2DArraySupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture_array");
|
||||
isTexture2DArraySupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture_array"));
|
||||
|
||||
max2DSize = 0;
|
||||
if (validContext) glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DSize);
|
||||
@@ -965,25 +938,28 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
setGLExtensionFuncPtr(glIsTextureHandleResident, "glIsTextureHandleResident","glIsTextureHandleResidentARB", "glIsTextureHandleResidentNV", validContext);
|
||||
|
||||
// Blending
|
||||
isBlendColorSupported = OSG_GLES2_FEATURES || OSG_GL3_FEATURES ||
|
||||
isGLExtensionSupported(contextID,"GL_EXT_blend_color") ||
|
||||
(glVersion >= 1.2f);
|
||||
isBlendColorSupported = validContext &&
|
||||
(OSG_GLES2_FEATURES || OSG_GL3_FEATURES ||
|
||||
isGLExtensionSupported(contextID,"GL_EXT_blend_color") ||
|
||||
(glVersion >= 1.2f));
|
||||
|
||||
setGLExtensionFuncPtr(glBlendColor, "glBlendColor", "glBlendColorEXT", validContext);
|
||||
|
||||
bool bultInSupport = OSG_GLES2_FEATURES || OSG_GL3_FEATURES;
|
||||
isBlendEquationSupported = bultInSupport ||
|
||||
isGLExtensionSupported(contextID, "GL_EXT_blend_equation") ||
|
||||
(glVersion >= 1.2f);
|
||||
isBlendEquationSupported = validContext &&
|
||||
(bultInSupport ||
|
||||
isGLExtensionSupported(contextID, "GL_EXT_blend_equation") ||
|
||||
(glVersion >= 1.2f));
|
||||
|
||||
|
||||
isBlendEquationSeparateSupported = bultInSupport ||
|
||||
isGLExtensionSupported(contextID, "GL_EXT_blend_equation_separate") ||
|
||||
(glVersion >= 2.0f);
|
||||
isBlendEquationSeparateSupported = validContext &&
|
||||
(bultInSupport ||
|
||||
isGLExtensionSupported(contextID, "GL_EXT_blend_equation_separate") ||
|
||||
(glVersion >= 2.0f));
|
||||
|
||||
|
||||
isSGIXMinMaxSupported = isGLExtensionSupported(contextID, "GL_SGIX_blend_alpha_minmax");
|
||||
isLogicOpSupported = isGLExtensionSupported(contextID, "GL_EXT_blend_logic_op");
|
||||
isSGIXMinMaxSupported = validContext && isGLExtensionSupported(contextID, "GL_SGIX_blend_alpha_minmax");
|
||||
isLogicOpSupported = validContext && isGLExtensionSupported(contextID, "GL_EXT_blend_logic_op");
|
||||
|
||||
setGLExtensionFuncPtr(glBlendEquation, "glBlendEquation", "glBlendEquationEXT", validContext);
|
||||
setGLExtensionFuncPtr(glBlendEquationSeparate, "glBlendEquationSeparate", "glBlendEquationSeparateEXT", validContext);
|
||||
@@ -998,10 +974,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
|
||||
|
||||
// Stencil`
|
||||
isStencilWrapSupported = isGLExtensionOrVersionSupported(contextID, "GL_EXT_stencil_wrap", 1.4f);
|
||||
isStencilTwoSidedSupported = isGLExtensionSupported(contextID, "GL_EXT_stencil_two_side");
|
||||
isOpenGL20Supported = (glVersion >= 2.0f);
|
||||
isSeparateStencilSupported = isGLExtensionSupported(contextID, "GL_ATI_separate_stencil");
|
||||
isStencilWrapSupported = validContext && isGLExtensionOrVersionSupported(contextID, "GL_EXT_stencil_wrap", 1.4f);
|
||||
isStencilTwoSidedSupported = validContext && isGLExtensionSupported(contextID, "GL_EXT_stencil_two_side");
|
||||
isOpenGL20Supported = validContext && (glVersion >= 2.0f);
|
||||
isSeparateStencilSupported = validContext && isGLExtensionSupported(contextID, "GL_ATI_separate_stencil");
|
||||
|
||||
// function pointers
|
||||
setGLExtensionFuncPtr(glActiveStencilFace, "glActiveStencilFaceEXT", validContext);
|
||||
@@ -1016,9 +992,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
|
||||
|
||||
// ClampColor
|
||||
isClampColorSupported = OSG_GL3_FEATURES ||
|
||||
isClampColorSupported = validContext &&
|
||||
(OSG_GL3_FEATURES ||
|
||||
isGLExtensionSupported(contextID,"GL_ARB_color_buffer_float") ||
|
||||
(glVersion >= 2.0f);
|
||||
(glVersion >= 2.0f));
|
||||
|
||||
setGLExtensionFuncPtr(glClampColor, "glClampColor", "glClampColorARB", validContext);
|
||||
|
||||
@@ -1028,14 +1005,15 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
|
||||
|
||||
// Point
|
||||
isPointParametersSupported = OSG_GL3_FEATURES || (glVersion >= 1.4f) ||
|
||||
isPointParametersSupported = validContext &&
|
||||
(OSG_GL3_FEATURES || (glVersion >= 1.4f) ||
|
||||
isGLExtensionSupported(contextID,"GL_ARB_point_parameters") ||
|
||||
isGLExtensionSupported(contextID,"GL_EXT_point_parameters") ||
|
||||
isGLExtensionSupported(contextID,"GL_SGIS_point_parameters");
|
||||
isGLExtensionSupported(contextID,"GL_SGIS_point_parameters"));
|
||||
|
||||
|
||||
isPointSpriteSupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_ARB_point_sprite") || isGLExtensionSupported(contextID, "GL_OES_point_sprite") || isGLExtensionSupported(contextID, "GL_NV_point_sprite");
|
||||
isPointSpriteCoordOriginSupported = OSG_GL3_FEATURES || (glVersion >= 2.0f);
|
||||
isPointSpriteSupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_ARB_point_sprite") || isGLExtensionSupported(contextID, "GL_OES_point_sprite") || isGLExtensionSupported(contextID, "GL_NV_point_sprite"));
|
||||
isPointSpriteCoordOriginSupported = validContext && (OSG_GL3_FEATURES || (glVersion >= 2.0f));
|
||||
|
||||
|
||||
setGLExtensionFuncPtr(glPointParameteri, "glPointParameteri", "glPointParameteriARB", validContext);
|
||||
@@ -1049,10 +1027,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
|
||||
|
||||
// Multisample
|
||||
isMultisampleSupported = OSG_GLES2_FEATURES || OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_multisample");
|
||||
isMultisampleFilterHintSupported = isGLExtensionSupported(contextID, "GL_NV_multisample_filter_hint");
|
||||
isMultisampleSupported = validContext && (OSG_GLES2_FEATURES || OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_multisample"));
|
||||
isMultisampleFilterHintSupported = validContext && isGLExtensionSupported(contextID, "GL_NV_multisample_filter_hint");
|
||||
|
||||
setGLExtensionFuncPtr(glSampleCoverage, "glSampleCoverageARB", validContext);
|
||||
setGLExtensionFuncPtr(glSampleCoverage, "glSampleCoverage", "glSampleCoverageARB", validContext);
|
||||
|
||||
|
||||
// FrameBufferObject
|
||||
@@ -1095,9 +1073,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
|
||||
( OSG_GLES1_FEATURES || isGLExtensionOrVersionSupported(contextID, "GL_EXT_framebuffer_object",3.0f) );
|
||||
|
||||
|
||||
isPackedDepthStencilSupported = OSG_GL3_FEATURES ||
|
||||
(isGLExtensionSupported(contextID, "GL_EXT_packed_depth_stencil")) ||
|
||||
(isGLExtensionSupported(contextID, "GL_OES_packed_depth_stencil"));
|
||||
isPackedDepthStencilSupported = validContext &&
|
||||
(OSG_GL3_FEATURES ||
|
||||
(isGLExtensionSupported(contextID, "GL_EXT_packed_depth_stencil")) ||
|
||||
(isGLExtensionSupported(contextID, "GL_OES_packed_depth_stencil")));
|
||||
|
||||
//subroutine
|
||||
osg::setGLExtensionFuncPtr(glGetSubroutineUniformLocation, "glGetSubroutineUniformLocation", validContext);
|
||||
|
||||
@@ -205,15 +205,10 @@ public:
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
virtual void apply(osg::Geode& geode)
|
||||
virtual void apply(osg::Geometry& geom)
|
||||
{
|
||||
apply(geode.getStateSet());
|
||||
for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
|
||||
{
|
||||
apply(geode.getDrawable(i)->getStateSet());
|
||||
osg::Geometry* geometry = geode.getDrawable(i)->asGeometry();
|
||||
if (geometry) apply(geometry);
|
||||
}
|
||||
apply(geom.getStateSet());
|
||||
apply(&geom);
|
||||
}
|
||||
|
||||
void apply(osg::StateSet* stateset)
|
||||
@@ -282,15 +277,10 @@ public:
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
virtual void apply(osg::Geode& geode)
|
||||
virtual void apply(osg::Geometry& geom)
|
||||
{
|
||||
apply(geode.getStateSet());
|
||||
for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
|
||||
{
|
||||
apply(geode.getDrawable(i)->getStateSet());
|
||||
osg::Geometry* geometry = geode.getDrawable(i)->asGeometry();
|
||||
if (geometry) apply(geometry);
|
||||
}
|
||||
apply(geom.getStateSet());
|
||||
apply(&geom);
|
||||
}
|
||||
|
||||
void apply(osg::StateSet* stateset)
|
||||
|
||||
@@ -732,26 +732,42 @@ void Program::PerContextProgram::linkProgram(osg::State& state)
|
||||
|
||||
if (!_loadedBinary)
|
||||
{
|
||||
// Detach removed shaders
|
||||
for( unsigned int i=0; i < _shadersToDetach.size(); ++i )
|
||||
const GLsizei shaderMaxCount = 20;
|
||||
GLsizei shadersCount;
|
||||
GLuint shaderObjectHandle[shaderMaxCount];
|
||||
_extensions->glGetAttachedShaders(_glProgramHandle, shaderMaxCount, &shadersCount, shaderObjectHandle);
|
||||
|
||||
typedef std::map<GLuint, int> ShaderSet;
|
||||
ShaderSet shadersRequired;
|
||||
|
||||
for(GLsizei i=0; i<shadersCount; ++i)
|
||||
{
|
||||
Shader::PerContextShader* pcs = _shadersToDetach[i]->getPCS(state);
|
||||
if (pcs) _extensions->glDetachShader( _glProgramHandle, pcs->getHandle() );
|
||||
shadersRequired[shaderObjectHandle[i]]--;
|
||||
}
|
||||
|
||||
for(unsigned int i=0; i < getProgram()->getNumShaders(); ++i)
|
||||
{
|
||||
const Shader* shader = getProgram()->getShader( i );
|
||||
Shader::PerContextShader* pcs = shader->getPCS(state);
|
||||
if (pcs) shadersRequired[ pcs->getHandle() ]++;
|
||||
}
|
||||
|
||||
for(ShaderSet::iterator itr = shadersRequired.begin();
|
||||
itr != shadersRequired.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->second>0)
|
||||
{
|
||||
_extensions->glAttachShader( _glProgramHandle, itr->first );
|
||||
}
|
||||
else if (itr->second<0)
|
||||
{
|
||||
_extensions->glDetachShader( _glProgramHandle, itr->first );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
_shadersToDetach.clear();
|
||||
|
||||
if (!_loadedBinary)
|
||||
{
|
||||
// Attach new shaders
|
||||
for( unsigned int i=0; i < _shadersToAttach.size(); ++i )
|
||||
{
|
||||
Shader::PerContextShader* pcs = _shadersToAttach[i]->getPCS(state);
|
||||
if (pcs) _extensions->glAttachShader( _glProgramHandle, pcs->getHandle() );
|
||||
}
|
||||
}
|
||||
//state.checkGLErrors("After attaching shaders.");
|
||||
|
||||
_shadersToAttach.clear();
|
||||
|
||||
_uniformInfoMap.clear();
|
||||
@@ -805,12 +821,12 @@ void Program::PerContextProgram::linkProgram(osg::State& state)
|
||||
|
||||
if( ! _isLinked )
|
||||
{
|
||||
OSG_WARN << "glLinkProgram \""<< _program->getName() << "\" FAILED" << std::endl;
|
||||
OSG_NOTICE << "glLinkProgram "<<this<<"\""<< _program->getName() << "\" FAILED" << std::endl;
|
||||
|
||||
std::string infoLog;
|
||||
if( getInfoLog(infoLog) )
|
||||
{
|
||||
OSG_WARN << "Program \""<< _program->getName() << "\" "
|
||||
OSG_NOTICE << "Program \""<< _program->getName() << "\" "
|
||||
"infolog:\n" << infoLog << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -142,8 +142,12 @@ State::~State()
|
||||
// delete the GLExtensions object associated with this osg::State.
|
||||
if (_glExtensions)
|
||||
{
|
||||
GLExtensions::Set(_contextID, 0);
|
||||
_glExtensions = 0;
|
||||
GLExtensions* glExtensions = GLExtensions::Get(_contextID, false);
|
||||
if (glExtensions && glExtensions->referenceCount() == 1) {
|
||||
// the only reference left to the extension is in the static map itself, so we clean it up now
|
||||
GLExtensions::Set(_contextID, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//_texCoordArrayList.clear();
|
||||
@@ -166,8 +170,7 @@ void State::initializeExtensionProcs()
|
||||
_defineMap.changed = true;
|
||||
}
|
||||
|
||||
_glExtensions = new GLExtensions(_contextID);
|
||||
GLExtensions::Set(_contextID, _glExtensions.get());
|
||||
_glExtensions = GLExtensions::Get(_contextID, true);
|
||||
|
||||
_isSecondaryColorSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_secondary_color");
|
||||
_isFogCoordSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_fog_coord");
|
||||
|
||||
@@ -44,7 +44,7 @@ void StateAttribute::removeParent(osg::StateSet* object)
|
||||
|
||||
void StateAttribute::setUpdateCallback(StateAttributeCallback* uc)
|
||||
{
|
||||
OSG_INFO<<"StateAttribute::Setting Update callbacks"<<std::endl;
|
||||
OSG_DEBUG<<"StateAttribute::Setting Update callbacks"<<std::endl;
|
||||
|
||||
if (_updateCallback==uc) return;
|
||||
|
||||
@@ -56,14 +56,10 @@ void StateAttribute::setUpdateCallback(StateAttributeCallback* uc)
|
||||
|
||||
if (delta!=0)
|
||||
{
|
||||
OSG_INFO<<"Going to set StateAttribute parents"<<std::endl;
|
||||
|
||||
for(ParentList::iterator itr=_parents.begin();
|
||||
itr!=_parents.end();
|
||||
++itr)
|
||||
{
|
||||
OSG_INFO<<" Setting StateAttribute parent"<<std::endl;
|
||||
|
||||
(*itr)->setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta);
|
||||
}
|
||||
}
|
||||
@@ -71,7 +67,7 @@ void StateAttribute::setUpdateCallback(StateAttributeCallback* uc)
|
||||
|
||||
void StateAttribute::setEventCallback(StateAttributeCallback* ec)
|
||||
{
|
||||
OSG_INFO<<"StateAttribute::Setting Event callbacks"<<std::endl;
|
||||
OSG_DEBUG<<"StateAttribute::Setting Event callbacks"<<std::endl;
|
||||
|
||||
if (_eventCallback==ec) return;
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ void Texture2D::apply(State& state) const
|
||||
glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
}
|
||||
|
||||
// if texture object is now valid and we have to allocate mipmap levels, then
|
||||
// if texture object is now valid and we have to allocate mipmap levels, then
|
||||
if (textureObject != 0 && _texMipmapGenerationDirtyList[contextID])
|
||||
{
|
||||
generateMipmap(state);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
using namespace osg;
|
||||
|
||||
#if 1
|
||||
#define VAS_NOTICE OSG_INFO
|
||||
#define VAS_NOTICE OSG_DEBUG
|
||||
#else
|
||||
#define VAS_NOTICE OSG_NOTICE
|
||||
#endif
|
||||
|
||||
@@ -93,20 +93,6 @@ void SharedStateManager::apply(osg::Node& node)
|
||||
if(ss) process(ss, &node);
|
||||
traverse(node);
|
||||
}
|
||||
void SharedStateManager::apply(osg::Geode& geode)
|
||||
{
|
||||
osg::StateSet* ss = geode.getStateSet();
|
||||
if(ss) process(ss, &geode);
|
||||
for(unsigned int i=0;i<geode.getNumDrawables();++i)
|
||||
{
|
||||
osg::Drawable* drawable = geode.getDrawable(i);
|
||||
if(drawable)
|
||||
{
|
||||
ss = drawable->getStateSet();
|
||||
if(ss) process(ss, drawable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SharedStateManager::isShared(osg::StateSet* ss)
|
||||
{
|
||||
|
||||
@@ -33,7 +33,7 @@ osg::Vec3d snap_point_to_grid(const osg::Vec3d& point, const osg::Vec3d& origin,
|
||||
scale[1] = spacing[1] ? round_to_nearest_int((point[1] - origin[1]) / spacing[1]) : 1.0;
|
||||
scale[2] = spacing[2] ? round_to_nearest_int((point[2] - origin[2]) / spacing[2]) : 1.0;
|
||||
osg::Vec3d snappedPoint = origin;
|
||||
snappedPoint += osg::Vec3(scale[0]*spacing[0],scale[1]*spacing[1],scale[2]*spacing[2]);
|
||||
snappedPoint += osg::Vec3d(scale[0]*spacing[0],scale[1]*spacing[1],scale[2]*spacing[2]);
|
||||
return snappedPoint;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ void ComputeAABBOnBoneVisitor::computeBoundingBoxOnBones() {
|
||||
}
|
||||
|
||||
// Compare initial and actual boundingBox if (no change) => no box on bone
|
||||
if(bb == osg::BoundingBox() || bb._min.x() == bb._max.x() || bb._min.y() == bb._max.y() || bb._min.z() == bb._max.z()) {
|
||||
if(bb == osg::BoundingBox() || (bb._min.x() == bb._max.x() && bb._min.y() == bb._max.y() && bb._min.z() == bb._max.z())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ SET(TARGET_SRC
|
||||
BindPerVertexVisitor.cpp
|
||||
DetachPrimitiveVisitor.cpp
|
||||
GeometryIndexSplitter.cpp
|
||||
GeometrySplitterVisitor.cpp
|
||||
SubGeometry.cpp
|
||||
OpenGLESGeometryOptimizer.cpp
|
||||
RemapGeometryVisitor.cpp
|
||||
RigAnimationVisitor.cpp
|
||||
RigAttributesVisitor.cpp
|
||||
TriangleMeshSmoother.cpp
|
||||
@@ -25,9 +25,11 @@ SET(TARGET_H
|
||||
DrawArrayVisitor
|
||||
EdgeIndexFunctor
|
||||
GeometryArray
|
||||
GeometryCleaner
|
||||
GeometryIndexSplitter
|
||||
GeometryInspector
|
||||
GeometrySplitterVisitor
|
||||
GeometryMapper
|
||||
RemapGeometryVisitor
|
||||
GeometryUniqueVisitor
|
||||
glesUtil
|
||||
IndexMeshVisitor
|
||||
|
||||
138
src/osgPlugins/gles/GeometryCleaner
Normal file
138
src/osgPlugins/gles/GeometryCleaner
Normal file
@@ -0,0 +1,138 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab
|
||||
*
|
||||
* This application is open source and may be redistributed and/or modified
|
||||
* freely and without restriction, both in commercial and non commercial
|
||||
* applications, as long as this copyright notice is maintained.
|
||||
*
|
||||
* This application 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GEOMETRY_CLEANER
|
||||
#define GEOMETRY_CLEANER
|
||||
|
||||
#include <osg/Geometry>
|
||||
#include <osgAnimation/RigGeometry>
|
||||
#include <osgAnimation/MorphGeometry>
|
||||
|
||||
#include "GeometryMapper"
|
||||
#include "SubGeometry"
|
||||
|
||||
|
||||
class GeometryCleaner : public GeometryMapper
|
||||
{
|
||||
public:
|
||||
|
||||
const GeometryList& process(osg::Geometry& geometry) {
|
||||
_clean.clear();
|
||||
|
||||
if(dynamic_cast<osgAnimation::MorphGeometry*>(&geometry)) {
|
||||
// a morph geometry may have a degenerated primitive in one target but not all targets
|
||||
// let's leave them unmodified
|
||||
_clean.push_back(&geometry);
|
||||
}
|
||||
else if(dynamic_cast<osgAnimation::RigGeometry*>(&geometry)) {
|
||||
// skipping rigged geometry for now
|
||||
_clean.push_back(&geometry);
|
||||
}
|
||||
else {
|
||||
osg::Vec3Array* positions = dynamic_cast<osg::Vec3Array*>(geometry.getVertexArray());
|
||||
SubGeometry cleaned(geometry,
|
||||
clean(*positions, getTriangles(geometry), 3),
|
||||
clean(*positions, getLines(geometry), 2),
|
||||
clean(*positions, getWireframe(geometry), 2),
|
||||
clean(*positions, getPoints(geometry), 1));
|
||||
_clean.push_back(cleaned.geometry());
|
||||
}
|
||||
|
||||
return _clean;
|
||||
}
|
||||
|
||||
osg::DrawElements* getTriangles(osg::Geometry& geometry) {
|
||||
for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) {
|
||||
osg::DrawElements* primitive = geometry.getPrimitiveSet(i)->getDrawElements();
|
||||
if(primitive && primitive->getMode() == osg::PrimitiveSet::TRIANGLES) {
|
||||
return primitive;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
osg::DrawElements* getLines(osg::Geometry& geometry) {
|
||||
for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) {
|
||||
osg::DrawElements* primitive = geometry.getPrimitiveSet(i)->getDrawElements();
|
||||
if(primitive && primitive->getMode() == osg::PrimitiveSet::LINES) {
|
||||
bool wireframe(false);
|
||||
if(!primitive->getUserValue("wireframe", wireframe) || !wireframe)
|
||||
return primitive;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
osg::DrawElements* getWireframe(osg::Geometry& geometry) {
|
||||
for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) {
|
||||
osg::DrawElements* primitive = geometry.getPrimitiveSet(i)->getDrawElements();
|
||||
if(primitive && primitive->getMode() == osg::PrimitiveSet::LINES) {
|
||||
bool wireframe(false);
|
||||
if(primitive->getUserValue("wireframe", wireframe) && wireframe)
|
||||
return primitive;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
osg::DrawElements* getPoints(osg::Geometry& geometry) {
|
||||
for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) {
|
||||
osg::DrawElements* primitive = geometry.getPrimitiveSet(i)->getDrawElements();
|
||||
if(primitive && primitive->getMode() == osg::PrimitiveSet::POINTS) {
|
||||
return primitive;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> clean(const osg::Vec3Array& positions, osg::DrawElements* elements, const unsigned int size) {
|
||||
std::vector<unsigned int> indices;
|
||||
|
||||
if(!elements) return indices;
|
||||
|
||||
for(unsigned int i = 0 ; i < elements->getNumIndices() ; i += size) {
|
||||
if(size == 3) {
|
||||
unsigned int v1 = elements->index(i),
|
||||
v2 = elements->index(i + 1),
|
||||
v3 = elements->index(i + 2);
|
||||
osg::Vec3 p1 = positions[v1],
|
||||
p2 = positions[v2],
|
||||
p3 = positions[v3];
|
||||
|
||||
osg::Vec3f cross = (p2 - p1) ^ (p3 - p1);
|
||||
if(cross.length()) {
|
||||
indices.push_back(v1);
|
||||
indices.push_back(v2);
|
||||
indices.push_back(v3);
|
||||
}
|
||||
}
|
||||
else if (size == 2) {
|
||||
unsigned int v1 = elements->index(i),
|
||||
v2 = elements->index(i + 1);
|
||||
if(!(positions[v1] == positions[v2])) {
|
||||
indices.push_back(v1);
|
||||
indices.push_back(v2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
indices.push_back(elements->index(i));
|
||||
}
|
||||
}
|
||||
|
||||
return indices;
|
||||
}
|
||||
|
||||
|
||||
GeometryList _clean;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -25,15 +25,81 @@
|
||||
#include <osgAnimation/RigGeometry>
|
||||
|
||||
#include "glesUtil"
|
||||
#include "GeometryMapper"
|
||||
#include "GeometryArray"
|
||||
#include "TriangleMeshGraph"
|
||||
#include "SubGeometry"
|
||||
#include "Line"
|
||||
|
||||
|
||||
class GeometryIndexSplitter
|
||||
class GeometryIndexSplitter : public GeometryMapper
|
||||
{
|
||||
protected:
|
||||
class Cluster {
|
||||
public:
|
||||
Cluster(unsigned int maxAllowedIndex):
|
||||
maxIndex(maxAllowedIndex)
|
||||
{
|
||||
}
|
||||
|
||||
bool full() const {
|
||||
return subvertices.size() >= maxIndex;
|
||||
}
|
||||
|
||||
bool fullOfTriangles() const {
|
||||
// consider worse case i.e. no triangle vertex is already in the cluster
|
||||
// so need room for 3 indices
|
||||
return subvertices.size() + 3 >= maxIndex;
|
||||
}
|
||||
|
||||
bool fullOfLines() const {
|
||||
return subvertices.size() + 2 >= maxIndex;
|
||||
}
|
||||
|
||||
bool contains(unsigned int v1, unsigned int v2) const {
|
||||
return contains(v1) && contains(v2);
|
||||
}
|
||||
|
||||
bool contains(unsigned int v1) const {
|
||||
return subvertices.count(v1);
|
||||
}
|
||||
|
||||
void addTriangle(unsigned int v1, unsigned int v2, unsigned v3) {
|
||||
subtriangles.push_back(v1);
|
||||
subtriangles.push_back(v2);
|
||||
subtriangles.push_back(v3);
|
||||
|
||||
subvertices.insert(v1);
|
||||
subvertices.insert(v2);
|
||||
subvertices.insert(v3);
|
||||
}
|
||||
|
||||
void addLine(unsigned int v1, unsigned int v2) {
|
||||
sublines.push_back(v1);
|
||||
sublines.push_back(v2);
|
||||
|
||||
subvertices.insert(v1);
|
||||
subvertices.insert(v2);
|
||||
}
|
||||
|
||||
void addPoint(unsigned int v1) {
|
||||
subpoints.push_back(v1);
|
||||
|
||||
subvertices.insert(v1);
|
||||
}
|
||||
|
||||
void addWire(unsigned int v1, unsigned int v2) {
|
||||
subwireframe.push_back(v1);
|
||||
subwireframe.push_back(v2);
|
||||
}
|
||||
|
||||
public:
|
||||
const unsigned int maxIndex;
|
||||
IndexVector subtriangles, subwireframe, sublines, subpoints;
|
||||
IndexSet subvertices;
|
||||
};
|
||||
|
||||
|
||||
class IndexCache : public IndexDeque {
|
||||
public:
|
||||
IndexCache(unsigned int size=64) : _size(size)
|
||||
@@ -48,18 +114,29 @@ protected:
|
||||
};
|
||||
|
||||
public:
|
||||
typedef std::vector< osg::ref_ptr<osg::Geometry> > GeometryList;
|
||||
|
||||
GeometryIndexSplitter(unsigned int maxAllowedIndex):
|
||||
_maxAllowedIndex(maxAllowedIndex)
|
||||
{}
|
||||
|
||||
const GeometryList& process(osg::Geometry& geometry) {
|
||||
_geometryList.clear();
|
||||
split(geometry);
|
||||
return _geometryList;
|
||||
}
|
||||
|
||||
bool split(osg::Geometry&);
|
||||
|
||||
unsigned int findCandidate(const IndexVector&);
|
||||
unsigned int findCandidate(const IndexVector&, const IndexVector&);
|
||||
void setTriangleCluster(const TriangleMeshGraph&, unsigned int, unsigned int, IndexVector&, IndexSet&, unsigned int&);
|
||||
void extract_primitives(const IndexSet&, const osg::DrawElements*, IndexVector&, unsigned int);
|
||||
template<typename C>
|
||||
typename C::value_type getNext(C& primitives, typename C::value_type default_value) {
|
||||
if(primitives.empty()) {
|
||||
return default_value;
|
||||
}
|
||||
typename C::value_type next = *primitives.begin();
|
||||
primitives.erase(primitives.begin());
|
||||
return next;
|
||||
}
|
||||
|
||||
unsigned int findCandidate(IndexSet&, const IndexCache&, const TriangleMeshGraph&);
|
||||
|
||||
protected:
|
||||
bool needToSplit(const osg::Geometry&) const;
|
||||
@@ -68,7 +145,6 @@ protected:
|
||||
|
||||
template<typename T>
|
||||
void setBufferBoundingBox(T*) const;
|
||||
void setValidIndices(std::set<unsigned int>&, const osg::DrawElements*) const;
|
||||
|
||||
public:
|
||||
const unsigned int _maxAllowedIndex;
|
||||
|
||||
@@ -11,8 +11,8 @@ bool GeometryIndexSplitter::split(osg::Geometry& geometry) {
|
||||
attachBufferBoundingBox(geometry);
|
||||
|
||||
osg::DrawElements *wire_primitive = 0,
|
||||
*line_primitive = 0,
|
||||
*point_primitive = 0;
|
||||
*line_primitive = 0,
|
||||
*point_primitive = 0;
|
||||
for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) {
|
||||
osg::DrawElements* primitive = (geometry.getPrimitiveSet(i) ? geometry.getPrimitiveSet(i)->getDrawElements() : 0);
|
||||
if(primitive) {
|
||||
@@ -31,29 +31,34 @@ bool GeometryIndexSplitter::split(osg::Geometry& geometry) {
|
||||
}
|
||||
}
|
||||
|
||||
TriangleMeshGraph graph(geometry, false);
|
||||
|
||||
// only wireframe can be processed directly as they simply "duplicate" triangle or edge data;
|
||||
// lines/points may reference points not used for triangles so we keep a set of primitives
|
||||
// that remain to process
|
||||
LineSet source_lines;
|
||||
IndexSet source_points;
|
||||
IndexSet triangles;
|
||||
LineSet lines, wires;
|
||||
IndexSet points;
|
||||
|
||||
for(unsigned int i = 0 ; i < graph.getNumTriangles() ; ++ i) {
|
||||
triangles.insert(i);
|
||||
}
|
||||
if(line_primitive) {
|
||||
for(unsigned int i = 0 ; i < line_primitive->getNumIndices() ; i += 2) {
|
||||
source_lines.insert(Line(line_primitive->index(i), line_primitive->index(i + 1)));
|
||||
lines.insert(Line(line_primitive->index(i), line_primitive->index(i + 1)));
|
||||
}
|
||||
}
|
||||
if(wire_primitive) {
|
||||
for(unsigned int i = 0 ; i < wire_primitive->getNumIndices() ; i += 2) {
|
||||
wires.insert(Line(wire_primitive->index(i), wire_primitive->index(i + 1)));
|
||||
}
|
||||
}
|
||||
if(point_primitive) {
|
||||
for(unsigned int i = 0 ; i < point_primitive->getNumIndices() ; ++ i) {
|
||||
source_points.insert(point_primitive->index(i));
|
||||
points.insert(point_primitive->index(i));
|
||||
}
|
||||
}
|
||||
|
||||
TriangleMeshGraph graph(geometry, false);
|
||||
unsigned int remaining_triangles = graph.getNumTriangles(),
|
||||
cluster = 0;
|
||||
IndexVector clusters(remaining_triangles, 0);
|
||||
IndexCache cache;
|
||||
|
||||
// assign a cluster id for each triangle
|
||||
// 1. bootstrap cluster by selecting first remaining triangle
|
||||
// 2. while cluster size is < max cluster size
|
||||
@@ -64,95 +69,75 @@ bool GeometryIndexSplitter::split(osg::Geometry& geometry) {
|
||||
// 3. insert wireframe edges corresponding to selected triangles
|
||||
// 4. extract subgeometry
|
||||
|
||||
while(remaining_triangles || !source_lines.empty() || !source_points.empty()) {
|
||||
IndexVector subtriangles, subwireframe, sublines, subpoints;
|
||||
IndexSet cluster_vertices;
|
||||
while(triangles.size() || lines.size() || points.size()) {
|
||||
Cluster cluster(_maxAllowedIndex);
|
||||
IndexCache cache;
|
||||
unsigned int candidate = std::numeric_limits<unsigned int>::max();
|
||||
|
||||
++ cluster;
|
||||
// let's consider that every insert needs the place for a full new primitive for simplicity
|
||||
while(!cluster.fullOfTriangles() &&
|
||||
(candidate = findCandidate(triangles, cache, graph)) != std::numeric_limits<unsigned int>::max()) {
|
||||
cache.push_back(candidate);
|
||||
Triangle t = graph.triangle(candidate);
|
||||
cluster.addTriangle(t.v1(), t.v2(), t.v3());
|
||||
}
|
||||
|
||||
if(remaining_triangles) {
|
||||
// find first unmarked triangle (as remaining_triangles > 0 there *must* be at least one)
|
||||
cache.push_back(findCandidate(clusters));
|
||||
setTriangleCluster(graph, cache.back(), cluster, clusters, cluster_vertices, remaining_triangles);
|
||||
while(!cluster.fullOfLines() && lines.size()) {
|
||||
Line line = getNext(lines, Line(std::numeric_limits<unsigned int>::max(), std::numeric_limits<unsigned int>::max()));
|
||||
cluster.addLine(line._a, line._b);
|
||||
}
|
||||
|
||||
while(remaining_triangles && cluster_vertices.size() < _maxAllowedIndex) {
|
||||
unsigned int candidate = std::numeric_limits<unsigned int>::max();
|
||||
while(!cluster.full() && points.size()) {
|
||||
unsigned int point = getNext(points, std::numeric_limits<unsigned int>::max());
|
||||
cluster.addPoint(point);
|
||||
}
|
||||
|
||||
for(IndexCache::const_reverse_iterator cached = cache.rbegin() ; cached != cache.rend() ; ++ cached) {
|
||||
candidate = findCandidate(graph.triangleNeighbors(*cached), clusters);
|
||||
if(candidate != std::numeric_limits<unsigned int>::max()) break;
|
||||
// update lines/points: if all vertices referenced by a point/line primitive are
|
||||
// already extracted, let's insert it in the subgeometry and update the set of
|
||||
// primitives still remaining Lines may e.g. reference one vertex in cluster A and
|
||||
// the other in cluster B hence need specific care
|
||||
if(line_primitive) {
|
||||
for(LineSet::iterator line = lines.begin() ; line != lines.end() ; ) {
|
||||
if(cluster.contains(line->_a, line->_b)) {
|
||||
cluster.addLine(line->_a, line->_b);
|
||||
lines.erase(line ++);
|
||||
}
|
||||
|
||||
if(candidate == std::numeric_limits<unsigned int>::max()) {
|
||||
// do we have room for a triangle having all vertices not in the cluster?
|
||||
if(!(cluster_vertices.size() + 2 < _maxAllowedIndex)) {
|
||||
break;
|
||||
}
|
||||
|
||||
candidate = findCandidate(clusters);
|
||||
}
|
||||
|
||||
cache.push_back(candidate);
|
||||
setTriangleCluster(graph, candidate, cluster, clusters, cluster_vertices, remaining_triangles);
|
||||
}
|
||||
|
||||
// build list of cluster triangles
|
||||
for(unsigned int triangle = 0 ; triangle < clusters.size() ; ++ triangle) {
|
||||
if(clusters[triangle] == cluster) {
|
||||
const Triangle& t = graph.triangle(triangle);
|
||||
subtriangles.push_back(t.v1());
|
||||
subtriangles.push_back(t.v2());
|
||||
subtriangles.push_back(t.v3());
|
||||
}
|
||||
}
|
||||
|
||||
// update lines/points: if all vertices referenced by a point/line primitive are
|
||||
// already extracted, let's insert it in the subgeometry and update the set of
|
||||
// primitives still remaining Lines may e.g. reference one vertex in cluster A and
|
||||
// the other in cluster B hence need specific care
|
||||
if(line_primitive) {
|
||||
extract_primitives(cluster_vertices, line_primitive, sublines, 2);
|
||||
for(unsigned int i = 0 ; i < sublines.size() / 2 ; i += 2) {
|
||||
source_lines.erase(Line(sublines[i], sublines[i + 1]));
|
||||
}
|
||||
}
|
||||
|
||||
if(point_primitive) {
|
||||
extract_primitives(cluster_vertices, point_primitive, subpoints, 1);
|
||||
for(unsigned int i = 0 ; i < subpoints.size() ; ++ i) {
|
||||
source_points.erase(subpoints[i]);
|
||||
else {
|
||||
++ line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// let's consider that every new lines adds 2 vertices for simplicity
|
||||
while(!source_lines.empty() && cluster_vertices.size() - 1 < _maxAllowedIndex) {
|
||||
Line line = *source_lines.begin();
|
||||
source_lines.erase(source_lines.begin());
|
||||
cluster_vertices.insert(line._a);
|
||||
cluster_vertices.insert(line._b);
|
||||
sublines.push_back(line._a);
|
||||
sublines.push_back(line._b);
|
||||
}
|
||||
|
||||
while(!source_points.empty() && cluster_vertices.size() < _maxAllowedIndex) {
|
||||
unsigned int point = *source_points.begin();
|
||||
source_points.erase(source_points.begin());
|
||||
cluster_vertices.insert(point);
|
||||
subpoints.push_back(point);
|
||||
if(point_primitive) {
|
||||
// find all cluster vertices that should also have a point primitive
|
||||
for(IndexSet::iterator subvertex = cluster.subvertices.begin() ; subvertex != cluster.subvertices.end() ; ++ subvertex) {
|
||||
unsigned int index = *subvertex;
|
||||
if(points.find(index) != points.end()) {
|
||||
cluster.addPoint(index);
|
||||
points.erase(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finally extract wireframe (may originate from triangles or lines but necessarily have
|
||||
// to reference vertices that are *all* in the geometry)
|
||||
if(wire_primitive) {
|
||||
extract_primitives(cluster_vertices, wire_primitive, subwireframe, 2);
|
||||
for(LineSet::iterator wire = wires.begin() ; wire != wires.end() ; ) {
|
||||
if(cluster.contains(wire->_a, wire->_b)) {
|
||||
cluster.addWire(wire->_a, wire->_b);
|
||||
wires.erase(wire ++);
|
||||
}
|
||||
else {
|
||||
++ wire;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_geometryList.push_back(SubGeometry(geometry,
|
||||
subtriangles,
|
||||
sublines,
|
||||
subwireframe,
|
||||
subpoints).geometry());
|
||||
cluster.subtriangles,
|
||||
cluster.sublines,
|
||||
cluster.subwireframe,
|
||||
cluster.subpoints).geometry());
|
||||
}
|
||||
|
||||
osg::notify(osg::NOTICE) << "geometry " << &geometry << " " << geometry.getName()
|
||||
@@ -164,60 +149,20 @@ bool GeometryIndexSplitter::split(osg::Geometry& geometry) {
|
||||
}
|
||||
|
||||
|
||||
unsigned int GeometryIndexSplitter::findCandidate(const IndexVector& clusters) {
|
||||
for(unsigned int i = 0 ; i < clusters.size() ; ++ i) {
|
||||
if(!clusters[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return std::numeric_limits<unsigned int>::max();
|
||||
}
|
||||
|
||||
|
||||
unsigned int GeometryIndexSplitter::findCandidate(const IndexVector& candidates, const IndexVector& clusters) {
|
||||
for(IndexVector::const_iterator candidate = candidates.begin() ; candidate != candidates.end() ; ++ candidate) {
|
||||
if(!clusters[*candidate]) {
|
||||
return *candidate;
|
||||
}
|
||||
}
|
||||
return std::numeric_limits<unsigned int>::max();
|
||||
}
|
||||
|
||||
|
||||
void GeometryIndexSplitter::setTriangleCluster(const TriangleMeshGraph& graph,
|
||||
unsigned int triangle,
|
||||
unsigned int cluster,
|
||||
IndexVector& clusters,
|
||||
IndexSet& cluster_vertices,
|
||||
unsigned int& remaining) {
|
||||
clusters[triangle] = cluster;
|
||||
const Triangle& t = graph.triangle(triangle);
|
||||
cluster_vertices.insert(t.v1());
|
||||
cluster_vertices.insert(t.v2());
|
||||
cluster_vertices.insert(t.v3());
|
||||
remaining --;
|
||||
}
|
||||
|
||||
|
||||
void GeometryIndexSplitter::extract_primitives(const IndexSet& vertices,
|
||||
const osg::DrawElements* elements,
|
||||
IndexVector& indices,
|
||||
unsigned int primitive_size) {
|
||||
for(unsigned int i = 0 ; i < elements->getNumIndices() ; i += primitive_size) {
|
||||
bool is_included = true;
|
||||
for(unsigned int j = 0 ; j < primitive_size ; ++ j) {
|
||||
if(!vertices.count(elements->index(i + j))) {
|
||||
is_included = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(is_included) {
|
||||
for(unsigned int j = 0 ; j < primitive_size ; ++ j) {
|
||||
indices.push_back(elements->index(i + j));
|
||||
unsigned int GeometryIndexSplitter::findCandidate(IndexSet& triangles, const IndexCache& cache, const TriangleMeshGraph& graph) {
|
||||
// look for unclustered neighboring triangles
|
||||
for(IndexCache::const_reverse_iterator cached = cache.rbegin() ; cached != cache.rend() ; ++ cached) {
|
||||
IndexVector candidates = graph.triangleNeighbors(*cached);
|
||||
for(IndexVector::const_iterator candidate = candidates.begin() ; candidate != candidates.end() ; ++ candidate) {
|
||||
if(triangles.count(*candidate)) {
|
||||
triangles.erase(*candidate);
|
||||
return *candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//fallback on any unclustered triangle
|
||||
return getNext(triangles, std::numeric_limits<unsigned int>::max());
|
||||
}
|
||||
|
||||
|
||||
@@ -276,10 +221,3 @@ void GeometryIndexSplitter::setBufferBoundingBox(T* buffer) const {
|
||||
buffer->setUserValue("ufr", ufr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GeometryIndexSplitter::setValidIndices(std::set<unsigned int>& indices, const osg::DrawElements* primitive) const {
|
||||
for(unsigned int j = 0 ; j < primitive->getNumIndices() ; ++ j) {
|
||||
indices.insert(primitive->index(j));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "GeometryUniqueVisitor"
|
||||
#include "glesUtil"
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osgDB/ReaderWriter>
|
||||
@@ -34,8 +35,7 @@ public:
|
||||
osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList();
|
||||
unsigned int count = 0;
|
||||
for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target, ++ count) {
|
||||
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry(*target->getGeometry());
|
||||
geometry->setPrimitiveSetList(morphGeometry.getPrimitiveSetList());
|
||||
glesUtil::TargetGeometry geometry(*target, morphGeometry);
|
||||
std::ostringstream oss;
|
||||
if(geometry->getName().empty()) {
|
||||
oss << "/tmp/noname_" << _processed.size();
|
||||
|
||||
31
src/osgPlugins/gles/GeometryMapper
Normal file
31
src/osgPlugins/gles/GeometryMapper
Normal file
@@ -0,0 +1,31 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab
|
||||
*
|
||||
* This application is open source and may be redistributed and/or modified
|
||||
* freely and without restriction, both in commercial and non commercial
|
||||
* applications, as long as this copyright notice is maintained.
|
||||
*
|
||||
* This application 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GEOMETRY_MAPPER
|
||||
#define GEOMETRY_MAPPER
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Geometry>
|
||||
|
||||
typedef std::vector< osg::ref_ptr<osg::Geometry> > GeometryList;
|
||||
|
||||
class GeometryMapper {
|
||||
public:
|
||||
|
||||
// map one geometry to a list of geometries
|
||||
// to be used with RemapGeometryVisitor
|
||||
virtual const GeometryList& process(osg::Geometry&) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -16,26 +16,32 @@
|
||||
#include <osg/Node>
|
||||
#include <algorithm> //std::max
|
||||
|
||||
#include "AnimationCleanerVisitor"
|
||||
#include "RigAnimationVisitor"
|
||||
//animation:
|
||||
#include "AABBonBoneVisitor"
|
||||
#include "AnimationCleanerVisitor"
|
||||
#include "DisableAnimationVisitor"
|
||||
#include "LimitMorphTargetCount"
|
||||
#include "MostInfluencedGeometryByBone"
|
||||
#include "RigAnimationVisitor"
|
||||
#include "RigAttributesVisitor"
|
||||
|
||||
// geometry:
|
||||
#include "BindPerVertexVisitor"
|
||||
#include "DetachPrimitiveVisitor"
|
||||
#include "DrawArrayVisitor"
|
||||
#include "GeometrySplitterVisitor"
|
||||
#include "IndexMeshVisitor"
|
||||
#include "PreTransformVisitor"
|
||||
#include "RemapGeometryVisitor"
|
||||
#include "SmoothNormalVisitor"
|
||||
#include "TangentSpaceVisitor"
|
||||
#include "TriangleStripVisitor"
|
||||
#include "UnIndexMeshVisitor"
|
||||
#include "WireframeVisitor"
|
||||
#include "AABBonBoneVisitor"
|
||||
#include "AnimationCleanerVisitor"
|
||||
#include "MostInfluencedGeometryByBone"
|
||||
#include "LimitMorphTargetCount"
|
||||
#include "RigAttributesVisitor"
|
||||
|
||||
#include "GeometryIndexSplitter"
|
||||
#include "GeometryCleaner"
|
||||
|
||||
// debug
|
||||
#include "GeometryInspector"
|
||||
|
||||
|
||||
@@ -165,6 +171,12 @@ protected:
|
||||
node->accept(indexer);
|
||||
}
|
||||
|
||||
void makeCleanGeometry(osg::Node* node) {
|
||||
GeometryCleaner cleaner;
|
||||
RemapGeometryVisitor remapper(cleaner, _exportNonGeometryDrawables);
|
||||
node->accept(remapper);
|
||||
}
|
||||
|
||||
void makeSmoothNormal(osg::Node* node) {
|
||||
SmoothNormalVisitor smoother(osg::PI / 4.f, true);
|
||||
node->accept(smoother);
|
||||
@@ -176,8 +188,9 @@ protected:
|
||||
}
|
||||
|
||||
void makeSplit(osg::Node* node) {
|
||||
GeometrySplitterVisitor splitter(_maxIndexValue, _exportNonGeometryDrawables );
|
||||
node->accept(splitter);
|
||||
GeometryIndexSplitter splitter(_maxIndexValue);
|
||||
RemapGeometryVisitor remapper(splitter, _exportNonGeometryDrawables);
|
||||
node->accept(remapper);
|
||||
}
|
||||
|
||||
void makeTriStrip(osg::Node* node) {
|
||||
|
||||
@@ -26,6 +26,12 @@ osg::Node* OpenGLESGeometryOptimizer::optimize(osg::Node& node) {
|
||||
// index (merge exact duplicates + uses simple triangles & lines i.e. no strip/fan/loop)
|
||||
makeIndexMesh(model.get());
|
||||
|
||||
// clean (remove degenerated data)
|
||||
std::string authoringTool;
|
||||
if(model->getUserValue("authoring_tool", authoringTool) && authoringTool == "Tilt Brush") {
|
||||
makeCleanGeometry(model.get());
|
||||
}
|
||||
|
||||
// smooth vertex normals (if geometry has no normal compute smooth normals)
|
||||
makeSmoothNormal(model.get());
|
||||
|
||||
|
||||
51
src/osgPlugins/gles/RemapGeometryVisitor
Normal file
51
src/osgPlugins/gles/RemapGeometryVisitor
Normal file
@@ -0,0 +1,51 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab
|
||||
*
|
||||
* This application is open source and may be redistributed and/or modified
|
||||
* freely and without restriction, both in commercial and non commercial
|
||||
* applications, as long as this copyright notice is maintained.
|
||||
*
|
||||
* This application 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef REMAP_GEOMETRY_VISITOR
|
||||
#define REMAP_GEOMETRY_VISITOR
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Geometry>
|
||||
#include <osgAnimation/RigGeometry>
|
||||
|
||||
#include "GeometryUniqueVisitor"
|
||||
#include "GeometryMapper"
|
||||
|
||||
|
||||
class RemapGeometryVisitor : public GeometryUniqueVisitor {
|
||||
public:
|
||||
typedef std::vector< osg::ref_ptr<osg::Geometry> > GeometryList;
|
||||
typedef std::vector< osg::ref_ptr<osg::Drawable> > DrawableList;
|
||||
typedef std::map<osg::Geometry*, GeometryList> GeometryMap;
|
||||
|
||||
RemapGeometryVisitor(GeometryMapper& mapper, bool exportNonGeometryDrawables=false):
|
||||
GeometryUniqueVisitor("RemapGeometryVisitor"),
|
||||
_mapper(mapper),
|
||||
_exportNonGeometryDrawables(exportNonGeometryDrawables)
|
||||
{}
|
||||
|
||||
void apply(osg::Geode&);
|
||||
void process(osg::Geometry&);
|
||||
|
||||
protected:
|
||||
bool isProcessed(osg::Geometry*);
|
||||
void setProcessed(osg::Geometry*, const GeometryList&);
|
||||
|
||||
protected:
|
||||
GeometryMapper& _mapper;
|
||||
std::map<osg::Geometry*, GeometryList> _remap;
|
||||
bool _exportNonGeometryDrawables;
|
||||
};
|
||||
|
||||
#endif
|
||||
72
src/osgPlugins/gles/RemapGeometryVisitor.cpp
Normal file
72
src/osgPlugins/gles/RemapGeometryVisitor.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "RemapGeometryVisitor"
|
||||
#include "glesUtil"
|
||||
|
||||
|
||||
void RemapGeometryVisitor::apply(osg::Geode& geode) {
|
||||
GeometryUniqueVisitor::apply(geode);
|
||||
GeometryList remappedGeometries;
|
||||
DrawableList nonGeometryDrawables;
|
||||
|
||||
for(unsigned int i = 0 ; i < geode.getNumDrawables() ; ++ i) {
|
||||
osg::Geometry* geometry = geode.getDrawable(i)->asGeometry();
|
||||
if(geometry) {
|
||||
if(osgAnimation::RigGeometry* rigGeometry = dynamic_cast<osgAnimation::RigGeometry*>(geometry)) {
|
||||
GeometryMap::iterator lookup = _remap.find(rigGeometry->getSourceGeometry());
|
||||
if(lookup != _remap.end() && !lookup->second.empty()) {
|
||||
|
||||
// convert now static rigGeometry into simple Geometry
|
||||
for(GeometryList::iterator mapped = lookup->second.begin() ; mapped != lookup->second.end() ; ++ mapped) {
|
||||
if(glesUtil::hasPositiveWeights(mapped->get())) {
|
||||
osgAnimation::RigGeometry* mappedRig = new osgAnimation::RigGeometry(*rigGeometry);
|
||||
mappedRig->setSourceGeometry(mapped->get());
|
||||
remappedGeometries.push_back(mappedRig);
|
||||
}
|
||||
else {
|
||||
remappedGeometries.push_back(mapped->get());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
GeometryMap::iterator lookup = _remap.find(geometry);
|
||||
if(lookup != _remap.end() && !lookup->second.empty()) {
|
||||
remappedGeometries.insert(remappedGeometries.end(), lookup->second.begin(), lookup->second.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
nonGeometryDrawables.push_back(geode.getDrawable(i));
|
||||
}
|
||||
}
|
||||
|
||||
// remove all drawables
|
||||
geode.removeDrawables(0, geode.getNumDrawables());
|
||||
// insert splitted geometries
|
||||
for(unsigned int i = 0 ; i < remappedGeometries.size() ; ++ i) {
|
||||
geode.addDrawable(remappedGeometries[i].get());
|
||||
}
|
||||
|
||||
if(_exportNonGeometryDrawables) {
|
||||
// insert other drawables (e.g. osgText)
|
||||
for(unsigned int i = 0 ; i < nonGeometryDrawables.size() ; ++ i) {
|
||||
geode.addDrawable(nonGeometryDrawables[i].get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RemapGeometryVisitor::process(osg::Geometry& geometry) {
|
||||
const GeometryList& mapped = _mapper.process(geometry);
|
||||
setProcessed(&geometry, mapped);
|
||||
}
|
||||
|
||||
|
||||
bool RemapGeometryVisitor::isProcessed(osg::Geometry* node) {
|
||||
return _remap.find(node) != _remap.end();
|
||||
}
|
||||
|
||||
|
||||
void RemapGeometryVisitor::setProcessed(osg::Geometry* node, const GeometryList& list) {
|
||||
_remap.insert(std::pair<osg::Geometry*, GeometryList>(node, GeometryList(list)));
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "GeometryUniqueVisitor"
|
||||
#include "TriangleMeshSmoother"
|
||||
#include "glesUtil"
|
||||
|
||||
|
||||
class SmoothNormalVisitor : public GeometryUniqueVisitor {
|
||||
@@ -25,20 +26,41 @@ public:
|
||||
}
|
||||
|
||||
void process(osgAnimation::MorphGeometry& morphGeometry) {
|
||||
TriangleMeshSmoother(morphGeometry, 0, true, TriangleMeshSmoother::smooth_all);
|
||||
osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList();
|
||||
for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) {
|
||||
// check normal orientation using the same primitives as parent geometry
|
||||
osg::Geometry::PrimitiveSetList& primitives = target->getGeometry()->getPrimitiveSetList();
|
||||
target->getGeometry()->setPrimitiveSetList(morphGeometry.getPrimitiveSetList());
|
||||
bool needSmoothing = needMorphGeometrySmoothing(morphGeometry);
|
||||
|
||||
TriangleMeshSmoother(*target->getGeometry(), 0, true, TriangleMeshSmoother::smooth_all);
|
||||
if(needSmoothing) {
|
||||
TriangleMeshSmoother(morphGeometry, 0, true, TriangleMeshSmoother::smooth_all);
|
||||
|
||||
target->getGeometry()->setPrimitiveSetList(primitives);
|
||||
osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList();
|
||||
for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) {
|
||||
// check normal orientation using the same primitives as parent geometry
|
||||
glesUtil::TargetGeometry geometry(*target, morphGeometry);
|
||||
if(geometry && !geometry->getNormalArray()) {
|
||||
TriangleMeshSmoother(*geometry, 0, true, TriangleMeshSmoother::smooth_all);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
bool needMorphGeometrySmoothing(osgAnimation::MorphGeometry& morphGeometry) {
|
||||
if(!morphGeometry.getNormalArray()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList();
|
||||
|
||||
for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) {
|
||||
osg::Geometry* geometry = target->getGeometry();
|
||||
if(geometry && !geometry->getNormalArray()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
float _creaseAngle;
|
||||
bool _comparePosition;
|
||||
};
|
||||
|
||||
@@ -1,26 +1,13 @@
|
||||
#include "TangentSpaceVisitor"
|
||||
|
||||
#include "glesUtil"
|
||||
|
||||
void TangentSpaceVisitor::process(osgAnimation::MorphGeometry& morphGeometry) {
|
||||
process(static_cast<osg::Geometry&>(morphGeometry));
|
||||
|
||||
osgAnimation::MorphGeometry::MorphTargetList& targets = morphGeometry.getMorphTargetList();
|
||||
for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) {
|
||||
osg::Geometry* geometry = target->getGeometry();
|
||||
bool useParentMorphTexCoord = geometry->getTexCoordArrayList().empty();
|
||||
|
||||
if(useParentMorphTexCoord) {
|
||||
// tangent space require tex coords; in case a target has no tex coords, we try to
|
||||
// bind the parent geometry tex coords
|
||||
geometry->setTexCoordArrayList(morphGeometry.getTexCoordArrayList());
|
||||
}
|
||||
|
||||
glesUtil::TargetGeometry geometry(*target, morphGeometry);
|
||||
process(*geometry);
|
||||
|
||||
if(useParentMorphTexCoord) {
|
||||
// drop parent tex coords after tangent space computation
|
||||
geometry->setTexCoordArrayList(osg::Geometry::ArrayList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +23,9 @@ void TangentSpaceVisitor::process(osg::Geometry& geometry) {
|
||||
geometry.getVertexAttribArray(tangentIndex)->setUserValue("tangent", true);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
OSG_WARN << "Anomaly: [TangentSpaceVisitor] Missing tangent array at specificied index." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (!geometry.getTexCoordArray(_textureUnit)){
|
||||
@@ -56,21 +46,6 @@ void TangentSpaceVisitor::process(osg::Geometry& geometry) {
|
||||
osg::ref_ptr<osgUtil::TangentSpaceGenerator> generator = new osgUtil::TangentSpaceGenerator;
|
||||
generator->generate(&geometry, _textureUnit);
|
||||
|
||||
// keep original normal array
|
||||
if (!geometry.getNormalArray()) {
|
||||
if (generator->getNormalArray()) {
|
||||
osg::Vec3Array* vec3Normals = new osg::Vec3Array();
|
||||
osg::Vec4Array* vec4Normals = generator->getNormalArray();
|
||||
for (unsigned int i = 0; i < vec4Normals->size(); i++) {
|
||||
osg::Vec3 n = osg::Vec3((*vec4Normals)[i][0],
|
||||
(*vec4Normals)[i][1],
|
||||
(*vec4Normals)[i][2]);
|
||||
vec3Normals->push_back(n);
|
||||
}
|
||||
geometry.setNormalArray(vec3Normals, osg::Array::BIND_PER_VERTEX);
|
||||
}
|
||||
}
|
||||
|
||||
if (generator->getTangentArray()) {
|
||||
osg::Vec4Array* normal = generator->getNormalArray();
|
||||
osg::Vec4Array* tangent = generator->getTangentArray();
|
||||
|
||||
@@ -244,14 +244,16 @@ void TriangleMeshSmoother::updateGeometryPrimitives() {
|
||||
}
|
||||
}
|
||||
|
||||
osg::DrawElementsUInt* triangles = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
|
||||
for(unsigned int i = 0 ; i < _graph->getNumTriangles() ; ++ i) {
|
||||
const Triangle& triangle = _graph->triangle(i);
|
||||
triangles->push_back(triangle.v1());
|
||||
triangles->push_back(triangle.v2());
|
||||
triangles->push_back(triangle.v3());
|
||||
if(_graph->getNumTriangles()) {
|
||||
osg::DrawElementsUInt* triangles = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
|
||||
for(unsigned int i = 0 ; i < _graph->getNumTriangles() ; ++ i) {
|
||||
const Triangle& triangle = _graph->triangle(i);
|
||||
triangles->push_back(triangle.v1());
|
||||
triangles->push_back(triangle.v2());
|
||||
triangles->push_back(triangle.v3());
|
||||
}
|
||||
primitives.push_back(triangles);
|
||||
}
|
||||
primitives.push_back(triangles);
|
||||
|
||||
_geometry.setPrimitiveSetList(primitives);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace glesUtil {
|
||||
using namespace std;
|
||||
using namespace osg;
|
||||
typedef std::vector<unsigned int> IndexList;
|
||||
|
||||
typedef osgAnimation::MorphGeometry::MorphTargetList MorphTargetList;
|
||||
|
||||
inline bool hasPositiveWeights(const osg::Geometry* geometry) {
|
||||
const osg::Vec4Array* weights = 0;
|
||||
@@ -53,6 +53,52 @@ namespace glesUtil {
|
||||
}
|
||||
|
||||
|
||||
class TargetGeometry {
|
||||
public:
|
||||
TargetGeometry(osgAnimation::MorphGeometry::MorphTarget& target,
|
||||
osgAnimation::MorphGeometry& morph):
|
||||
_geometry(0)
|
||||
{
|
||||
_geometry = target.getGeometry();
|
||||
_geometry->setPrimitiveSetList(morph.getPrimitiveSetList());
|
||||
|
||||
_hasTexCoord = _geometry->getTexCoordArrayList().size();
|
||||
if(!_hasTexCoord) {
|
||||
_geometry->setTexCoordArrayList(morph.getTexCoordArrayList());
|
||||
}
|
||||
}
|
||||
|
||||
osg::Geometry* operator->() {
|
||||
return _geometry;
|
||||
}
|
||||
|
||||
operator osg::Geometry*() {
|
||||
return _geometry;
|
||||
}
|
||||
|
||||
operator osg::Geometry&() {
|
||||
return *_geometry;
|
||||
}
|
||||
|
||||
operator bool() {
|
||||
return _geometry != 0;
|
||||
}
|
||||
|
||||
~TargetGeometry() {
|
||||
if(!_hasTexCoord) {
|
||||
// drop parent tex coords after tangent space computation
|
||||
_geometry->setTexCoordArrayList(osg::Geometry::ArrayList());
|
||||
}
|
||||
_geometry->setPrimitiveSetList(osg::Geometry::PrimitiveSetList());
|
||||
}
|
||||
|
||||
protected:
|
||||
osg::Geometry* _geometry;
|
||||
bool _hasTexCoord;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// A helper class that gathers up all the attribute arrays of an
|
||||
// osg::Geometry object that are BIND_PER_VERTEX and runs an
|
||||
// ArrayVisitor on them.
|
||||
@@ -61,6 +107,20 @@ namespace glesUtil {
|
||||
typedef std::vector<osg::Array*> ArrayList;
|
||||
|
||||
GeometryArrayGatherer(osg::Geometry& geometry) {
|
||||
addGeometryVertexAttributes(geometry);
|
||||
_targetAttributesIndex = _arrayList.size();
|
||||
|
||||
if(osgAnimation::MorphGeometry* morphGeometry = dynamic_cast<osgAnimation::MorphGeometry*>(&geometry)) {
|
||||
MorphTargetList targets = morphGeometry->getMorphTargetList();
|
||||
for (MorphTargetList::iterator iterator = targets.begin(); iterator != targets.end(); ++ iterator) {
|
||||
if(iterator->getGeometry()) {
|
||||
addTargetVertexAttributes(*iterator->getGeometry());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addGeometryVertexAttributes(osg::Geometry& geometry) {
|
||||
add(geometry.getVertexArray());
|
||||
add(geometry.getNormalArray());
|
||||
add(geometry.getColorArray());
|
||||
@@ -74,6 +134,10 @@ namespace glesUtil {
|
||||
}
|
||||
}
|
||||
|
||||
void addTargetVertexAttributes(osg::Geometry& target) {
|
||||
add(target.getVertexArray());
|
||||
}
|
||||
|
||||
void add(osg::Array* array) {
|
||||
if (array) {
|
||||
_arrayList.push_back(array);
|
||||
@@ -81,12 +145,16 @@ namespace glesUtil {
|
||||
}
|
||||
|
||||
void accept(osg::ArrayVisitor& av) {
|
||||
for(ArrayList::iterator itr = _arrayList.begin() ; itr != _arrayList.end(); ++ itr) {
|
||||
unsigned int geometryAttributesIndex = 0;
|
||||
for(ArrayList::iterator itr = _arrayList.begin() ;
|
||||
geometryAttributesIndex < _targetAttributesIndex && itr != _arrayList.end();
|
||||
++ geometryAttributesIndex, ++ itr) {
|
||||
(*itr)->accept(av);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList _arrayList;
|
||||
unsigned int _targetAttributesIndex;
|
||||
};
|
||||
|
||||
|
||||
@@ -349,8 +417,8 @@ namespace glesUtil {
|
||||
void remapTargetVertices(Remapper remapper, Geometry& geom)
|
||||
{
|
||||
if(osgAnimation::MorphGeometry *morphGeometry = dynamic_cast<osgAnimation::MorphGeometry*>(&geom)) {
|
||||
osgAnimation::MorphGeometry::MorphTargetList targetList = morphGeometry->getMorphTargetList();
|
||||
for (osgAnimation::MorphGeometry::MorphTargetList::iterator ti = targetList.begin(); ti != targetList.end(); ++ti) {
|
||||
MorphTargetList targetList = morphGeometry->getMorphTargetList();
|
||||
for (MorphTargetList::iterator ti = targetList.begin(); ti != targetList.end(); ++ti) {
|
||||
osgAnimation::MorphGeometry::MorphTarget *morphTarget = &(*ti);
|
||||
osg::Geometry *target = morphTarget->getGeometry();
|
||||
GeometryArrayGatherer gatherer(*target);
|
||||
|
||||
@@ -45,7 +45,7 @@ bool addJSONChannel(const std::string& channelType, T* channel, bool packByCoord
|
||||
osg::ref_ptr<JSONObject> json = new JSONObject;
|
||||
std::string jsonType = channelType + (packByCoords ? "Packed" : "");
|
||||
|
||||
translateObject(json.get(), channel);
|
||||
writer->translateObject(json.get(), channel);
|
||||
|
||||
json->getMaps()["Name"] = new JSONValue<std::string>(channel->getName());
|
||||
json->getMaps()["TargetName"] = new JSONValue<std::string>(channel->getTargetName());
|
||||
|
||||
@@ -125,7 +125,7 @@ public:
|
||||
writer.setBaseName(basename);
|
||||
writer.useExternalBinaryArray(options.useExternalBinaryArray);
|
||||
writer.mergeAllBinaryFiles(options.mergeAllBinaryFiles);
|
||||
writer.inlineImages(options.inlineImages);
|
||||
writer.setInlineImages(options.inlineImages);
|
||||
writer.setMaxTextureDimension(options.resizeTextureUpToPowerOf2);
|
||||
writer.setVarint(options.varint);
|
||||
writer.setBaseLodURL(options.baseLodURL);
|
||||
|
||||
@@ -29,8 +29,10 @@
|
||||
#include <osgAnimation/Bone>
|
||||
#include <osgAnimation/UpdateBone>
|
||||
|
||||
#include <osgSim/ShapeAttribute>
|
||||
|
||||
#include <osgText/Text>
|
||||
#
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
@@ -47,8 +49,9 @@
|
||||
#define WRITER_VERSION 9
|
||||
|
||||
|
||||
class WriteVisitor;
|
||||
|
||||
osg::Array* getTangentSpaceArray(osg::Geometry& geometry);
|
||||
void translateObject(JSONObject* json, osg::Object* osg);
|
||||
void getStringifiedUserValue(osg::Object* o, std::string& name, std::string& value);
|
||||
template<typename T>
|
||||
bool getStringifiedUserValue(osg::Object* o, std::string& name, std::string& value);
|
||||
@@ -59,8 +62,9 @@ class WriteVisitor : public osg::NodeVisitor
|
||||
public:
|
||||
typedef std::vector<osg::ref_ptr<osg::StateSet> > StateSetStack;
|
||||
typedef std::pair<std::string, std::string> KeyValue;
|
||||
typedef std::map<osg::ref_ptr<osg::Object>, osg::ref_ptr<JSONObject> > OsgObjectToJSONObject;
|
||||
|
||||
std::map<osg::ref_ptr<osg::Object>, osg::ref_ptr<JSONObject> > _maps;
|
||||
OsgObjectToJSONObject _maps;
|
||||
std::vector<osg::ref_ptr<JSONObject> > _parents;
|
||||
osg::ref_ptr<JSONObject> _root;
|
||||
StateSetStack _stateset;
|
||||
@@ -74,6 +78,20 @@ public:
|
||||
std::map<KeyValue, std::string> _specificBuffers;
|
||||
std::map<std::string, std::ofstream*> _buffers;
|
||||
|
||||
JSONObject* getJSON(osg::Object* object) const {
|
||||
OsgObjectToJSONObject::const_iterator lookup = _maps.find(object);
|
||||
if(lookup != _maps.end()) {
|
||||
return lookup->second->getShadowObject();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setJSON(osg::Object* object, JSONObject* json) {
|
||||
if(json) {
|
||||
_maps[object] = json;
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream& getBufferFile(const std::string& name) {
|
||||
if(_buffers.find(name) == _buffers.end()) {
|
||||
_buffers[name] = new std::ofstream(name.c_str(), std::ios::binary);
|
||||
@@ -238,6 +256,10 @@ public:
|
||||
return getBinaryFilename(flag);
|
||||
}
|
||||
|
||||
void translateObject(JSONObject* json, osg::Object* osg);
|
||||
JSONObject* createJSONOsgSimUserData(osgSim::ShapeAttributeList*);
|
||||
JSONObject* createJSONUserDataContainer(osg::UserDataContainer*);
|
||||
|
||||
JSONObject* createJSONPagedLOD(osg::PagedLOD* plod);
|
||||
JSONObject* createJSONStateSet(osg::StateSet* ss);
|
||||
JSONObject* createJSONTexture(osg::Texture* sa);
|
||||
@@ -650,10 +672,14 @@ public:
|
||||
_parents.pop_back();
|
||||
}
|
||||
|
||||
std::string getBaseName() const { return _baseName; }
|
||||
bool getInlineImages() const { return _inlineImages; }
|
||||
int getMaxTextureDimension() const { return _maxTextureDimension; }
|
||||
|
||||
void setBaseName(const std::string& basename) { _baseName = basename; }
|
||||
void useExternalBinaryArray(bool use) { _useExternalBinaryArray = use; }
|
||||
void mergeAllBinaryFiles(bool use) { _mergeAllBinaryFiles = use; }
|
||||
void inlineImages(bool use) { _inlineImages = use; }
|
||||
void setInlineImages(bool use) { _inlineImages = use; }
|
||||
void setVarint(bool use) { _varint = use; }
|
||||
void setMaxTextureDimension(int use) { _maxTextureDimension = use; }
|
||||
void addSpecificBuffer(const std::string& bufferFlag) {
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#include <osg/Material>
|
||||
#include <osg/BlendFunc>
|
||||
|
||||
#include <osgSim/ShapeAttribute>
|
||||
|
||||
#include <osgText/Text>
|
||||
|
||||
#include <osgAnimation/MorphGeometry>
|
||||
@@ -76,82 +74,6 @@ osg::ref_ptr<JSONObject> buildRigBoneMap(osgAnimation::RigGeometry& rigGeometry)
|
||||
}
|
||||
|
||||
|
||||
void translateObject(JSONObject* json, osg::Object* osg)
|
||||
{
|
||||
if (!osg->getName().empty()) {
|
||||
json->getMaps()["Name"] = new JSONValue<std::string>(osg->getName());
|
||||
}
|
||||
|
||||
osgSim::ShapeAttributeList* osgSim_userdata = dynamic_cast<osgSim::ShapeAttributeList* >(osg->getUserData());
|
||||
if (osgSim_userdata) {
|
||||
JSONObject* jsonUDC = new JSONObject();
|
||||
jsonUDC->addUniqueID();
|
||||
|
||||
JSONArray* jsonUDCArray = new JSONArray();
|
||||
jsonUDC->getMaps()["Values"] = jsonUDCArray;
|
||||
for (unsigned int i = 0; i < osgSim_userdata->size(); i++) {
|
||||
const osgSim::ShapeAttribute& attr = (*osgSim_userdata)[i];
|
||||
JSONObject* jsonEntry = new JSONObject();
|
||||
jsonEntry->getMaps()["Name"] = new JSONValue<std::string>(attr.getName());
|
||||
osg::ref_ptr<JSONValue<std::string> > value;
|
||||
switch(attr.getType()) {
|
||||
case osgSim::ShapeAttribute::INTEGER:
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << attr.getInt();
|
||||
value = new JSONValue<std::string>(ss.str());
|
||||
}
|
||||
break;
|
||||
case osgSim::ShapeAttribute::DOUBLE:
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << attr.getDouble();
|
||||
value = new JSONValue<std::string>(ss.str());
|
||||
}
|
||||
break;
|
||||
case osgSim::ShapeAttribute::STRING:
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << attr.getString();
|
||||
value = new JSONValue<std::string>(ss.str());
|
||||
}
|
||||
break;
|
||||
case osgSim::ShapeAttribute::UNKNOWN:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
jsonEntry->getMaps()["Value"] = value;
|
||||
jsonUDCArray->getArray().push_back(jsonEntry);
|
||||
}
|
||||
json->getMaps()["UserDataContainer"] = jsonUDC;
|
||||
|
||||
} else if (osg->getUserDataContainer()) {
|
||||
JSONObject* jsonUDC = new JSONObject();
|
||||
jsonUDC->addUniqueID();
|
||||
|
||||
if (!osg->getUserDataContainer()->getName().empty()) {
|
||||
jsonUDC->getMaps()["Name"] = new JSONValue<std::string>(osg->getUserDataContainer()->getName());
|
||||
}
|
||||
JSONArray* jsonUDCArray = new JSONArray();
|
||||
jsonUDC->getMaps()["Values"] = jsonUDCArray;
|
||||
for (unsigned int i = 0; i < osg->getUserDataContainer()->getNumUserObjects(); i++) {
|
||||
osg::Object* o = osg->getUserDataContainer()->getUserObject(i);
|
||||
std::string name, value;
|
||||
getStringifiedUserValue(o, name, value);
|
||||
if(!name.empty() && !value.empty())
|
||||
{
|
||||
JSONObject* jsonEntry = new JSONObject();
|
||||
jsonEntry->getMaps()["Name"] = new JSONValue<std::string>(name);
|
||||
jsonEntry->getMaps()["Value"] = new JSONValue<std::string>(value);
|
||||
jsonUDCArray->getArray().push_back(jsonEntry);
|
||||
}
|
||||
|
||||
}
|
||||
json->getMaps()["UserDataContainer"] = jsonUDC;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void getStringifiedUserValue(osg::Object* o, std::string& name, std::string& value) {
|
||||
if(getStringifiedUserValue<std::string>(o, name, value)) return;
|
||||
if(getStringifiedUserValue<char>(o, name, value)) return;
|
||||
@@ -352,6 +274,108 @@ JSONObject* createImage(osg::Image* image, bool inlineImages, int maxTextureDime
|
||||
}
|
||||
|
||||
|
||||
|
||||
JSONObject* WriteVisitor::createJSONOsgSimUserData(osgSim::ShapeAttributeList* osgSimData) {
|
||||
JSONObject* jsonUDC = new JSONObject();
|
||||
jsonUDC->addUniqueID();
|
||||
|
||||
JSONArray* jsonUDCArray = new JSONArray();
|
||||
jsonUDC->getMaps()["Values"] = jsonUDCArray;
|
||||
for (unsigned int i = 0; i < osgSimData->size(); i++) {
|
||||
const osgSim::ShapeAttribute& attr = (*osgSimData)[i];
|
||||
JSONObject* jsonEntry = new JSONObject();
|
||||
jsonEntry->getMaps()["Name"] = new JSONValue<std::string>(attr.getName());
|
||||
osg::ref_ptr<JSONValue<std::string> > value;
|
||||
switch(attr.getType()) {
|
||||
case osgSim::ShapeAttribute::INTEGER:
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << attr.getInt();
|
||||
value = new JSONValue<std::string>(ss.str());
|
||||
}
|
||||
break;
|
||||
case osgSim::ShapeAttribute::DOUBLE:
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << attr.getDouble();
|
||||
value = new JSONValue<std::string>(ss.str());
|
||||
}
|
||||
break;
|
||||
case osgSim::ShapeAttribute::STRING:
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << attr.getString();
|
||||
value = new JSONValue<std::string>(ss.str());
|
||||
}
|
||||
break;
|
||||
case osgSim::ShapeAttribute::UNKNOWN:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
jsonEntry->getMaps()["Value"] = value;
|
||||
jsonUDCArray->getArray().push_back(jsonEntry);
|
||||
}
|
||||
return jsonUDC;
|
||||
}
|
||||
|
||||
|
||||
JSONObject* WriteVisitor::createJSONUserDataContainer(osg::UserDataContainer* container) {
|
||||
JSONObject* jsonUDC = new JSONObject();
|
||||
jsonUDC->addUniqueID();
|
||||
|
||||
if (!container->getName().empty()) {
|
||||
jsonUDC->getMaps()["Name"] = new JSONValue<std::string>(container->getName());
|
||||
}
|
||||
JSONArray* jsonUDCArray = new JSONArray();
|
||||
jsonUDC->getMaps()["Values"] = jsonUDCArray;
|
||||
for (unsigned int i = 0; i < container->getNumUserObjects(); i++) {
|
||||
osg::Object* o = container->getUserObject(i);
|
||||
std::string name, value;
|
||||
getStringifiedUserValue(o, name, value);
|
||||
if(!name.empty() && !value.empty())
|
||||
{
|
||||
JSONObject* jsonEntry = new JSONObject();
|
||||
jsonEntry->getMaps()["Name"] = new JSONValue<std::string>(name);
|
||||
jsonEntry->getMaps()["Value"] = new JSONValue<std::string>(value);
|
||||
jsonUDCArray->getArray().push_back(jsonEntry);
|
||||
}
|
||||
}
|
||||
return jsonUDC;
|
||||
}
|
||||
|
||||
|
||||
void WriteVisitor::translateObject(JSONObject* json, osg::Object* osg)
|
||||
{
|
||||
if (!osg->getName().empty()) {
|
||||
json->getMaps()["Name"] = new JSONValue<std::string>(osg->getName());
|
||||
}
|
||||
|
||||
JSONObject* jsonUDC = 0;
|
||||
|
||||
osgSim::ShapeAttributeList* osgSimData = dynamic_cast<osgSim::ShapeAttributeList* >(osg->getUserData());
|
||||
if (osgSimData) {
|
||||
jsonUDC = this->getJSON(osgSimData);
|
||||
if(!jsonUDC) {
|
||||
jsonUDC = createJSONOsgSimUserData(osgSimData);
|
||||
this->setJSON(osgSimData, jsonUDC);
|
||||
}
|
||||
}
|
||||
else if (osg::UserDataContainer* container = osg->getUserDataContainer()) {
|
||||
jsonUDC = this->getJSON(container);
|
||||
if(!jsonUDC) {
|
||||
jsonUDC = createJSONUserDataContainer(container);
|
||||
this->setJSON(container, jsonUDC);
|
||||
}
|
||||
}
|
||||
|
||||
if(jsonUDC) {
|
||||
json->getMaps()["UserDataContainer"] = jsonUDC;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
JSONObject* WriteVisitor::createJSONBufferArray(osg::Array* array, osg::Object* parent)
|
||||
{
|
||||
if (_maps.find(array) != _maps.end())
|
||||
@@ -765,12 +789,16 @@ JSONObject* WriteVisitor::createJSONLight(osg::Light* light)
|
||||
return jsonLight.release();
|
||||
}
|
||||
|
||||
template <class T> JSONObject* createImageFromTexture(osg::Texture* texture, JSONObject* jsonTexture, bool inlineImages,
|
||||
int maxTextureDimension, const std::string &baseName = "")
|
||||
template <class T>
|
||||
JSONObject* createImageFromTexture(osg::Texture* texture, JSONObject* jsonTexture, WriteVisitor* writer)
|
||||
{
|
||||
bool inlineImages = writer->getInlineImages();
|
||||
int maxTextureDimension = writer->getMaxTextureDimension();
|
||||
const std::string baseName = writer->getBaseName();
|
||||
|
||||
T* text = dynamic_cast<T*>( texture);
|
||||
if (text) {
|
||||
translateObject(jsonTexture,text);
|
||||
writer->translateObject(jsonTexture,text);
|
||||
JSONObject* image = createImage(text->getImage(), inlineImages, maxTextureDimension, baseName);
|
||||
if (image)
|
||||
jsonTexture->getMaps()["File"] = image;
|
||||
@@ -902,24 +930,21 @@ JSONObject* WriteVisitor::createJSONTexture(osg::Texture* texture)
|
||||
|
||||
|
||||
{
|
||||
JSONObject* obj = createImageFromTexture<osg::Texture1D>(texture, jsonTexture.get(), this->_inlineImages,
|
||||
this->_maxTextureDimension, this->_baseName);
|
||||
JSONObject* obj = createImageFromTexture<osg::Texture1D>(texture, jsonTexture.get(), this);
|
||||
if (obj) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
JSONObject* obj = createImageFromTexture<osg::Texture2D>(texture, jsonTexture.get(), this->_inlineImages,
|
||||
this->_maxTextureDimension, this->_baseName);
|
||||
JSONObject* obj = createImageFromTexture<osg::Texture2D>(texture, jsonTexture.get(), this);
|
||||
if (obj) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
JSONObject* obj = createImageFromTexture<osg::TextureRectangle>(texture, jsonTexture.get(), this->_inlineImages,
|
||||
this->_maxTextureDimension, this->_baseName);
|
||||
JSONObject* obj = createImageFromTexture<osg::TextureRectangle>(texture, jsonTexture.get(), this);
|
||||
if (obj) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -210,10 +210,10 @@ class ReaderWriterPNG : public osgDB::ReaderWriter
|
||||
pinfo->Depth = depth;
|
||||
}
|
||||
|
||||
OSG_INFO<<"width="<<width<<" height="<<height<<" depth="<<depth<<std::endl;
|
||||
if ( color == PNG_COLOR_TYPE_RGB) { OSG_INFO << "color == PNG_COLOR_TYPE_RGB "<<std::endl; }
|
||||
if ( color == PNG_COLOR_TYPE_GRAY) { OSG_INFO << "color == PNG_COLOR_TYPE_GRAY "<<std::endl; }
|
||||
if ( color == PNG_COLOR_TYPE_GRAY_ALPHA) { OSG_INFO << "color == PNG_COLOR_TYPE_GRAY_ALPHA"<<std::endl; }
|
||||
OSG_DEBUG<<"width="<<width<<" height="<<height<<" depth="<<depth<<std::endl;
|
||||
if ( color == PNG_COLOR_TYPE_RGB) { OSG_DEBUG << "color == PNG_COLOR_TYPE_RGB "<<std::endl; }
|
||||
if ( color == PNG_COLOR_TYPE_GRAY) { OSG_DEBUG << "color == PNG_COLOR_TYPE_GRAY "<<std::endl; }
|
||||
if ( color == PNG_COLOR_TYPE_GRAY_ALPHA) { OSG_DEBUG << "color == PNG_COLOR_TYPE_GRAY_ALPHA"<<std::endl; }
|
||||
|
||||
// png default to big endian, so we'll need to swap bytes if on a little endian machine.
|
||||
if (depth>8 && getCpuByteOrder()==osg::LittleEndian)
|
||||
|
||||
@@ -22,7 +22,7 @@ class ReaderWriterSDL : public osgDB::ReaderWriter
|
||||
|
||||
virtual const char* className() const { return "SDL Device Integration plugin"; }
|
||||
|
||||
virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const
|
||||
virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* =NULL) const
|
||||
{
|
||||
if (file=="joystick.sdl")
|
||||
{
|
||||
|
||||
@@ -77,22 +77,13 @@ public:
|
||||
if (transform.getStateSet()) popState();
|
||||
}
|
||||
|
||||
void apply(osg::Geode& geode)
|
||||
void apply(osg::Drawable& drawable)
|
||||
{
|
||||
if (geode.getStateSet()) pushState(geode.getStateSet());
|
||||
if (drawable.getStateSet()) pushState(drawable.getStateSet());
|
||||
|
||||
for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
|
||||
{
|
||||
osg::Drawable* drawable = geode.getDrawable(i);
|
||||
apply(&drawable);
|
||||
|
||||
if (drawable->getStateSet()) pushState(drawable->getStateSet());
|
||||
|
||||
apply(geode.getDrawable(i));
|
||||
|
||||
if (drawable->getStateSet()) popState();
|
||||
}
|
||||
|
||||
if (geode.getStateSet()) popState();
|
||||
if (drawable.getStateSet()) popState();
|
||||
}
|
||||
|
||||
void pushState(osg::StateSet* stateset)
|
||||
|
||||
@@ -274,20 +274,14 @@ public:
|
||||
popCurrentMask();
|
||||
}
|
||||
|
||||
void apply(osg::Geode& node)
|
||||
void apply(osg::Drawable& drawable)
|
||||
{
|
||||
if (isCulled(node)) return;
|
||||
if (isCulled(drawable)) return;
|
||||
|
||||
// push the culling mode.
|
||||
pushCurrentMask();
|
||||
|
||||
for(unsigned int i=0; i<node.getNumDrawables();++i)
|
||||
{
|
||||
if (node.getDrawable(i))
|
||||
{
|
||||
updateBound(node.getDrawable(i)->getBoundingBox());
|
||||
}
|
||||
}
|
||||
updateBound(drawable.getBoundingBox());
|
||||
|
||||
// pop the culling mode.
|
||||
popCurrentMask();
|
||||
|
||||
@@ -71,15 +71,3 @@ void DisplayRequirementsVisitor::apply(Node& node)
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
void DisplayRequirementsVisitor::apply(Geode& geode)
|
||||
{
|
||||
osg::StateSet* geode_stateset = geode.getStateSet();
|
||||
if (geode_stateset) applyStateSet(*geode_stateset);
|
||||
|
||||
for(unsigned int i = 0; i < geode.getNumDrawables(); i++ )
|
||||
{
|
||||
osg::StateSet* stateset = geode.getDrawable(i)->getStateSet();
|
||||
if (stateset) applyStateSet(*stateset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,18 +66,10 @@ void DrawElementTypeSimplifier::simplify(osg::Geometry & geometry) const
|
||||
}
|
||||
}
|
||||
|
||||
void DrawElementTypeSimplifierVisitor::apply(osg::Geode& node)
|
||||
void DrawElementTypeSimplifierVisitor::apply(osg::Geometry& geom)
|
||||
{
|
||||
DrawElementTypeSimplifier dets;
|
||||
|
||||
unsigned int numDrawables = node.getNumDrawables();
|
||||
for (unsigned int i = 0; i != numDrawables; ++i)
|
||||
{
|
||||
osg::Geometry * geom = dynamic_cast<osg::Geometry*>(node.getDrawable(i));
|
||||
if (geom) dets.simplify(*geom);
|
||||
}
|
||||
|
||||
osg::NodeVisitor::apply((osg::Node&)node);
|
||||
dets.simplify(geom);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,28 +53,6 @@ void GLObjectsVisitor::apply(osg::Node& node)
|
||||
}
|
||||
}
|
||||
|
||||
void GLObjectsVisitor::apply(osg::Geode& node)
|
||||
{
|
||||
bool programSetBefore = _lastCompiledProgram.valid();
|
||||
|
||||
if (node.getStateSet())
|
||||
{
|
||||
apply(*(node.getStateSet()));
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
|
||||
bool programSetAfter = _lastCompiledProgram.valid();
|
||||
if (!programSetBefore && programSetAfter)
|
||||
{
|
||||
osg::State* state = _renderInfo.getState();
|
||||
osg::GLExtensions* extensions = state->get<osg::GLExtensions>();
|
||||
extensions->glUseProgram(0);
|
||||
state->setLastAppliedProgramObject(0);
|
||||
_lastCompiledProgram = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GLObjectsVisitor::apply(osg::Drawable& drawable)
|
||||
{
|
||||
if (_drawablesAppliedSet.count(&drawable)!=0) return;
|
||||
|
||||
@@ -38,13 +38,9 @@ void GeometryCollector::reset()
|
||||
_geometryList.clear();
|
||||
}
|
||||
|
||||
void GeometryCollector::apply(Geode& geode)
|
||||
void GeometryCollector::apply(Geometry& geom)
|
||||
{
|
||||
for(unsigned int i = 0; i < geode.getNumDrawables(); ++i )
|
||||
{
|
||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
|
||||
if (geom) _geometryList.insert(geom);
|
||||
}
|
||||
_geometryList.insert(&geom);
|
||||
}
|
||||
|
||||
namespace
|
||||
@@ -890,14 +886,9 @@ void VertexCacheMissVisitor::reset()
|
||||
triangles = 0;
|
||||
}
|
||||
|
||||
void VertexCacheMissVisitor::apply(Geode& geode)
|
||||
void VertexCacheMissVisitor::apply(Geometry& geom)
|
||||
{
|
||||
for(unsigned int i = 0; i < geode.getNumDrawables(); ++i )
|
||||
{
|
||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
|
||||
if (geom)
|
||||
doGeometry(*geom);
|
||||
}
|
||||
doGeometry(geom);
|
||||
}
|
||||
|
||||
namespace
|
||||
|
||||
@@ -50,8 +50,6 @@
|
||||
|
||||
using namespace osgUtil;
|
||||
|
||||
// #define GEOMETRYDEPRECATED
|
||||
|
||||
void Optimizer::reset()
|
||||
{
|
||||
}
|
||||
@@ -290,14 +288,6 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
|
||||
OSG_INFO<<"MERGE_GEODES took "<<osg::Timer::instance()->delta_s(startTick,endTick)<<std::endl;
|
||||
}
|
||||
|
||||
if (options & CHECK_GEOMETRY)
|
||||
{
|
||||
OSG_INFO<<"Optimizer::optimize() doing CHECK_GEOMETRY"<<std::endl;
|
||||
|
||||
CheckGeometryVisitor mgv(this);
|
||||
node->accept(mgv);
|
||||
}
|
||||
|
||||
if (options & MAKE_FAST_GEOMETRY)
|
||||
{
|
||||
OSG_INFO<<"Optimizer::optimize() doing MAKE_FAST_GEOMETRY"<<std::endl;
|
||||
@@ -405,17 +395,10 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Tessellate geometry - eg break complex POLYGONS into triangles, strips, fans..
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void Optimizer::TessellateVisitor::apply(osg::Geode& geode)
|
||||
void Optimizer::TessellateVisitor::apply(osg::Geometry &geom)
|
||||
{
|
||||
for(unsigned int i=0;i<geode.getNumDrawables();++i)
|
||||
{
|
||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
|
||||
if (geom) {
|
||||
osgUtil::Tessellator Tessellator;
|
||||
Tessellator.retessellatePolygons(*geom);
|
||||
}
|
||||
}
|
||||
traverse(geode);
|
||||
osgUtil::Tessellator Tessellator;
|
||||
Tessellator.retessellatePolygons(geom);
|
||||
}
|
||||
|
||||
|
||||
@@ -468,38 +451,6 @@ void Optimizer::StateVisitor::apply(osg::Node& node)
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
void Optimizer::StateVisitor::apply(osg::Geode& geode)
|
||||
{
|
||||
if (!isOperationPermissibleForObject(&geode)) return;
|
||||
|
||||
osg::StateSet* ss = geode.getStateSet();
|
||||
|
||||
|
||||
if (ss && ss->getDataVariance()==osg::Object::STATIC)
|
||||
{
|
||||
if (isOperationPermissibleForObject(ss))
|
||||
{
|
||||
addStateSet(ss,&geode);
|
||||
}
|
||||
}
|
||||
for(unsigned int i=0;i<geode.getNumDrawables();++i)
|
||||
{
|
||||
osg::Drawable* drawable = geode.getDrawable(i);
|
||||
if (drawable)
|
||||
{
|
||||
ss = drawable->getStateSet();
|
||||
if (ss && ss->getDataVariance()==osg::Object::STATIC)
|
||||
{
|
||||
if (isOperationPermissibleForObject(drawable) &&
|
||||
isOperationPermissibleForObject(ss))
|
||||
{
|
||||
addStateSet(ss,drawable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Optimizer::StateVisitor::optimize()
|
||||
{
|
||||
OSG_INFO << "Num of StateSet="<<_statesets.size()<< std::endl;
|
||||
@@ -1173,26 +1124,19 @@ void Optimizer::FlattenStaticTransformsVisitor::apply(osg::PagedLOD& node)
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
|
||||
void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Geode& geode)
|
||||
void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Drawable& drawable)
|
||||
{
|
||||
if (!_transformStack.empty())
|
||||
osg::Geometry *geometry = drawable.asGeometry();
|
||||
if((geometry) && (isOperationPermissibleForObject(&drawable)))
|
||||
{
|
||||
for(unsigned int i=0;i<geode.getNumDrawables();++i)
|
||||
{
|
||||
osg::Geometry *geometry = geode.getDrawable(i)->asGeometry();
|
||||
if((geometry) && (isOperationPermissibleForObject(&geode)) && (isOperationPermissibleForObject(geometry)))
|
||||
{
|
||||
if(geometry->getVertexArray() && geometry->getVertexArray()->referenceCount() > 1) {
|
||||
geometry->setVertexArray(dynamic_cast<osg::Array*>(geometry->getVertexArray()->clone(osg::CopyOp::DEEP_COPY_ALL)));
|
||||
}
|
||||
if(geometry->getNormalArray() && geometry->getNormalArray()->referenceCount() > 1) {
|
||||
geometry->setNormalArray(dynamic_cast<osg::Array*>(geometry->getNormalArray()->clone(osg::CopyOp::DEEP_COPY_ALL)));
|
||||
}
|
||||
}
|
||||
_drawableSet.insert(geode.getDrawable(i));
|
||||
if(geometry->getVertexArray() && geometry->getVertexArray()->referenceCount() > 1) {
|
||||
geometry->setVertexArray(dynamic_cast<osg::Array*>(geometry->getVertexArray()->clone(osg::CopyOp::DEEP_COPY_ALL)));
|
||||
}
|
||||
if(geometry->getNormalArray() && geometry->getNormalArray()->referenceCount() > 1) {
|
||||
geometry->setNormalArray(dynamic_cast<osg::Array*>(geometry->getNormalArray()->clone(osg::CopyOp::DEEP_COPY_ALL)));
|
||||
}
|
||||
}
|
||||
_drawableSet.insert(&drawable);
|
||||
}
|
||||
|
||||
void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Billboard& billboard)
|
||||
@@ -1329,23 +1273,6 @@ bool Optimizer::CombineStaticTransformsVisitor::removeTransforms(osg::Node* node
|
||||
// RemoveEmptyNodes.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Geode& geode)
|
||||
{
|
||||
for(int i=geode.getNumDrawables()-1;i>=0;--i)
|
||||
{
|
||||
osg::Geometry* geom = geode.getDrawable(i)->asGeometry();
|
||||
if (geom && geom->empty() && isOperationPermissibleForObject(geom))
|
||||
{
|
||||
geode.removeDrawables(i,1);
|
||||
}
|
||||
}
|
||||
|
||||
if (geode.getNumParents()>0)
|
||||
{
|
||||
if (geode.getNumDrawables()==0 && isOperationPermissibleForObject(&geode)) _redundantNodeList.insert(&geode);
|
||||
}
|
||||
}
|
||||
|
||||
void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Group& group)
|
||||
{
|
||||
if (group.getNumParents()>0)
|
||||
@@ -1389,7 +1316,7 @@ void Optimizer::RemoveEmptyNodesVisitor::removeEmptyNodes()
|
||||
strcmp(parent->className(),"MultiSwitch")!=0)
|
||||
{
|
||||
parent->removeChild(nodeToRemove.get());
|
||||
if (parent->getNumChildren()==0) newEmptyGroups.insert(*pitr);
|
||||
if (parent->getNumChildren()==0 && isOperationPermissibleForObject(parent)) newEmptyGroups.insert(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1795,39 +1722,13 @@ struct LessGeometryPrimitiveType
|
||||
}
|
||||
};
|
||||
|
||||
void Optimizer::CheckGeometryVisitor::checkGeode(osg::Geode& geode)
|
||||
void Optimizer::MakeFastGeometryVisitor::apply(osg::Geometry& geom)
|
||||
{
|
||||
if (isOperationPermissibleForObject(&geode))
|
||||
if (isOperationPermissibleForObject(&geom))
|
||||
{
|
||||
for(unsigned int i=0;i<geode.getNumDrawables();++i)
|
||||
if (geom.checkForDeprecatedData())
|
||||
{
|
||||
osg::Geometry* geom = geode.getDrawable(i)->asGeometry();
|
||||
if (geom && isOperationPermissibleForObject(geom))
|
||||
{
|
||||
#ifdef GEOMETRYDEPRECATED
|
||||
geom1829
|
||||
->computeCorrectBindingsAndArraySizes();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Optimizer::MakeFastGeometryVisitor::checkGeode(osg::Geode& geode)
|
||||
{
|
||||
// GeometryDeprecated CAN REMOVED
|
||||
if (isOperationPermissibleForObject(&geode))
|
||||
{
|
||||
for(unsigned int i=0;i<geode.getNumDrawables();++i)
|
||||
{
|
||||
osg::Geometry* geom = geode.getDrawable(i)->asGeometry();
|
||||
if (geom && isOperationPermissibleForObject(geom))
|
||||
{
|
||||
if (geom->checkForDeprecatedData())
|
||||
{
|
||||
geom->fixDeprecatedData();
|
||||
}
|
||||
}
|
||||
geom.fixDeprecatedData();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2985,33 +2886,6 @@ void Optimizer::TextureVisitor::apply(osg::Node& node)
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
void Optimizer::TextureVisitor::apply(osg::Geode& geode)
|
||||
{
|
||||
if (!isOperationPermissibleForObject(&geode)) return;
|
||||
|
||||
osg::StateSet* ss = geode.getStateSet();
|
||||
|
||||
if (ss && isOperationPermissibleForObject(ss))
|
||||
{
|
||||
apply(*ss);
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i<geode.getNumDrawables();++i)
|
||||
{
|
||||
osg::Drawable* drawable = geode.getDrawable(i);
|
||||
if (drawable)
|
||||
{
|
||||
ss = drawable->getStateSet();
|
||||
if (ss &&
|
||||
isOperationPermissibleForObject(drawable) &&
|
||||
isOperationPermissibleForObject(ss))
|
||||
{
|
||||
apply(*ss);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Optimizer::TextureVisitor::apply(osg::StateSet& stateset)
|
||||
{
|
||||
for(unsigned int i=0;i<stateset.getTextureAttributeList().size();++i)
|
||||
@@ -4137,56 +4011,31 @@ void Optimizer::TextureAtlasVisitor::apply(osg::Node& node)
|
||||
if (pushedStateState) popStateSet();
|
||||
}
|
||||
|
||||
void Optimizer::TextureAtlasVisitor::apply(osg::Geode& geode)
|
||||
void Optimizer::TextureAtlasVisitor::apply(osg::Drawable& node)
|
||||
{
|
||||
if (!isOperationPermissibleForObject(&geode)) return;
|
||||
|
||||
osg::StateSet* ss = geode.getStateSet();
|
||||
|
||||
|
||||
bool pushedGeodeStateState = false;
|
||||
bool pushedStateState = false;
|
||||
|
||||
osg::StateSet* ss = node.getStateSet();
|
||||
if (ss && ss->getDataVariance()==osg::Object::STATIC)
|
||||
{
|
||||
if (isOperationPermissibleForObject(ss))
|
||||
if (isOperationPermissibleForObject(&node) &&
|
||||
isOperationPermissibleForObject(ss))
|
||||
{
|
||||
pushedGeodeStateState = pushStateSet(ss);
|
||||
pushedStateState = pushStateSet(ss);
|
||||
}
|
||||
}
|
||||
for(unsigned int i=0;i<geode.getNumDrawables();++i)
|
||||
|
||||
if (!_statesetStack.empty())
|
||||
{
|
||||
|
||||
osg::Drawable* drawable = geode.getDrawable(i);
|
||||
if (drawable)
|
||||
for(StateSetStack::iterator ssitr = _statesetStack.begin();
|
||||
ssitr != _statesetStack.end();
|
||||
++ssitr)
|
||||
{
|
||||
bool pushedDrawableStateState = false;
|
||||
|
||||
ss = drawable->getStateSet();
|
||||
if (ss && ss->getDataVariance()==osg::Object::STATIC)
|
||||
{
|
||||
if (isOperationPermissibleForObject(drawable) &&
|
||||
isOperationPermissibleForObject(ss))
|
||||
{
|
||||
pushedDrawableStateState = pushStateSet(ss);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_statesetStack.empty())
|
||||
{
|
||||
for(StateSetStack::iterator ssitr = _statesetStack.begin();
|
||||
ssitr != _statesetStack.end();
|
||||
++ssitr)
|
||||
{
|
||||
_statesetMap[*ssitr].insert(drawable);
|
||||
}
|
||||
}
|
||||
|
||||
if (pushedDrawableStateState) popStateSet();
|
||||
_statesetMap[*ssitr].insert(&node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (pushedGeodeStateState) popStateSet();
|
||||
if (pushedStateState) popStateSet();
|
||||
}
|
||||
|
||||
void Optimizer::TextureAtlasVisitor::optimize()
|
||||
@@ -4474,14 +4323,11 @@ void Optimizer::StaticObjectDetectionVisitor::apply(osg::Node& node)
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
void Optimizer::StaticObjectDetectionVisitor::apply(osg::Geode& geode)
|
||||
void Optimizer::StaticObjectDetectionVisitor::apply(osg::Drawable& drawable)
|
||||
{
|
||||
if (geode.getStateSet()) applyStateSet(*geode.getStateSet());
|
||||
if (drawable.getStateSet()) applyStateSet(*drawable.getStateSet());
|
||||
|
||||
for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
|
||||
{
|
||||
applyDrawable(*geode.getDrawable(i));
|
||||
}
|
||||
drawable.computeDataVariance();
|
||||
}
|
||||
|
||||
void Optimizer::StaticObjectDetectionVisitor::applyStateSet(osg::StateSet& stateset)
|
||||
@@ -4490,15 +4336,6 @@ void Optimizer::StaticObjectDetectionVisitor::applyStateSet(osg::StateSet& state
|
||||
}
|
||||
|
||||
|
||||
void Optimizer::StaticObjectDetectionVisitor::applyDrawable(osg::Drawable& drawable)
|
||||
{
|
||||
|
||||
if (drawable.getStateSet()) applyStateSet(*drawable.getStateSet());
|
||||
|
||||
drawable.computeDataVariance();
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor
|
||||
|
||||
@@ -322,24 +322,13 @@ void ShaderGenVisitor::apply(osg::Node &node)
|
||||
_state->popStateSet();
|
||||
}
|
||||
|
||||
void ShaderGenVisitor::apply(osg::Geode &geode)
|
||||
void ShaderGenVisitor::apply(osg::Drawable &drawable)
|
||||
{
|
||||
osg::StateSet *stateSet = geode.getStateSet();
|
||||
osg::StateSet *stateSet = drawable.getStateSet();
|
||||
if (stateSet)
|
||||
_state->pushStateSet(stateSet);
|
||||
|
||||
for (unsigned int i=0; i<geode.getNumDrawables(); ++i)
|
||||
{
|
||||
osg::Drawable *drawable = geode.getDrawable(i);
|
||||
osg::StateSet *ss = drawable->getStateSet();
|
||||
if (ss)
|
||||
_state->pushStateSet(ss);
|
||||
|
||||
update(drawable);
|
||||
|
||||
if (ss)
|
||||
_state->popStateSet();
|
||||
}
|
||||
update(&drawable);
|
||||
|
||||
if (stateSet)
|
||||
_state->popStateSet();
|
||||
|
||||
@@ -702,11 +702,7 @@ void SmoothingVisitor::smooth(osg::Geometry& geom, double creaseAngle)
|
||||
}
|
||||
|
||||
|
||||
void SmoothingVisitor::apply(osg::Geode& geode)
|
||||
void SmoothingVisitor::apply(osg::Geometry& geom)
|
||||
{
|
||||
for(unsigned int i = 0; i < geode.getNumDrawables(); i++ )
|
||||
{
|
||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
|
||||
if (geom) smooth(*geom, _creaseAngle);
|
||||
}
|
||||
smooth(geom, _creaseAngle);
|
||||
}
|
||||
|
||||
@@ -629,11 +629,7 @@ void TriStripVisitor::stripify()
|
||||
}
|
||||
}
|
||||
|
||||
void TriStripVisitor::apply(Geode& geode)
|
||||
void TriStripVisitor::apply(Geometry& geom)
|
||||
{
|
||||
for(unsigned int i = 0; i < geode.getNumDrawables(); ++i )
|
||||
{
|
||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
|
||||
if (geom) _geometryList.insert(geom);
|
||||
}
|
||||
_geometryList.insert(&geom);
|
||||
}
|
||||
|
||||
@@ -928,33 +928,6 @@ void MultipassTechnique::backfaceSubgraphCullTraversal(osgUtil::CullVisitor* cv)
|
||||
cv->popStateSet();
|
||||
}
|
||||
|
||||
class RTTBackfaceCameraCullCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
|
||||
RTTBackfaceCameraCullCallback(MultipassTechnique::MultipassTileData* tileData, MultipassTechnique* mt):
|
||||
_tileData(tileData),
|
||||
_mt(mt) {}
|
||||
|
||||
virtual void operator()(osg::Node* /*node*/, osg::NodeVisitor* nv)
|
||||
{
|
||||
osgUtil::CullVisitor* cv = nv->asCullVisitor();
|
||||
|
||||
cv->pushProjectionMatrix(_tileData->projectionMatrix.get());
|
||||
|
||||
_mt->backfaceSubgraphCullTraversal(cv);
|
||||
|
||||
cv->popProjectionMatrix();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~RTTBackfaceCameraCullCallback() {}
|
||||
|
||||
osg::observer_ptr<osgVolume::MultipassTechnique::MultipassTileData> _tileData;
|
||||
osg::observer_ptr<osgVolume::MultipassTechnique> _mt;
|
||||
};
|
||||
|
||||
class ShadingModelVisitor : public osgVolume::PropertyVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user