Compare commits

...
Author SHA1 Message Date
James Turner 7fbdd9ad2f MSVC lacks stdint.h / inttypes.h
- we can't use simgear/misc/stdint.hxx here, since it's a C++
header and md5.c is compiled as plain C (no bool type available).
2014-02-10 18:03:38 +00:00
James Turner 24539968fd Replace md5 from RSA with OpenBSD version
- no more BSD-with-advertising-license
- files from http://sources.debian.net/src/dpkg/1.17.6/lib/compat
(with SG_ prefixes to avoid collision issues)
2014-02-10 18:03:13 +00:00
James Turner f13b356531 Race-condition fix in get_effect.
Adapted from a fix by Jeff Biggs. (Shows up easier when using osgEarth,
and multiple osgDB pager threads)
2014-02-10 18:02:58 +00:00
Thomas Geymayer 477594d7bc Canvas: Fix bounding box calculation for paths with subpaths. 2014-02-08 00:25:03 +01:00
Thomas Geymayer e955a18126 Canvas::Element: expose combined transformation matrix 2014-02-08 00:24:55 +01:00
James Turner adec1c4507 Add desktop() accessor to SGPath
(Windows-only for the moment)
2014-02-01 09:23:21 +00:00
James Turner 172b8a032c Crash-fix: make mat-lib reference counted.
Make SGReaderWriterOptions own the material lib it's passing to
loader code, so it cannot be freed unexpectedly.
2014-01-23 09:18:39 +00:00
14 changed files with 433 additions and 403 deletions
+73 -65
View File
@@ -167,66 +167,8 @@ namespace canvas
// Don't do anything if element is hidden // Don't do anything if element is hidden
return; return;
if( _transform_dirty ) // Trigger matrix update
{ getMatrix();
osg::Matrix m;
for( size_t i = 0; i < _transform_types.size(); ++i )
{
// Skip unused indizes...
if( _transform_types[i] == TT_NONE )
continue;
SGPropertyNode* tf_node = _node->getChild("tf", i, true);
// Build up the matrix representation of the current transform node
osg::Matrix tf;
switch( _transform_types[i] )
{
case TT_MATRIX:
tf = osg::Matrix( tf_node->getDoubleValue("m[0]", 1),
tf_node->getDoubleValue("m[1]", 0),
0,
tf_node->getDoubleValue("m[6]", 0),
tf_node->getDoubleValue("m[2]", 0),
tf_node->getDoubleValue("m[3]", 1),
0,
tf_node->getDoubleValue("m[7]", 0),
0,
0,
1,
0,
tf_node->getDoubleValue("m[4]", 0),
tf_node->getDoubleValue("m[5]", 0),
0,
tf_node->getDoubleValue("m[8]", 1) );
break;
case TT_TRANSLATE:
tf.makeTranslate( osg::Vec3f( tf_node->getDoubleValue("t[0]", 0),
tf_node->getDoubleValue("t[1]", 0),
0 ) );
break;
case TT_ROTATE:
tf.makeRotate( tf_node->getDoubleValue("rot", 0), 0, 0, 1 );
break;
case TT_SCALE:
{
float sx = tf_node->getDoubleValue("s[0]", 1);
// sy defaults to sx...
tf.makeScale( sx, tf_node->getDoubleValue("s[1]", sx), 1 );
break;
}
default:
break;
}
m.postMult( tf );
}
_transform->setMatrix(m);
_transform_dirty = false;
_attributes_dirty |= SCISSOR_COORDS;
}
if( _attributes_dirty & SCISSOR_COORDS ) if( _attributes_dirty & SCISSOR_COORDS )
{ {
@@ -364,7 +306,7 @@ namespace canvas
_transform_types.resize( child->getIndex() + 1 ); _transform_types.resize( child->getIndex() + 1 );
_transform_types[ child->getIndex() ] = TT_NONE; _transform_types[ child->getIndex() ] = TT_NONE;
_transform_dirty = true; _attributes_dirty |= TRANSFORM;
return; return;
} }
else if( parent->getParent() == _node else if( parent->getParent() == _node
@@ -385,7 +327,7 @@ namespace canvas
else if( name == "s" ) else if( name == "s" )
type = TT_SCALE; type = TT_SCALE;
_transform_dirty = true; _attributes_dirty |= TRANSFORM;
return; return;
} }
@@ -418,7 +360,7 @@ namespace canvas
while( !_transform_types.empty() && _transform_types.back() == TT_NONE ) while( !_transform_types.empty() && _transform_types.back() == TT_NONE )
_transform_types.pop_back(); _transform_types.pop_back();
_transform_dirty = true; _attributes_dirty |= TRANSFORM;
return; return;
} }
else if( StyleInfo const* style = getStyleInfo(child->getNameString()) ) else if( StyleInfo const* style = getStyleInfo(child->getNameString()) )
@@ -460,7 +402,7 @@ namespace canvas
else if( parent->getParent() == _node else if( parent->getParent() == _node
&& parent->getNameString() == NAME_TRANSFORM ) && parent->getNameString() == NAME_TRANSFORM )
{ {
_transform_dirty = true; _attributes_dirty |= TRANSFORM;
return; return;
} }
@@ -583,6 +525,73 @@ namespace canvas
return transformed; return transformed;
} }
//----------------------------------------------------------------------------
osg::Matrix Element::getMatrix() const
{
if( !(_attributes_dirty & TRANSFORM) )
return _transform->getMatrix();
osg::Matrix m;
for( size_t i = 0; i < _transform_types.size(); ++i )
{
// Skip unused indizes...
if( _transform_types[i] == TT_NONE )
continue;
SGPropertyNode* tf_node = _node->getChild("tf", i, true);
// Build up the matrix representation of the current transform node
osg::Matrix tf;
switch( _transform_types[i] )
{
case TT_MATRIX:
tf = osg::Matrix( tf_node->getDoubleValue("m[0]", 1),
tf_node->getDoubleValue("m[1]", 0),
0,
tf_node->getDoubleValue("m[6]", 0),
tf_node->getDoubleValue("m[2]", 0),
tf_node->getDoubleValue("m[3]", 1),
0,
tf_node->getDoubleValue("m[7]", 0),
0,
0,
1,
0,
tf_node->getDoubleValue("m[4]", 0),
tf_node->getDoubleValue("m[5]", 0),
0,
tf_node->getDoubleValue("m[8]", 1) );
break;
case TT_TRANSLATE:
tf.makeTranslate( osg::Vec3f( tf_node->getDoubleValue("t[0]", 0),
tf_node->getDoubleValue("t[1]", 0),
0 ) );
break;
case TT_ROTATE:
tf.makeRotate( tf_node->getDoubleValue("rot", 0), 0, 0, 1 );
break;
case TT_SCALE:
{
float sx = tf_node->getDoubleValue("s[0]", 1);
// sy defaults to sx...
tf.makeScale( sx, tf_node->getDoubleValue("s[1]", sx), 1 );
break;
}
default:
break;
}
m.postMult( tf );
}
_transform->setMatrix(m);
_attributes_dirty &= ~TRANSFORM;
_attributes_dirty |= SCISSOR_COORDS;
return m;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Element::StyleSetters Element::_style_setters; Element::StyleSetters Element::_style_setters;
@@ -595,7 +604,6 @@ namespace canvas
_canvas( canvas ), _canvas( canvas ),
_parent( parent ), _parent( parent ),
_attributes_dirty( 0 ), _attributes_dirty( 0 ),
_transform_dirty( false ),
_transform( new osg::MatrixTransform ), _transform( new osg::MatrixTransform ),
_style( parent_style ), _style( parent_style ),
_scissor( 0 ), _scissor( 0 ),
+8 -3
View File
@@ -157,6 +157,11 @@ namespace canvas
*/ */
virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) const; virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) const;
/**
* Get the transformation matrix (product of all transforms)
*/
osg::Matrix getMatrix() const;
/** /**
* Create an canvas Element * Create an canvas Element
* *
@@ -181,7 +186,8 @@ namespace canvas
enum Attributes enum Attributes
{ {
BLEND_FUNC = 1, TRANSFORM = 1,
BLEND_FUNC = TRANSFORM << 1,
SCISSOR_COORDS = BLEND_FUNC << 1, SCISSOR_COORDS = BLEND_FUNC << 1,
LAST_ATTRIBUTE = SCISSOR_COORDS << 1 LAST_ATTRIBUTE = SCISSOR_COORDS << 1
}; };
@@ -200,9 +206,8 @@ namespace canvas
CanvasWeakPtr _canvas; CanvasWeakPtr _canvas;
Element *_parent; Element *_parent;
uint32_t _attributes_dirty; mutable uint32_t _attributes_dirty;
bool _transform_dirty;
osg::observer_ptr<osg::MatrixTransform> _transform; osg::observer_ptr<osg::MatrixTransform> _transform;
std::vector<TransformType> _transform_types; std::vector<TransformType> _transform_types;
+8 -1
View File
@@ -277,7 +277,8 @@ namespace canvas
{ {
osg::BoundingBox bb; osg::BoundingBox bb;
osg::Vec2f cur; // VG "Current point" (in local coordinates) osg::Vec2f cur(0, 0), // VG "Current point" (in local coordinates)
sub(0, 0); // beginning of current sub path
VGubyte cmd_index = 0; VGubyte cmd_index = 0;
for( size_t i = 0, ci = 0; for( size_t i = 0, ci = 0;
i < _cmds.size() && ci < _coords.size(); i < _cmds.size() && ci < _coords.size();
@@ -297,6 +298,7 @@ namespace canvas
switch( cmd ) switch( cmd )
{ {
case VG_CLOSE_PATH: case VG_CLOSE_PATH:
cur = sub;
break; break;
case VG_MOVE_TO: case VG_MOVE_TO:
case VG_LINE_TO: case VG_LINE_TO:
@@ -352,7 +354,12 @@ namespace canvas
} }
if( num_coords > 0 ) if( num_coords > 0 )
{
cur = points[ num_coords - 1 ]; cur = points[ num_coords - 1 ];
if( cmd == VG_MOVE_TO )
sub = cur;
}
} }
return bb; return bb;
+3 -2
View File
@@ -377,8 +377,9 @@ public:
memset(&md5Context, 0, sizeof(SG_MD5_CTX)); memset(&md5Context, 0, sizeof(SG_MD5_CTX));
SG_MD5Init(&md5Context); SG_MD5Init(&md5Context);
SG_MD5Update(&md5Context, (unsigned char*) output.data(), output.size()); SG_MD5Update(&md5Context, (unsigned char*) output.data(), output.size());
SG_MD5Final(&md5Context); unsigned char digest[MD5_DIGEST_LENGTH];
decodedFileMd5 = strutils::encodeHex(md5Context.digest, 16); SG_MD5Final(digest, &md5Context);
decodedFileMd5 = strutils::encodeHex(digest, MD5_DIGEST_LENGTH);
return true; return true;
} }
+42 -19
View File
@@ -55,6 +55,34 @@ static const char sgSearchPathSep = ';';
static const char sgSearchPathSep = ':'; static const char sgSearchPathSep = ':';
#endif #endif
#ifdef _WIN32
#include <ShlObj.h> // for CSIDL
static SGPath pathForCSIDL(int csidl, const SGPath::PermissonChecker& checker)
{
typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPSTR, int, BOOL);
static GetSpecialFolderPath SHGetSpecialFolderPath = NULL;
// lazy open+resolve of shell32
if (!SHGetSpecialFolderPath) {
HINSTANCE shellDll = ::LoadLibrary("shell32");
SHGetSpecialFolderPath = (GetSpecialFolderPath) GetProcAddress(shellDll, "SHGetSpecialFolderPathA");
}
if (!SHGetSpecialFolderPath){
return SGPath();
}
char path[MAX_PATH];
if (SHGetSpecialFolderPath(0, path, csidl, false)) {
return SGPath(path, checker);
}
return SGPath();
}
#endif
// For windows, replace "\" by "/". // For windows, replace "\" by "/".
void void
@@ -644,33 +672,28 @@ SGPath SGPath::home(const SGPath& def)
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
#include <ShlObj.h> // for CSIDL
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
SGPath SGPath::desktop(const SGPath& def) SGPath SGPath::desktop(const SGPath& def)
{ {
typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPSTR, int, BOOL); SGPath r = pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def._permission_checker);
static GetSpecialFolderPath SHGetSpecialFolderPath = NULL; if (!r.isNull()) {
return r;
// lazy open+resolve of shell32
if (!SHGetSpecialFolderPath) {
HINSTANCE shellDll = ::LoadLibrary("shell32");
SHGetSpecialFolderPath = (GetSpecialFolderPath) GetProcAddress(shellDll, "SHGetSpecialFolderPathA");
}
if (!SHGetSpecialFolderPath){
return def;
}
char path[MAX_PATH];
if (SHGetSpecialFolderPath(0, path, CSIDL_DESKTOPDIRECTORY, false)) {
return SGPath(path, def._permission_checker);
} }
SG_LOG(SG_GENERAL, SG_ALERT, "SGPath::desktop() failed, bad" ); SG_LOG(SG_GENERAL, SG_ALERT, "SGPath::desktop() failed, bad" );
return def; return def;
} }
SGPath SGPath::documents(const SGPath& def)
{
SGPath r = pathForCSIDL(CSIDL_MYDOCUMENTS, def._permission_checker);
if (!r.isNull()) {
return r;
}
SG_LOG(SG_GENERAL, SG_ALERT, "SGPath::documents() failed, bad" );
return def;
}
#elif __APPLE__ #elif __APPLE__
#include <CoreServices/CoreServices.h> #include <CoreServices/CoreServices.h>
+4
View File
@@ -276,6 +276,10 @@ public:
*/ */
static SGPath desktop(const SGPath& def = SGPath()); static SGPath desktop(const SGPath& def = SGPath());
/**
* Get path to the user's documents directory
*/
static SGPath documents(const SGPath& def = SGPath());
private: private:
void fix(); void fix();
+5 -4
View File
@@ -89,13 +89,14 @@ protected:
return; return;
} }
SG_MD5Final(&m_md5); unsigned char digest[MD5_DIGEST_LENGTH];
SG_MD5Final(digest, &m_md5);
// convert final sum to hex // convert final sum to hex
const char hexChar[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; const char hexChar[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
std::stringstream hexMd5; std::stringstream hexMd5;
for (int i=0; i<16;++i) { for (int i=0; i<MD5_DIGEST_LENGTH;++i) {
hexMd5 << hexChar[m_md5.digest[i] >> 4]; hexMd5 << hexChar[digest[i] >> 4];
hexMd5 << hexChar[m_md5.digest[i] & 0x0f]; hexMd5 << hexChar[digest[i] & 0x0f];
} }
if (hexMd5.str() != m_owner->package()->md5()) { if (hexMd5.str() != m_owner->package()->md5()) {
+228 -244
View File
@@ -1,266 +1,250 @@
/* /* $OpenBSD: md5.c,v 1.7 2004/05/28 15:10:27 millert Exp $ */
**********************************************************************
** md5.c **
** RSA Data Security, Inc. MD5 Message Digest Algorithm **
** Created: 2/17/90 RLR **
** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version **
**********************************************************************
*/
/* /*
********************************************************************** * This code implements the MD5 message-digest algorithm.
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** * The algorithm is due to Ron Rivest. This code was
** ** * written by Colin Plumb in 1993, no copyright is claimed.
** License to copy and use this software is granted provided that ** * This code is in the public domain; do with it what you wish.
** it is identified as the "RSA Data Security, Inc. MD5 Message ** *
** Digest Algorithm" in all material mentioning or referencing this ** * Equivalent code is available from RSA Data Security, Inc.
** software or this function. ** * This code has been tested against that, and is equivalent,
** ** * except that you don't need to include two pages of legalese
** License is also granted to make and use derivative works ** * with every copy.
** provided that such works are identified as "derived from the RSA ** *
** Data Security, Inc. MD5 Message Digest Algorithm" in all ** * To compute the message digest of a chunk of bytes, declare an
** material mentioning or referencing the derived work. ** * MD5Context structure, pass it to MD5Init, call MD5Update as
** ** * needed on buffers full of bytes, and then call MD5Final, which
** RSA Data Security, Inc. makes no representations concerning ** * will fill a supplied 16-byte array with the digest.
** either the merchantability of this software or the suitability **
** of this software for any particular purpose. It is provided "as **
** is" without express or implied warranty of any kind. **
** **
** These notices must be retained in any copies of any part of this **
** documentation and/or software. **
**********************************************************************
*/ */
/* -- include the following line if the md5.h header file is separate -- */
#include <sys/types.h>
#include <string.h>
#include "md5.h" #include "md5.h"
/* forward declaration */ #define PUT_64BIT_LE(cp, value) do { \
static void Transform (); (cp)[7] = (value) >> 56; \
(cp)[6] = (value) >> 48; \
(cp)[5] = (value) >> 40; \
(cp)[4] = (value) >> 32; \
(cp)[3] = (value) >> 24; \
(cp)[2] = (value) >> 16; \
(cp)[1] = (value) >> 8; \
(cp)[0] = (value); } while (0)
static unsigned char PADDING[64] = { #define PUT_32BIT_LE(cp, value) do { \
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (cp)[3] = (value) >> 24; \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (cp)[2] = (value) >> 16; \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (cp)[1] = (value) >> 8; \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (cp)[0] = (value); } while (0)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, static u_int8_t PADDING[MD5_BLOCK_LENGTH] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}; };
/* F, G and H are basic MD5 functions: selection, majority, parity */ /*
#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) * initialization constants.
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
/* Rotation is separate from addition to prevent recomputation */
#define FF(a, b, c, d, x, s, ac) \
{(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) \
{(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) \
{(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) \
{(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
void SG_MD5Init (SG_MD5_CTX *mdContext)
{
mdContext->i[0] = mdContext->i[1] = (UINT4)0;
/* Load magic initialization constants.
*/ */
mdContext->buf[0] = (UINT4)0x67452301; void
mdContext->buf[1] = (UINT4)0xefcdab89; SG_MD5Init(SG_MD5_CTX *ctx)
mdContext->buf[2] = (UINT4)0x98badcfe;
mdContext->buf[3] = (UINT4)0x10325476;
}
void SG_MD5Update (SG_MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
{ {
UINT4 in[16]; ctx->count = 0;
int mdi; ctx->state[0] = 0x67452301;
unsigned int i, ii; ctx->state[1] = 0xefcdab89;
ctx->state[2] = 0x98badcfe;
/* compute number of bytes mod 64 */ ctx->state[3] = 0x10325476;
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
/* update number of bits */
if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
mdContext->i[1]++;
mdContext->i[0] += ((UINT4)inLen << 3);
mdContext->i[1] += ((UINT4)inLen >> 29);
while (inLen--) {
/* add new character to buffer, increment mdi */
mdContext->in[mdi++] = *inBuf++;
/* transform if necessary */
if (mdi == 0x40) {
for (i = 0, ii = 0; i < 16; i++, ii += 4)
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
(((UINT4)mdContext->in[ii+2]) << 16) |
(((UINT4)mdContext->in[ii+1]) << 8) |
((UINT4)mdContext->in[ii]);
Transform (mdContext->buf, in);
mdi = 0;
}
}
} }
void SG_MD5Final (SG_MD5_CTX *mdContext) /*
{ * Update context to reflect the concatenation of another buffer full
UINT4 in[16]; * of bytes.
int mdi;
unsigned int i, ii;
unsigned int padLen;
/* save number of bits */
in[14] = mdContext->i[0];
in[15] = mdContext->i[1];
/* compute number of bytes mod 64 */
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
/* pad out to 56 mod 64 */
padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
SG_MD5Update (mdContext, PADDING, padLen);
/* append length in bits and transform */
for (i = 0, ii = 0; i < 14; i++, ii += 4)
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
(((UINT4)mdContext->in[ii+2]) << 16) |
(((UINT4)mdContext->in[ii+1]) << 8) |
((UINT4)mdContext->in[ii]);
Transform (mdContext->buf, in);
/* store buffer in digest */
for (i = 0, ii = 0; i < 4; i++, ii += 4) {
mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
mdContext->digest[ii+1] =
(unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
mdContext->digest[ii+2] =
(unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
mdContext->digest[ii+3] =
(unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
}
}
/* Basic MD5 step. Transform buf based on in.
*/ */
static void Transform (buf, in) void
UINT4 *buf; SG_MD5Update(SG_MD5_CTX *ctx, const unsigned char *input, size_t len)
UINT4 *in;
{ {
UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; size_t have, need;
/* Round 1 */ /* Check how many bytes we already have and how many more we need. */
#define S11 7 have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
#define S12 12 need = MD5_BLOCK_LENGTH - have;
#define S13 17
#define S14 22
FF ( a, b, c, d, in[ 0], S11, 3614090360); /* 1 */
FF ( d, a, b, c, in[ 1], S12, 3905402710); /* 2 */
FF ( c, d, a, b, in[ 2], S13, 606105819); /* 3 */
FF ( b, c, d, a, in[ 3], S14, 3250441966); /* 4 */
FF ( a, b, c, d, in[ 4], S11, 4118548399); /* 5 */
FF ( d, a, b, c, in[ 5], S12, 1200080426); /* 6 */
FF ( c, d, a, b, in[ 6], S13, 2821735955); /* 7 */
FF ( b, c, d, a, in[ 7], S14, 4249261313); /* 8 */
FF ( a, b, c, d, in[ 8], S11, 1770035416); /* 9 */
FF ( d, a, b, c, in[ 9], S12, 2336552879); /* 10 */
FF ( c, d, a, b, in[10], S13, 4294925233); /* 11 */
FF ( b, c, d, a, in[11], S14, 2304563134); /* 12 */
FF ( a, b, c, d, in[12], S11, 1804603682); /* 13 */
FF ( d, a, b, c, in[13], S12, 4254626195); /* 14 */
FF ( c, d, a, b, in[14], S13, 2792965006); /* 15 */
FF ( b, c, d, a, in[15], S14, 1236535329); /* 16 */
/* Round 2 */ /* Update bitcount */
#define S21 5 ctx->count += (u_int64_t)len << 3;
#define S22 9
#define S23 14
#define S24 20
GG ( a, b, c, d, in[ 1], S21, 4129170786); /* 17 */
GG ( d, a, b, c, in[ 6], S22, 3225465664); /* 18 */
GG ( c, d, a, b, in[11], S23, 643717713); /* 19 */
GG ( b, c, d, a, in[ 0], S24, 3921069994); /* 20 */
GG ( a, b, c, d, in[ 5], S21, 3593408605); /* 21 */
GG ( d, a, b, c, in[10], S22, 38016083); /* 22 */
GG ( c, d, a, b, in[15], S23, 3634488961); /* 23 */
GG ( b, c, d, a, in[ 4], S24, 3889429448); /* 24 */
GG ( a, b, c, d, in[ 9], S21, 568446438); /* 25 */
GG ( d, a, b, c, in[14], S22, 3275163606); /* 26 */
GG ( c, d, a, b, in[ 3], S23, 4107603335); /* 27 */
GG ( b, c, d, a, in[ 8], S24, 1163531501); /* 28 */
GG ( a, b, c, d, in[13], S21, 2850285829); /* 29 */
GG ( d, a, b, c, in[ 2], S22, 4243563512); /* 30 */
GG ( c, d, a, b, in[ 7], S23, 1735328473); /* 31 */
GG ( b, c, d, a, in[12], S24, 2368359562); /* 32 */
/* Round 3 */ if (len >= need) {
#define S31 4 if (have != 0) {
#define S32 11 memcpy(ctx->buffer + have, input, need);
#define S33 16 SG_MD5Transform(ctx->state, ctx->buffer);
#define S34 23 input += need;
HH ( a, b, c, d, in[ 5], S31, 4294588738); /* 33 */ len -= need;
HH ( d, a, b, c, in[ 8], S32, 2272392833); /* 34 */ have = 0;
HH ( c, d, a, b, in[11], S33, 1839030562); /* 35 */ }
HH ( b, c, d, a, in[14], S34, 4259657740); /* 36 */
HH ( a, b, c, d, in[ 1], S31, 2763975236); /* 37 */
HH ( d, a, b, c, in[ 4], S32, 1272893353); /* 38 */
HH ( c, d, a, b, in[ 7], S33, 4139469664); /* 39 */
HH ( b, c, d, a, in[10], S34, 3200236656); /* 40 */
HH ( a, b, c, d, in[13], S31, 681279174); /* 41 */
HH ( d, a, b, c, in[ 0], S32, 3936430074); /* 42 */
HH ( c, d, a, b, in[ 3], S33, 3572445317); /* 43 */
HH ( b, c, d, a, in[ 6], S34, 76029189); /* 44 */
HH ( a, b, c, d, in[ 9], S31, 3654602809); /* 45 */
HH ( d, a, b, c, in[12], S32, 3873151461); /* 46 */
HH ( c, d, a, b, in[15], S33, 530742520); /* 47 */
HH ( b, c, d, a, in[ 2], S34, 3299628645); /* 48 */
/* Round 4 */ /* Process data in MD5_BLOCK_LENGTH-byte chunks. */
#define S41 6 while (len >= MD5_BLOCK_LENGTH) {
#define S42 10 SG_MD5Transform(ctx->state, input);
#define S43 15 input += MD5_BLOCK_LENGTH;
#define S44 21 len -= MD5_BLOCK_LENGTH;
II ( a, b, c, d, in[ 0], S41, 4096336452); /* 49 */ }
II ( d, a, b, c, in[ 7], S42, 1126891415); /* 50 */ }
II ( c, d, a, b, in[14], S43, 2878612391); /* 51 */
II ( b, c, d, a, in[ 5], S44, 4237533241); /* 52 */
II ( a, b, c, d, in[12], S41, 1700485571); /* 53 */
II ( d, a, b, c, in[ 3], S42, 2399980690); /* 54 */
II ( c, d, a, b, in[10], S43, 4293915773); /* 55 */
II ( b, c, d, a, in[ 1], S44, 2240044497); /* 56 */
II ( a, b, c, d, in[ 8], S41, 1873313359); /* 57 */
II ( d, a, b, c, in[15], S42, 4264355552); /* 58 */
II ( c, d, a, b, in[ 6], S43, 2734768916); /* 59 */
II ( b, c, d, a, in[13], S44, 1309151649); /* 60 */
II ( a, b, c, d, in[ 4], S41, 4149444226); /* 61 */
II ( d, a, b, c, in[11], S42, 3174756917); /* 62 */
II ( c, d, a, b, in[ 2], S43, 718787259); /* 63 */
II ( b, c, d, a, in[ 9], S44, 3951481745); /* 64 */
buf[0] += a; /* Handle any remaining bytes of data. */
buf[1] += b; if (len != 0)
buf[2] += c; memcpy(ctx->buffer + have, input, len);
buf[3] += d;
} }
/*
* Pad pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void
SG_MD5Pad(SG_MD5_CTX *ctx)
{
u_int8_t count[8];
size_t padlen;
/* Convert count to 8 bytes in little endian order. */
PUT_64BIT_LE(count, ctx->count);
/* Pad out to 56 mod 64. */
padlen = MD5_BLOCK_LENGTH -
((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));
if (padlen < 1 + 8)
padlen += MD5_BLOCK_LENGTH;
SG_MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */
SG_MD5Update(ctx, count, 8);
}
/*
* Final wrapup--call MD5Pad, fill in digest and zero out ctx.
*/
void
SG_MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], SG_MD5_CTX *ctx)
{
int i;
SG_MD5Pad(ctx);
if (digest != NULL) {
for (i = 0; i < 4; i++)
PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
memset(ctx, 0, sizeof(*ctx));
}
}
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void
SG_MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH])
{
u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
#ifndef WORDS_BIGENDIAN
memcpy(in, block, sizeof(in));
#else
for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
in[a] = (u_int32_t)(
(u_int32_t)(block[a * 4 + 0]) |
(u_int32_t)(block[a * 4 + 1]) << 8 |
(u_int32_t)(block[a * 4 + 2]) << 16 |
(u_int32_t)(block[a * 4 + 3]) << 24);
}
#endif
a = state[0];
b = state[1];
c = state[2];
d = state[3];
MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}
+33 -49
View File
@@ -1,68 +1,52 @@
#ifndef SG_PACKAGE_MD5_H /* $OpenBSD: md5.h,v 1.15 2004/05/03 17:30:14 millert Exp $ */
#define SG_PACKAGE_MD5_H
/* /*
********************************************************************** * This code implements the MD5 message-digest algorithm.
** md5.h -- Header file for implementation of MD5 ** * The algorithm is due to Ron Rivest. This code was
** RSA Data Security, Inc. MD5 Message Digest Algorithm ** * written by Colin Plumb in 1993, no copyright is claimed.
** Created: 2/17/90 RLR ** * This code is in the public domain; do with it what you wish.
** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** *
** Revised (for MD5): RLR 4/27/91 ** * Equivalent code is available from RSA Data Security, Inc.
** -- G modified to have y&~z instead of y&z ** * This code has been tested against that, and is equivalent,
** -- FF, GG, HH modified to add in last register done ** * except that you don't need to include two pages of legalese
** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** * with every copy.
** -- distinct additive constant for each step **
** -- round 4 added, working mod 7 **
**********************************************************************
*/ */
/* #ifndef _MD5_H_
********************************************************************** #define _MD5_H_
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
** **
** License to copy and use this software is granted provided that **
** it is identified as the "RSA Data Security, Inc. MD5 Message **
** Digest Algorithm" in all material mentioning or referencing this **
** software or this function. **
** **
** License is also granted to make and use derivative works **
** provided that such works are identified as "derived from the RSA **
** Data Security, Inc. MD5 Message Digest Algorithm" in all **
** material mentioning or referencing the derived work. **
** **
** RSA Data Security, Inc. makes no representations concerning **
** either the merchantability of this software or the suitability **
** of this software for any particular purpose. It is provided "as **
** is" without express or implied warranty of any kind. **
** **
** These notices must be retained in any copies of any part of this **
** documentation and/or software. **
**********************************************************************
*/
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* typedef a 32 bit type */ #if defined(_MSC_VER)
typedef unsigned int UINT4; typedef unsigned char u_int8_t;
typedef unsigned int u_int32_t;
typedef unsigned __int64 u_int64_t;
#endif
/* Data structure for MD5 (Message Digest) computation */ #define MD5_BLOCK_LENGTH 64
typedef struct { #define MD5_DIGEST_LENGTH 16
UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ #define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1)
UINT4 buf[4]; /* scratch buffer */
unsigned char in[64]; /* input buffer */ typedef struct MD5Context {
unsigned char digest[16]; /* actual digest after MD5Final call */ u_int32_t state[4]; /* state */
u_int64_t count; /* number of bits, mod 2^64 */
u_int8_t buffer[MD5_BLOCK_LENGTH]; /* input buffer */
} SG_MD5_CTX; } SG_MD5_CTX;
void SG_MD5Init (SG_MD5_CTX *mdContext); void SG_MD5Init(SG_MD5_CTX *);
void SG_MD5Update (SG_MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen); void SG_MD5Update(SG_MD5_CTX *, const u_int8_t *, size_t);
void SG_MD5Final (SG_MD5_CTX *mdContext); void SG_MD5Pad(SG_MD5_CTX *);
void SG_MD5Final(u_int8_t [MD5_DIGEST_LENGTH], SG_MD5_CTX *);
void SG_MD5Transform(u_int32_t [4], const u_int8_t [MD5_BLOCK_LENGTH]);
#ifdef __cplusplus #ifdef __cplusplus
} // of extern C } // of extern C
#endif #endif
#endif // of SG_PACKAGE_MD5_H #endif /* _MD5_H_ */
+4
View File
@@ -50,6 +50,8 @@
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sgstream.hxx> #include <simgear/misc/sgstream.hxx>
#include <simgear/threads/SGGuard.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx> #include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/props/vectorPropTemplates.hxx> #include <simgear/props/vectorPropTemplates.hxx>
@@ -455,6 +457,7 @@ Effect* SGMaterial::get_effect(int i)
Effect* SGMaterial::get_effect(const SGTexturedTriangleBin& triangleBin) Effect* SGMaterial::get_effect(const SGTexturedTriangleBin& triangleBin)
{ {
SGGuard<SGMutex> g(_lock);
if (_status.empty()) { if (_status.empty()) {
SG_LOG( SG_GENERAL, SG_WARN, "No effect available."); SG_LOG( SG_GENERAL, SG_WARN, "No effect available.");
return 0; return 0;
@@ -466,6 +469,7 @@ Effect* SGMaterial::get_effect(const SGTexturedTriangleBin& triangleBin)
Effect* SGMaterial::get_effect() Effect* SGMaterial::get_effect()
{ {
SGGuard<SGMutex> g(_lock);
return get_effect(0); return get_effect(0);
} }
+4
View File
@@ -43,6 +43,7 @@ class StateSet;
} }
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/threads/SGThread.hxx> // for SGMutex
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
#include <simgear/bvh/BVHMaterial.hxx> #include <simgear/bvh/BVHMaterial.hxx>
@@ -473,6 +474,9 @@ private:
// Parameters from the materials file // Parameters from the materials file
const SGPropertyNode* parameters; const SGPropertyNode* parameters;
// per-material lock for entrypoints called from multiple threads
SGMutex _lock;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Internal constructors and methods. // Internal constructors and methods.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
+4 -1
View File
@@ -27,6 +27,7 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
#include <memory> #include <memory>
@@ -41,7 +42,8 @@ namespace simgear { class Effect; }
namespace osg { class Geode; } namespace osg { class Geode; }
// Material management class // Material management class
class SGMaterialLib { class SGMaterialLib : public SGReferenced
{
private: private:
class MatLibPrivate; class MatLibPrivate;
@@ -99,5 +101,6 @@ public:
~SGMaterialLib ( void ); ~SGMaterialLib ( void );
}; };
typedef SGSharedPtr<SGMaterialLib> SGMaterialLibPtr;
#endif // _MATLIB_HXX #endif // _MATLIB_HXX
+3 -3
View File
@@ -905,7 +905,7 @@ public:
// Generate all the lighting objects for the tile. // Generate all the lighting objects for the tile.
osg::LOD* generateLightingTileObjects() osg::LOD* generateLightingTileObjects()
{ {
SGMaterialLib* matlib = NULL; SGMaterialLibPtr matlib;
if (_options) if (_options)
matlib = _options->getMaterialLib(); matlib = _options->getMaterialLib();
@@ -1046,7 +1046,7 @@ public:
// Generate all the random forest, objects and buildings for the tile // Generate all the random forest, objects and buildings for the tile
osg::LOD* generateRandomTileObjects() osg::LOD* generateRandomTileObjects()
{ {
SGMaterialLib* matlib = NULL; SGMaterialLibPtr matlib;
bool use_random_objects = false; bool use_random_objects = false;
bool use_random_vegetation = false; bool use_random_vegetation = false;
bool use_random_buildings = false; bool use_random_buildings = false;
@@ -1181,7 +1181,7 @@ SGLoadBTG(const std::string& path, const simgear::SGReaderWriterOptions* options
if (!tile.read_bin(path)) if (!tile.read_bin(path))
return NULL; return NULL;
SGMaterialLib* matlib = 0; SGMaterialLibPtr matlib;
if (options) { if (options) {
matlib = options->getMaterialLib(); matlib = options->getMaterialLib();
+5 -3
View File
@@ -22,10 +22,12 @@
#include <osgDB/Options> #include <osgDB/Options>
#include <simgear/scene/model/modellib.hxx> #include <simgear/scene/model/modellib.hxx>
#include <simgear/scene/material/matlib.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
class SGPropertyNode; class SGPropertyNode;
class SGMaterialLib;
namespace simgear namespace simgear
{ {
@@ -70,7 +72,7 @@ public:
void setPropertyNode(const SGSharedPtr<SGPropertyNode>& propertyNode) void setPropertyNode(const SGSharedPtr<SGPropertyNode>& propertyNode)
{ _propertyNode = propertyNode; } { _propertyNode = propertyNode; }
SGMaterialLib* getMaterialLib() const SGMaterialLibPtr getMaterialLib() const
{ return _materialLib; } { return _materialLib; }
void setMaterialLib(SGMaterialLib* materialLib) void setMaterialLib(SGMaterialLib* materialLib)
{ _materialLib = materialLib; } { _materialLib = materialLib; }
@@ -100,7 +102,7 @@ protected:
private: private:
SGSharedPtr<SGPropertyNode> _propertyNode; SGSharedPtr<SGPropertyNode> _propertyNode;
SGMaterialLib* _materialLib; SGSharedPtr<SGMaterialLib> _materialLib;
osg::Node *(*_load_panel)(SGPropertyNode *); osg::Node *(*_load_panel)(SGPropertyNode *);
osg::ref_ptr<SGModelData> _model_data; osg::ref_ptr<SGModelData> _model_data;
bool _instantiateEffects; bool _instantiateEffects;