- added another boost dependency.
- further work on the collada loader. Should load static geometry correctly now, but still not properly integrated - added some Collada sample files. The license is hopefully fine with this. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@245 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
01ceeeb00b
commit
fe3c008301
|
@ -117,6 +117,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
# include <boost/scoped_array.hpp>
|
||||
# include <boost/format.hpp>
|
||||
# include <boost/math/common_factor_rt.hpp>
|
||||
# include <boost/foreach.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ ColladaParser::~ColladaParser()
|
|||
delete mReader;
|
||||
for( NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it)
|
||||
delete it->second;
|
||||
for( MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it)
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -163,6 +165,9 @@ void ColladaParser::ReadAssetInfo()
|
|||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "asset") != 0)
|
||||
ThrowException( "Expected end of \"asset\" element.");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +177,491 @@ void ColladaParser::ReadAssetInfo()
|
|||
// Reads the geometry library contents
|
||||
void ColladaParser::ReadGeometryLibrary()
|
||||
{
|
||||
while( mReader->read())
|
||||
{
|
||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||
{
|
||||
if( IsElement( "geometry"))
|
||||
{
|
||||
// read ID. Another entry which is "optional" by design but obligatory in reality
|
||||
int indexID = GetAttribute( "id");
|
||||
std::string id = mReader->getAttributeValue( indexID);
|
||||
|
||||
// TODO: (thom) support SIDs
|
||||
assert( TestAttribute( "sid") == -1);
|
||||
|
||||
// a <geometry> always contains a single <mesh> element inside, so we just skip that element in advance
|
||||
TestOpening( "mesh");
|
||||
|
||||
// create a mesh and store it in the library under its ID
|
||||
Mesh* mesh = new Mesh;
|
||||
mMeshLibrary[id] = mesh;
|
||||
// read on from there
|
||||
ReadMesh( mesh);
|
||||
|
||||
// check for the closing tag of the outer <geometry" element, the inner closing of <mesh> has been consumed by ReadMesh()
|
||||
TestClosing( "geometry");
|
||||
} else
|
||||
{
|
||||
// ignore the rest
|
||||
SkipElement();
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "library_geometries") != 0)
|
||||
ThrowException( "Expected end of \"library_geometries\" element.");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a mesh from the geometry library
|
||||
void ColladaParser::ReadMesh( Mesh* pMesh)
|
||||
{
|
||||
// I'm doing a dirty state parsing here because I don't want to open another submethod for it.
|
||||
// There's a <source> tag defining the name for the accessor inside, and possible a <float_array>
|
||||
// with it's own ID. This string contains the current source's ID if parsing is inside a <source> element.
|
||||
std::string presentSourceID;
|
||||
|
||||
while( mReader->read())
|
||||
{
|
||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||
{
|
||||
if( IsElement( "source"))
|
||||
{
|
||||
// beginning of a source element - store ID for the inner elements
|
||||
int attrID = GetAttribute( "id");
|
||||
presentSourceID = mReader->getAttributeValue( attrID);
|
||||
}
|
||||
else if( IsElement( "float_array"))
|
||||
{
|
||||
ReadFloatArray();
|
||||
}
|
||||
else if( IsElement( "technique_common"))
|
||||
{
|
||||
// I don't fucking care for your profiles bullshit
|
||||
}
|
||||
else if( IsElement( "accessor"))
|
||||
{
|
||||
ReadAccessor( presentSourceID);
|
||||
}
|
||||
else if( IsElement( "vertices"))
|
||||
{
|
||||
// read per-vertex mesh data
|
||||
ReadVertexData( pMesh);
|
||||
}
|
||||
else if( IsElement( "polylist") || IsElement( "triangles"))
|
||||
{
|
||||
// read per-index mesh data and faces setup
|
||||
ReadIndexData( pMesh);
|
||||
} else
|
||||
{
|
||||
// ignore the rest
|
||||
SkipElement();
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "source") == 0)
|
||||
{
|
||||
// end of <source> - reset present source ID
|
||||
presentSourceID.clear();
|
||||
}
|
||||
else if( strcmp( mReader->getNodeName(), "technique_common") == 0)
|
||||
{
|
||||
// end of another meaningless element - read over it
|
||||
}
|
||||
else if( strcmp( mReader->getNodeName(), "mesh") == 0)
|
||||
{
|
||||
// end of <mesh> element - we're done here
|
||||
break;
|
||||
} else
|
||||
{
|
||||
// everything else should be punished
|
||||
ThrowException( "Expected end of \"mesh\" element.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a data array holding a number of floats, and stores it in the global library
|
||||
void ColladaParser::ReadFloatArray()
|
||||
{
|
||||
// read attributes
|
||||
int indexID = GetAttribute( "id");
|
||||
std::string id = mReader->getAttributeValue( indexID);
|
||||
int indexCount = GetAttribute( "count");
|
||||
unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( indexCount);
|
||||
const char* content = GetTextContent();
|
||||
|
||||
// read values and store inside an array in the data library
|
||||
mDataLibrary[id] = Data();
|
||||
Data& data = mDataLibrary[id];
|
||||
data.mValues.reserve( count);
|
||||
for( unsigned int a = 0; a < count; a++)
|
||||
{
|
||||
if( *content == 0)
|
||||
ThrowException( "Expected more values while reading float_array contents.");
|
||||
|
||||
float value;
|
||||
// read a number
|
||||
content = fast_atof_move( content, value);
|
||||
data.mValues.push_back( value);
|
||||
// skip whitespace after it
|
||||
SkipSpacesAndLineEnd( &content);
|
||||
}
|
||||
|
||||
// test for closing tag
|
||||
TestClosing( "float_array");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads an accessor and stores it in the global library
|
||||
void ColladaParser::ReadAccessor( const std::string& pID)
|
||||
{
|
||||
// read accessor attributes
|
||||
int attrSource = GetAttribute( "source");
|
||||
const char* source = mReader->getAttributeValue( attrSource);
|
||||
if( source[0] != '#')
|
||||
ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\".") % source));
|
||||
int attrCount = GetAttribute( "count");
|
||||
unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( attrCount);
|
||||
int attrOffset = TestAttribute( "offset");
|
||||
unsigned int offset = 0;
|
||||
if( attrOffset > -1)
|
||||
offset = (unsigned int) mReader->getAttributeValueAsInt( attrOffset);
|
||||
int attrStride = TestAttribute( "stride");
|
||||
unsigned int stride = 1;
|
||||
if( attrStride > -1)
|
||||
stride = (unsigned int) mReader->getAttributeValueAsInt( attrStride);
|
||||
|
||||
// store in the library under the given ID
|
||||
mAccessorLibrary[pID] = Accessor();
|
||||
Accessor& acc = mAccessorLibrary[pID];
|
||||
acc.mCount = count;
|
||||
acc.mOffset = offset;
|
||||
acc.mStride = stride;
|
||||
acc.mSource = source+1; // ignore the leading '#'
|
||||
|
||||
// and read the components
|
||||
while( mReader->read())
|
||||
{
|
||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||
{
|
||||
if( IsElement( "param"))
|
||||
{
|
||||
// read data param
|
||||
int attrName = TestAttribute( "name");
|
||||
std::string name;
|
||||
if( attrName > -1)
|
||||
{
|
||||
name = mReader->getAttributeValue( attrName);
|
||||
|
||||
// analyse for common type components and store it's sub-offset in the corresponding field
|
||||
if( name == "X") acc.mSubOffset[0] = acc.mParams.size();
|
||||
else if( name == "Y") acc.mSubOffset[1] = acc.mParams.size();
|
||||
else if( name == "Z") acc.mSubOffset[2] = acc.mParams.size();
|
||||
else if( name == "R") acc.mSubOffset[0] = acc.mParams.size();
|
||||
else if( name == "G") acc.mSubOffset[1] = acc.mParams.size();
|
||||
else if( name == "B") acc.mSubOffset[2] = acc.mParams.size();
|
||||
else if( name == "A") acc.mSubOffset[3] = acc.mParams.size();
|
||||
else if( name == "S") acc.mSubOffset[0] = acc.mParams.size();
|
||||
else if( name == "T") acc.mSubOffset[1] = acc.mParams.size();
|
||||
else
|
||||
DefaultLogger::get()->warn( boost::str( boost::format( "Unknown accessor parameter \"%s\". Ignoring data channel.") % name));
|
||||
}
|
||||
|
||||
acc.mParams.push_back( name);
|
||||
|
||||
// skip remaining stuff of this element, if any
|
||||
SkipElement();
|
||||
} else
|
||||
{
|
||||
ThrowException( "Unexpected sub element in tag \"accessor\".");
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "accessor") != 0)
|
||||
ThrowException( "Expected end of \"accessor\" element.");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads input declarations of per-vertex mesh data into the given mesh
|
||||
void ColladaParser::ReadVertexData( Mesh* pMesh)
|
||||
{
|
||||
// extract the ID of the <vertices> element. Not that we care, but to catch strange referencing schemes we should warn about
|
||||
int attrID= GetAttribute( "id");
|
||||
pMesh->mVertexID = mReader->getAttributeValue( attrID);
|
||||
|
||||
// a number of <input> elements
|
||||
while( mReader->read())
|
||||
{
|
||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||
{
|
||||
if( IsElement( "input"))
|
||||
{
|
||||
ReadInputChannel( pMesh->mPerVertexData);
|
||||
} else
|
||||
{
|
||||
ThrowException( "Unexpected sub element in tag \"vertices\".");
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "vertices") != 0)
|
||||
ThrowException( "Expected end of \"vertices\" element.");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads input declarations of per-index mesh data into the given mesh
|
||||
void ColladaParser::ReadIndexData( Mesh* pMesh)
|
||||
{
|
||||
std::vector<size_t> vcount;
|
||||
std::vector<InputChannel> perIndexData;
|
||||
|
||||
// read primitive count from the attribute
|
||||
int attrCount = GetAttribute( "count");
|
||||
size_t numPrimitives = (size_t) mReader->getAttributeValueAsInt( attrCount);
|
||||
|
||||
// distinguish between polys and triangles
|
||||
std::string elementName = mReader->getNodeName();
|
||||
bool isPolylist = IsElement( "polylist");
|
||||
|
||||
// also a number of <input> elements, but in addition a <p> primitive collection and propably index counts for all primitives
|
||||
while( mReader->read())
|
||||
{
|
||||
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||
{
|
||||
if( IsElement( "input"))
|
||||
{
|
||||
ReadInputChannel( perIndexData);
|
||||
}
|
||||
else if( IsElement( "vcount"))
|
||||
{
|
||||
// case <polylist> - specifies the number of indices for each polygon
|
||||
const char* content = GetTextContent();
|
||||
vcount.reserve( numPrimitives);
|
||||
for( unsigned int a = 0; a < numPrimitives; a++)
|
||||
{
|
||||
if( *content == 0)
|
||||
ThrowException( "Expected more values while reading vcount contents.");
|
||||
// read a number
|
||||
vcount.push_back( (size_t) strtol10( content, &content));
|
||||
// skip whitespace after it
|
||||
SkipSpacesAndLineEnd( &content);
|
||||
}
|
||||
|
||||
TestClosing( "vcount");
|
||||
}
|
||||
else if( IsElement( "p"))
|
||||
{
|
||||
// now here the actual fun starts - these are the indices to construct the mesh data from
|
||||
ReadPrimitives( pMesh, perIndexData, numPrimitives, vcount, isPolylist);
|
||||
} else
|
||||
{
|
||||
ThrowException( "Unexpected sub element in tag \"vertices\".");
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( mReader->getNodeName() != elementName)
|
||||
ThrowException( boost::str( boost::format( "Expected end of \"%s\" element.") % elementName));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a single input channel element and stores it in the given array, if valid
|
||||
void ColladaParser::ReadInputChannel( std::vector<InputChannel>& poChannels)
|
||||
{
|
||||
InputChannel channel;
|
||||
|
||||
// read semantic
|
||||
int attrSemantic = GetAttribute( "semantic");
|
||||
std::string semantic = mReader->getAttributeValue( attrSemantic);
|
||||
channel.mType = GetTypeForSemantic( semantic);
|
||||
|
||||
// read source
|
||||
int attrSource = GetAttribute( "source");
|
||||
const char* source = mReader->getAttributeValue( attrSource);
|
||||
if( source[0] != '#')
|
||||
ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\".") % source));
|
||||
channel.mAccessor = source+1; // skipping the leading #, hopefully the remaining text is the accessor ID only
|
||||
|
||||
// read index offset, if per-index <input>
|
||||
int attrOffset = TestAttribute( "offset");
|
||||
if( attrOffset > -1)
|
||||
channel.mOffset = mReader->getAttributeValueAsInt( attrOffset);
|
||||
|
||||
// store, if valid type
|
||||
if( channel.mType != IT_Invalid)
|
||||
poChannels.push_back( channel);
|
||||
|
||||
// skip remaining stuff of this element, if any
|
||||
SkipElement();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a <p> primitive index list and assembles the mesh data into the given mesh
|
||||
void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPerIndexChannels,
|
||||
size_t pNumPrimitives, const std::vector<size_t>& pVCount, bool pIsPolylist)
|
||||
{
|
||||
// determine number of indices coming per vertex
|
||||
// find the offset index for all per-vertex channels
|
||||
size_t numOffsets = 1;
|
||||
size_t perVertexOffset = -1; // invalid value
|
||||
BOOST_FOREACH( const InputChannel& channel, pPerIndexChannels)
|
||||
{
|
||||
numOffsets = std::max( numOffsets, channel.mOffset+1);
|
||||
if( channel.mType == IT_Vertex)
|
||||
perVertexOffset = channel.mOffset;
|
||||
}
|
||||
|
||||
// determine the expected number of indices
|
||||
size_t expectedPointCount = 0;
|
||||
if( pIsPolylist)
|
||||
{
|
||||
BOOST_FOREACH( size_t i, pVCount)
|
||||
expectedPointCount += i;
|
||||
} else
|
||||
{
|
||||
// everything triangles
|
||||
expectedPointCount = 3 * pNumPrimitives;
|
||||
}
|
||||
|
||||
// and read all indices into a temporary array
|
||||
std::vector<size_t> indices( expectedPointCount * numOffsets);
|
||||
const char* content = GetTextContent();
|
||||
BOOST_FOREACH( size_t& value, indices)
|
||||
{
|
||||
if( *content == 0)
|
||||
ThrowException( "Expected more values while reading primitive indices.");
|
||||
// read a value in place
|
||||
value = strtol10( content, &content);
|
||||
// skip whitespace after it
|
||||
SkipSpacesAndLineEnd( &content);
|
||||
}
|
||||
|
||||
// find the data for all sources
|
||||
BOOST_FOREACH( InputChannel& input, pMesh->mPerVertexData)
|
||||
{
|
||||
// find accessor
|
||||
input.mResolved = &ResolveLibraryReference( mAccessorLibrary, input.mAccessor);
|
||||
// resolve accessor's data pointer as well, if neccessary
|
||||
const Accessor* acc = input.mResolved;
|
||||
if( !acc->mData)
|
||||
acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource);
|
||||
}
|
||||
// and the same for the per-index channels
|
||||
BOOST_FOREACH( InputChannel& input, pPerIndexChannels)
|
||||
{
|
||||
// ignore vertex pointer, it doesn't refer to an accessor
|
||||
if( input.mType == IT_Vertex)
|
||||
{
|
||||
// warn if the vertex channel does not refer to the <vertices> element in the same mesh
|
||||
if( input.mAccessor != pMesh->mVertexID)
|
||||
ThrowException( "Unsupported vertex referencing scheme. I fucking hate Collada.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// find accessor
|
||||
input.mResolved = &ResolveLibraryReference( mAccessorLibrary, input.mAccessor);
|
||||
// resolve accessor's data pointer as well, if neccessary
|
||||
const Accessor* acc = input.mResolved;
|
||||
if( !acc->mData)
|
||||
acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource);
|
||||
}
|
||||
|
||||
|
||||
// now assemble vertex data according to those indices
|
||||
std::vector<size_t>::const_iterator idx = indices.begin();
|
||||
for( size_t a = 0; a < pNumPrimitives; a++)
|
||||
{
|
||||
// determine number of points for this primitive
|
||||
size_t numPoints = 3;
|
||||
if( pIsPolylist)
|
||||
numPoints = pVCount[a];
|
||||
|
||||
// store the face size to later reconstruct the face from
|
||||
pMesh->mFaceSize.push_back( numPoints);
|
||||
|
||||
// gather that number of vertices
|
||||
for( size_t b = 0; b < numPoints; b++)
|
||||
{
|
||||
// read all indices for this vertex. Yes, in a hacky static array
|
||||
assert( numOffsets < 20);
|
||||
static size_t vindex[20];
|
||||
for( size_t offsets = 0; offsets < numOffsets; ++offsets)
|
||||
vindex[offsets] = *idx++;
|
||||
|
||||
// extract per-vertex channels using the global per-vertex offset
|
||||
BOOST_FOREACH( const InputChannel& input, pMesh->mPerVertexData)
|
||||
ExtractDataObjectFromChannel( input, vindex[perVertexOffset], pMesh);
|
||||
// and extract per-index channels using there specified offset
|
||||
BOOST_FOREACH( const InputChannel& input, pPerIndexChannels)
|
||||
ExtractDataObjectFromChannel( input, vindex[input.mOffset], pMesh);
|
||||
}
|
||||
}
|
||||
|
||||
// if I ever get my hands on that guy how invented this steaming pile of indirection...
|
||||
TestClosing( "p");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Extracts a single object from an input channel and stores it in the appropriate mesh data array
|
||||
void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, size_t pLocalIndex, Mesh* pMesh)
|
||||
{
|
||||
// ignore vertex referrer - we handle them that separate
|
||||
if( pInput.mType == IT_Vertex)
|
||||
return;
|
||||
|
||||
const Accessor& acc = *pInput.mResolved;
|
||||
if( pLocalIndex >= acc.mCount)
|
||||
ThrowException( boost::str( boost::format( "Invalid data index (%d/%d) in primitive specification") % pLocalIndex % acc.mCount));
|
||||
|
||||
// get a pointer to the start of the data object referred to by the accessor and the local index
|
||||
const float* dataObject = &(acc.mData->mValues[0]) + acc.mOffset + pLocalIndex* acc.mStride;
|
||||
|
||||
// assemble according to the accessors component sub-offset list. We don't care, yet, what kind of object exactly we're extracting here
|
||||
float obj[4];
|
||||
for( size_t c = 0; c < 4; ++c)
|
||||
obj[c] = dataObject[acc.mSubOffset[c]];
|
||||
|
||||
// now we reinterpret it according to the type we're reading here
|
||||
switch( pInput.mType)
|
||||
{
|
||||
case IT_Position: // ignore all position streams except 0 - there can be only one position
|
||||
if( pInput.mIndex == 0)
|
||||
pMesh->mPositions.push_back( aiVector3D( obj[0], obj[1], obj[2]));
|
||||
break;
|
||||
case IT_Normal: // ignore all normal streams except 0 - there can be only one normal
|
||||
if( pInput.mIndex == 0)
|
||||
pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2]));
|
||||
break;
|
||||
case IT_Texcoord: // up to 4 texture coord sets are fine, ignore the others
|
||||
if( pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS)
|
||||
pMesh->mTexCoords[pInput.mIndex].push_back( aiVector2D( obj[0], obj[1]));
|
||||
break;
|
||||
case IT_Color: // up to 4 color sets are fine, ignore the others
|
||||
if( pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS)
|
||||
pMesh->mColors[pInput.mIndex].push_back( aiColor4D( obj[0], obj[1], obj[2], obj[3]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -214,6 +703,9 @@ void ColladaParser::ReadSceneLibrary()
|
|||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "library_visual_scenes") != 0)
|
||||
ThrowException( "Expected end of \"library_visual_scenes\" element.");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -371,6 +863,22 @@ void ColladaParser::SkipElement()
|
|||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Tests for an opening element of the given name, throws an exception if not found
|
||||
void ColladaParser::TestOpening( const char* pName)
|
||||
{
|
||||
// read element start
|
||||
if( !mReader->read())
|
||||
ThrowException( boost::str( boost::format( "Unexpected end of file while beginning of \"%s\" element.") % pName));
|
||||
// whitespace in front is ok, just read again if found
|
||||
if( mReader->getNodeType() == irr::io::EXN_TEXT)
|
||||
if( !mReader->read())
|
||||
ThrowException( boost::str( boost::format( "Unexpected end of file while reading beginning of \"%s\" element.") % pName));
|
||||
|
||||
if( mReader->getNodeType() != irr::io::EXN_ELEMENT || strcmp( mReader->getNodeName(), pName) != 0)
|
||||
ThrowException( boost::str( boost::format( "Expected start of \"%s\" element.") % pName));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Tests for the closing tag of the given element, throws an exception if not found
|
||||
void ColladaParser::TestClosing( const char* pName)
|
||||
|
@ -378,6 +886,11 @@ void ColladaParser::TestClosing( const char* pName)
|
|||
// read closing tag
|
||||
if( !mReader->read())
|
||||
ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of \"%s\" element.") % pName));
|
||||
// whitespace in front is ok, just read again if found
|
||||
if( mReader->getNodeType() == irr::io::EXN_TEXT)
|
||||
if( !mReader->read())
|
||||
ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of \"%s\" element.") % pName));
|
||||
|
||||
if( mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp( mReader->getNodeName(), pName) != 0)
|
||||
ThrowException( boost::str( boost::format( "Expected end of \"%s\" element.") % pName));
|
||||
}
|
||||
|
@ -482,3 +995,22 @@ aiMatrix4x4 ColladaParser::CalculateResultTransform( const std::vector<Transform
|
|||
|
||||
return res;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Determines the input data type for the given semantic string
|
||||
ColladaParser::InputType ColladaParser::GetTypeForSemantic( const std::string& pSemantic)
|
||||
{
|
||||
if( pSemantic == "POSITION")
|
||||
return IT_Position;
|
||||
else if( pSemantic == "TEXCOORD")
|
||||
return IT_Texcoord;
|
||||
else if( pSemantic == "NORMAL")
|
||||
return IT_Normal;
|
||||
else if( pSemantic == "COLOR")
|
||||
return IT_Color;
|
||||
else if( pSemantic == "VERTEX")
|
||||
return IT_Vertex;
|
||||
|
||||
DefaultLogger::get()->warn( boost::str( boost::format( "Unknown vertex input type \"%s\". Ignoring.") % pSemantic));
|
||||
return IT_Invalid;
|
||||
}
|
||||
|
|
|
@ -97,16 +97,65 @@ public:
|
|||
/** Accessor to a data array */
|
||||
struct Accessor
|
||||
{
|
||||
unsigned int mCount; // in number of objects
|
||||
unsigned int mOffset; // in number of values
|
||||
unsigned int mStride; // Stride in number of values
|
||||
size_t mCount; // in number of objects
|
||||
size_t mOffset; // in number of values
|
||||
size_t mStride; // Stride in number of values
|
||||
std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
|
||||
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, thats XYZ, for a color RGBA and so on.
|
||||
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
|
||||
std::string mSource; // URL of the source array
|
||||
mutable const Data* mData; // Pointer to the source array, if resolved. NULL else
|
||||
|
||||
Accessor()
|
||||
{
|
||||
mCount = 0; mOffset = 0; mStride = 0; mData = NULL;
|
||||
mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/** A single face in a mesh */
|
||||
struct Face
|
||||
{
|
||||
std::vector<size_t> mIndices;
|
||||
};
|
||||
|
||||
/** Different types of input data to a vertex or face */
|
||||
enum InputType
|
||||
{
|
||||
IT_Invalid,
|
||||
IT_Vertex, // special type for per-index data referring to the <vertices> element carrying the per-vertex data.
|
||||
IT_Position,
|
||||
IT_Normal,
|
||||
IT_Texcoord,
|
||||
IT_Color
|
||||
};
|
||||
|
||||
/** An input channel for mesh data, referring to a single accessor */
|
||||
struct InputChannel
|
||||
{
|
||||
InputType mType; // Type of the data
|
||||
size_t mIndex; // Optional index, if multiple sets of the same data type are given
|
||||
size_t mOffset; // Index offset in the indices array of per-face indices. Don't ask, can't explain that any better.
|
||||
std::string mAccessor; // ID of the accessor where to read the actual values from.
|
||||
mutable const Accessor* mResolved; // Pointer to the accessor, if resolved. NULL else
|
||||
|
||||
InputChannel() { mType = IT_Invalid; mIndex = 0; mOffset = 0; mResolved = NULL; }
|
||||
};
|
||||
|
||||
/** Contains data for a single mesh */
|
||||
struct Mesh
|
||||
{
|
||||
std::string mVertexID; // just to check if there's some sophisticated addressing involved... which we don't support, and therefore should warn about.
|
||||
std::vector<InputChannel> mPerVertexData; // Vertex data addressed by vertex indices
|
||||
|
||||
// actual mesh data, assembled on encounter of a <p> element. Verbose format, not indexed
|
||||
std::vector<aiVector3D> mPositions;
|
||||
std::vector<aiVector3D> mNormals;
|
||||
std::vector<aiVector2D> mTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
||||
std::vector<aiColor4D> mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
|
||||
|
||||
// Faces. Stored are only the number of vertices for each face. 1 == point, 2 == line, 3 == triangle, 4+ == poly
|
||||
std::vector<size_t> mFaceSize;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
@ -129,7 +178,31 @@ protected:
|
|||
void ReadGeometryLibrary();
|
||||
|
||||
/** Reads a mesh from the geometry library */
|
||||
void ReadGeometry();
|
||||
void ReadMesh( Mesh* pMesh);
|
||||
|
||||
/** Reads a data array holding a number of floats, and stores it in the global library */
|
||||
void ReadFloatArray();
|
||||
|
||||
/** Reads an accessor and stores it in the global library under the given ID -
|
||||
* accessors use the ID of the parent <source> element
|
||||
*/
|
||||
void ReadAccessor( const std::string& pID);
|
||||
|
||||
/** Reads input declarations of per-vertex mesh data into the given mesh */
|
||||
void ReadVertexData( Mesh* pMesh);
|
||||
|
||||
/** Reads input declarations of per-index mesh data into the given mesh */
|
||||
void ReadIndexData( Mesh* pMesh);
|
||||
|
||||
/** Reads a single input channel element and stores it in the given array, if valid */
|
||||
void ReadInputChannel( std::vector<InputChannel>& poChannels);
|
||||
|
||||
/** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
|
||||
void ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPerIndexChannels,
|
||||
size_t pNumPrimitives, const std::vector<size_t>& pVCount, bool pIsPolylist);
|
||||
|
||||
/** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
|
||||
void ExtractDataObjectFromChannel( const InputChannel& pInput, size_t pLocalIndex, Mesh* pMesh);
|
||||
|
||||
/** Reads the library of node hierarchies and scene parts */
|
||||
void ReadSceneLibrary();
|
||||
|
@ -153,6 +226,9 @@ protected:
|
|||
/** Compares the current xml element name to the given string and returns true if equal */
|
||||
bool IsElement( const char* pName) const { assert( mReader->getNodeType() == irr::io::EXN_ELEMENT); return strcmp( mReader->getNodeName(), pName) == 0; }
|
||||
|
||||
/** Tests for the opening tag of the given element, throws an exception if not found */
|
||||
void TestOpening( const char* pName);
|
||||
|
||||
/** Tests for the closing tag of the given element, throws an exception if not found */
|
||||
void TestClosing( const char* pName);
|
||||
|
||||
|
@ -168,6 +244,12 @@ protected:
|
|||
/** Calculates the resulting transformation fromm all the given transform steps */
|
||||
aiMatrix4x4 CalculateResultTransform( const std::vector<Transform>& pTransforms) const;
|
||||
|
||||
/** Determines the input data type for the given semantic string */
|
||||
InputType GetTypeForSemantic( const std::string& pSemantic);
|
||||
|
||||
/** Finds the item in the given library by its reference, throws if not found */
|
||||
template <typename Type> const Type& ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
|
||||
|
||||
protected:
|
||||
/** Filename, for a verbose error message */
|
||||
std::string mFileName;
|
||||
|
@ -175,6 +257,18 @@ protected:
|
|||
/** XML reader */
|
||||
irr::io::IrrXMLReader* mReader;
|
||||
|
||||
/** All data arrays found in the file by ID. Might be referred to by actually everyone. Collada, you are a steaming pile of indirection. */
|
||||
typedef std::map<std::string, Data> DataLibrary;
|
||||
DataLibrary mDataLibrary;
|
||||
|
||||
/** Same for accessors which define how the data in a data array is accessed. */
|
||||
typedef std::map<std::string, Accessor> AccessorLibrary;
|
||||
AccessorLibrary mAccessorLibrary;
|
||||
|
||||
/** Mesh library: mesh by ID */
|
||||
typedef std::map<std::string, Mesh*> MeshLibrary;
|
||||
MeshLibrary mMeshLibrary;
|
||||
|
||||
/** node library: root node of the hierarchy part by ID */
|
||||
typedef std::map<std::string, Node*> NodeLibrary;
|
||||
NodeLibrary mNodeLibrary;
|
||||
|
@ -189,6 +283,17 @@ protected:
|
|||
enum { UP_X, UP_Y, UP_Z } mUpDirection;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Finds the item in the given library by its reference, throws if not found
|
||||
template <typename Type>
|
||||
const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const
|
||||
{
|
||||
std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL);
|
||||
if( it == pLibrary.end())
|
||||
ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL));
|
||||
return it->second;
|
||||
}
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
#endif // AI_COLLADAPARSER_H_INC
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
|
@ -0,0 +1,210 @@
|
|||
<?xml version="1.0"?>
|
||||
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
|
||||
<asset>
|
||||
<contributor>
|
||||
<author>alorino</author>
|
||||
<authoring_tool>Maya 7.0 | ColladaMaya v2.01 Jun 9 2006 at 16:08:19 | FCollada v1.11</authoring_tool>
|
||||
<comments>Collada Maya Export Options: bakeTransforms=0;exportPolygonMeshes=1;bakeLighting=0;isSampling=0;
|
||||
curveConstrainSampling=0;exportCameraAsLookat=0;
|
||||
exportLights=1;exportCameras=1;exportJointsAndSkin=1;
|
||||
exportAnimations=1;exportTriangles=0;exportInvisibleNodes=0;
|
||||
exportNormals=1;exportTexCoords=1;exportVertexColors=1;exportTangents=0;
|
||||
exportTexTangents=0;exportConstraints=0;exportPhysics=0;exportXRefs=1;
|
||||
dereferenceXRefs=0;cameraXFov=0;cameraYFov=1</comments>
|
||||
<copyright>
|
||||
Copyright 2006 Sony Computer Entertainment Inc.
|
||||
Licensed under the SCEA Shared Source License, Version 1.0 (the
|
||||
"License"); you may not use this file except in compliance with the
|
||||
License. You may obtain a copy of the License at:
|
||||
http://research.scea.com/scea_shared_source_license.html
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
</copyright>
|
||||
</contributor>
|
||||
<created>2006-06-21T21:23:22Z</created>
|
||||
<modified>2006-06-21T21:23:22Z</modified>
|
||||
<unit meter="0.01" name="centimeter"/>
|
||||
<up_axis>Y_UP</up_axis>
|
||||
</asset>
|
||||
<library_cameras>
|
||||
<camera id="PerspCamera" name="PerspCamera">
|
||||
<optics>
|
||||
<technique_common>
|
||||
<perspective>
|
||||
<yfov>37.8493</yfov>
|
||||
<aspect_ratio>1</aspect_ratio>
|
||||
<znear>10</znear>
|
||||
<zfar>1000</zfar>
|
||||
</perspective>
|
||||
</technique_common>
|
||||
</optics>
|
||||
</camera>
|
||||
<camera id="testCameraShape" name="testCameraShape">
|
||||
<optics>
|
||||
<technique_common>
|
||||
<perspective>
|
||||
<yfov>37.8501</yfov>
|
||||
<aspect_ratio>1</aspect_ratio>
|
||||
<znear>0.01</znear>
|
||||
<zfar>1000</zfar>
|
||||
</perspective>
|
||||
</technique_common>
|
||||
</optics>
|
||||
</camera>
|
||||
</library_cameras>
|
||||
<library_lights>
|
||||
<light id="light-lib" name="light">
|
||||
<technique_common>
|
||||
<point>
|
||||
<color>1 1 1</color>
|
||||
<constant_attenuation>1</constant_attenuation>
|
||||
<linear_attenuation>0</linear_attenuation>
|
||||
<quadratic_attenuation>0</quadratic_attenuation>
|
||||
</point>
|
||||
</technique_common>
|
||||
<technique profile="MAX3D">
|
||||
<intensity>1.000000</intensity>
|
||||
</technique>
|
||||
</light>
|
||||
<light id="pointLightShape1-lib" name="pointLightShape1">
|
||||
<technique_common>
|
||||
<point>
|
||||
<color>1 1 1</color>
|
||||
<constant_attenuation>1</constant_attenuation>
|
||||
<linear_attenuation>0</linear_attenuation>
|
||||
<quadratic_attenuation>0</quadratic_attenuation>
|
||||
</point>
|
||||
</technique_common>
|
||||
</light>
|
||||
</library_lights>
|
||||
<library_materials>
|
||||
<material id="Blue" name="Blue">
|
||||
<instance_effect url="#Blue-fx"/>
|
||||
</material>
|
||||
</library_materials>
|
||||
<library_effects>
|
||||
<effect id="Blue-fx">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color>0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color>0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color>0.137255 0.403922 0.870588 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color>0.5 0.5 0.5 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float>16</float>
|
||||
</shininess>
|
||||
<reflective>
|
||||
<color>0 0 0 1</color>
|
||||
</reflective>
|
||||
<reflectivity>
|
||||
<float>0.5</float>
|
||||
</reflectivity>
|
||||
<transparent>
|
||||
<color>0 0 0 1</color>
|
||||
</transparent>
|
||||
<transparency>
|
||||
<float>1</float>
|
||||
</transparency>
|
||||
<index_of_refraction>
|
||||
<float>0</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
</library_effects>
|
||||
<library_geometries>
|
||||
<geometry id="box-lib" name="box">
|
||||
<mesh>
|
||||
<source id="box-lib-positions" name="position">
|
||||
<float_array id="box-lib-positions-array" count="24">-50 50 50 50 50 50 -50 -50 50 50 -50 50 -50 50 -50 50 50 -50 -50 -50 -50 50 -50 -50</float_array>
|
||||
<technique_common>
|
||||
<accessor count="8" offset="0" source="#box-lib-positions-array" stride="3">
|
||||
<param name="X" type="float"></param>
|
||||
<param name="Y" type="float"></param>
|
||||
<param name="Z" type="float"></param>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="box-lib-normals" name="normal">
|
||||
<float_array id="box-lib-normals-array" count="72">0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1</float_array>
|
||||
<technique_common>
|
||||
<accessor count="24" offset="0" source="#box-lib-normals-array" stride="3">
|
||||
<param name="X" type="float"></param>
|
||||
<param name="Y" type="float"></param>
|
||||
<param name="Z" type="float"></param>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<vertices id="box-lib-vertices">
|
||||
<input semantic="POSITION" source="#box-lib-positions"/>
|
||||
</vertices>
|
||||
<polylist count="6" material="BlueSG">
|
||||
<input offset="0" semantic="VERTEX" source="#box-lib-vertices"/>
|
||||
<input offset="1" semantic="NORMAL" source="#box-lib-normals"/>
|
||||
<vcount>4 4 4 4 4 4</vcount>
|
||||
<p>0 0 2 1 3 2 1 3 0 4 1 5 5 6 4 7 6 8 7 9 3 10 2 11 0 12 4 13 6 14 2 15 3 16 7 17 5 18 1 19 5 20 7 21 6 22 4 23</p>
|
||||
</polylist>
|
||||
</mesh>
|
||||
</geometry>
|
||||
</library_geometries>
|
||||
<library_visual_scenes>
|
||||
<visual_scene id="VisualSceneNode" name="untitled">
|
||||
<node id="Camera" name="Camera">
|
||||
<translate sid="translate">-427.749 333.855 655.017</translate>
|
||||
<rotate sid="rotateY">0 1 0 -33</rotate>
|
||||
<rotate sid="rotateX">1 0 0 -22.1954</rotate>
|
||||
<rotate sid="rotateZ">0 0 1 0</rotate>
|
||||
<instance_camera url="#PerspCamera"/>
|
||||
</node>
|
||||
<node id="Light" name="Light">
|
||||
<translate sid="translate">-500 1000 400</translate>
|
||||
<rotate sid="rotateZ">0 0 1 0</rotate>
|
||||
<rotate sid="rotateY">0 1 0 0</rotate>
|
||||
<rotate sid="rotateX">1 0 0 0</rotate>
|
||||
<instance_light url="#light-lib"/>
|
||||
</node>
|
||||
<node id="Box" name="Box">
|
||||
<rotate sid="rotateZ">0 0 1 0</rotate>
|
||||
<rotate sid="rotateY">0 1 0 0</rotate>
|
||||
<rotate sid="rotateX">1 0 0 0</rotate>
|
||||
<instance_geometry url="#box-lib">
|
||||
<bind_material>
|
||||
<technique_common>
|
||||
<instance_material symbol="BlueSG" target="#Blue"/>
|
||||
</technique_common>
|
||||
</bind_material>
|
||||
</instance_geometry>
|
||||
</node>
|
||||
<node id="testCamera" name="testCamera">
|
||||
<translate sid="translate">-427.749 333.855 655.017</translate>
|
||||
<rotate sid="rotateY">0 1 0 -33</rotate>
|
||||
<rotate sid="rotateX">1 0 0 -22.1954</rotate>
|
||||
<rotate sid="rotateZ">0 0 1 0</rotate>
|
||||
<instance_camera url="#testCameraShape"/>
|
||||
</node>
|
||||
<node id="pointLight1" name="pointLight1">
|
||||
<translate sid="translate">3 4 10</translate>
|
||||
<rotate sid="rotateZ">0 0 1 0</rotate>
|
||||
<rotate sid="rotateY">0 1 0 0</rotate>
|
||||
<rotate sid="rotateX">1 0 0 0</rotate>
|
||||
<instance_light url="#pointLightShape1-lib"/>
|
||||
</node>
|
||||
</visual_scene>
|
||||
</library_visual_scenes>
|
||||
<scene>
|
||||
<instance_visual_scene url="#VisualSceneNode"/>
|
||||
</scene>
|
||||
</COLLADA>
|
|
@ -0,0 +1,210 @@
|
|||
<?xml version="1.0"?>
|
||||
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
|
||||
<asset>
|
||||
<contributor>
|
||||
<author>alorino</author>
|
||||
<authoring_tool>Maya 7.0 | ColladaMaya v2.01 Jun 9 2006 at 16:08:19 | FCollada v1.11</authoring_tool>
|
||||
<comments>Collada Maya Export Options: bakeTransforms=0;exportPolygonMeshes=1;bakeLighting=0;isSampling=0;
|
||||
curveConstrainSampling=0;exportCameraAsLookat=0;
|
||||
exportLights=1;exportCameras=1;exportJointsAndSkin=1;
|
||||
exportAnimations=1;exportTriangles=0;exportInvisibleNodes=0;
|
||||
exportNormals=1;exportTexCoords=1;exportVertexColors=1;exportTangents=0;
|
||||
exportTexTangents=0;exportConstraints=0;exportPhysics=0;exportXRefs=1;
|
||||
dereferenceXRefs=0;cameraXFov=0;cameraYFov=1</comments>
|
||||
<copyright>
|
||||
Copyright 2006 Sony Computer Entertainment Inc.
|
||||
Licensed under the SCEA Shared Source License, Version 1.0 (the
|
||||
"License"); you may not use this file except in compliance with the
|
||||
License. You may obtain a copy of the License at:
|
||||
http://research.scea.com/scea_shared_source_license.html
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
</copyright>
|
||||
|
||||
</contributor>
|
||||
<created>2006-06-21T21:23:22Z</created>
|
||||
<modified>2006-06-21T21:23:22Z</modified>
|
||||
<unit meter="0.01" name="centimeter"/>
|
||||
<up_axis>Y_UP</up_axis>
|
||||
</asset>
|
||||
<library_cameras>
|
||||
<camera id="PerspCamera" name="PerspCamera">
|
||||
<optics>
|
||||
<technique_common>
|
||||
<perspective>
|
||||
<yfov>37.8493</yfov>
|
||||
<aspect_ratio>1</aspect_ratio>
|
||||
<znear>10</znear>
|
||||
<zfar>1000</zfar>
|
||||
</perspective>
|
||||
</technique_common>
|
||||
</optics>
|
||||
</camera>
|
||||
<camera id="testCameraShape" name="testCameraShape">
|
||||
<optics>
|
||||
<technique_common>
|
||||
<perspective>
|
||||
<yfov>37.8501</yfov>
|
||||
<aspect_ratio>1</aspect_ratio>
|
||||
<znear>0.01</znear>
|
||||
<zfar>1000</zfar>
|
||||
</perspective>
|
||||
</technique_common>
|
||||
</optics>
|
||||
</camera>
|
||||
</library_cameras>
|
||||
<library_lights>
|
||||
<light id="light-lib" name="light">
|
||||
<technique_common>
|
||||
<point>
|
||||
<color>1 1 1</color>
|
||||
<constant_attenuation>1</constant_attenuation>
|
||||
<linear_attenuation>0</linear_attenuation>
|
||||
<quadratic_attenuation>0</quadratic_attenuation>
|
||||
</point>
|
||||
</technique_common>
|
||||
<technique profile="MAX3D">
|
||||
<intensity>1.000000</intensity>
|
||||
</technique>
|
||||
</light>
|
||||
<light id="pointLightShape1-lib" name="pointLightShape1">
|
||||
<technique_common>
|
||||
<point>
|
||||
<color>1 1 1</color>
|
||||
<constant_attenuation>1</constant_attenuation>
|
||||
<linear_attenuation>0</linear_attenuation>
|
||||
<quadratic_attenuation>0</quadratic_attenuation>
|
||||
</point>
|
||||
</technique_common>
|
||||
</light>
|
||||
</library_lights>
|
||||
<library_materials>
|
||||
<material id="Blue" name="Blue">
|
||||
<instance_effect url="#Blue-fx"/>
|
||||
</material>
|
||||
</library_materials>
|
||||
<library_effects>
|
||||
<effect id="Blue-fx">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color>0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color>0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color>0.137255 0.403922 0.870588 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color>0.5 0.5 0.5 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float>16</float>
|
||||
</shininess>
|
||||
<reflective>
|
||||
<color>0 0 0 1</color>
|
||||
</reflective>
|
||||
<reflectivity>
|
||||
<float>0.5</float>
|
||||
</reflectivity>
|
||||
<transparent>
|
||||
<color>0 0 0 1</color>
|
||||
</transparent>
|
||||
<transparency>
|
||||
<float>1</float>
|
||||
</transparency>
|
||||
<index_of_refraction>
|
||||
<float>0</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
</library_effects>
|
||||
<library_geometries>
|
||||
<geometry id="box-lib" name="box">
|
||||
<mesh>
|
||||
<source id="box-lib-positions" name="position">
|
||||
<float_array id="box-lib-positions-array" count="24">-50 50 50 50 50 50 -50 -50 50 50 -50 50 -50 50 -50 50 50 -50 -50 -50 -50 50 -50 -50</float_array>
|
||||
<technique_common>
|
||||
<accessor count="8" offset="0" source="#box-lib-positions-array" stride="3">
|
||||
<param name="X" type="float"></param>
|
||||
<param name="Y" type="float"></param>
|
||||
<param name="Z" type="float"></param>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="box-lib-normals" name="normal">
|
||||
<float_array id="box-lib-normals-array" count="72">0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1</float_array>
|
||||
<technique_common>
|
||||
<accessor count="24" offset="0" source="#box-lib-normals-array" stride="3">
|
||||
<param name="X" type="float"></param>
|
||||
<param name="Y" type="float"></param>
|
||||
<param name="Z" type="float"></param>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<vertices id="box-lib-vertices">
|
||||
<input semantic="POSITION" source="#box-lib-positions"/>
|
||||
</vertices>
|
||||
<triangles count="12" material="BlueSG">
|
||||
<input offset="0" semantic="VERTEX" source="#box-lib-vertices"/>
|
||||
<input offset="1" semantic="NORMAL" source="#box-lib-normals"/>
|
||||
<p>0 0 2 1 3 2 0 0 3 2 1 3 0 4 1 5 5 6 0 4 5 6 4 7 6 8 7 9 3 10 6 8 3 10 2 11 0 12 4 13 6 14 0 12 6 14 2 15 3 16 7 17 5 18 3 16 5 18 1 19 5 20 7 21 6 22 5 20 6 22 4 23</p>
|
||||
</triangles>
|
||||
</mesh>
|
||||
</geometry>
|
||||
</library_geometries>
|
||||
<library_visual_scenes>
|
||||
<visual_scene id="VisualSceneNode" name="untitled">
|
||||
<node id="Camera" name="Camera">
|
||||
<translate sid="translate">-427.749 333.855 655.017</translate>
|
||||
<rotate sid="rotateY">0 1 0 -33</rotate>
|
||||
<rotate sid="rotateX">1 0 0 -22.1954</rotate>
|
||||
<rotate sid="rotateZ">0 0 1 0</rotate>
|
||||
<instance_camera url="#PerspCamera"/>
|
||||
</node>
|
||||
<node id="Light" name="Light">
|
||||
<translate sid="translate">-500 1000 400</translate>
|
||||
<rotate sid="rotateZ">0 0 1 0</rotate>
|
||||
<rotate sid="rotateY">0 1 0 0</rotate>
|
||||
<rotate sid="rotateX">1 0 0 0</rotate>
|
||||
<instance_light url="#light-lib"/>
|
||||
</node>
|
||||
<node id="Box" name="Box">
|
||||
<rotate sid="rotateZ">0 0 1 0</rotate>
|
||||
<rotate sid="rotateY">0 1 0 0</rotate>
|
||||
<rotate sid="rotateX">1 0 0 0</rotate>
|
||||
<instance_geometry url="#box-lib">
|
||||
<bind_material>
|
||||
<technique_common>
|
||||
<instance_material symbol="BlueSG" target="#Blue"/>
|
||||
</technique_common>
|
||||
</bind_material>
|
||||
</instance_geometry>
|
||||
</node>
|
||||
<node id="testCamera" name="testCamera">
|
||||
<translate sid="translate">-427.749 333.855 655.017</translate>
|
||||
<rotate sid="rotateY">0 1 0 -33</rotate>
|
||||
<rotate sid="rotateX">1 0 0 -22.1954</rotate>
|
||||
<rotate sid="rotateZ">0 0 1 0</rotate>
|
||||
<instance_camera url="#testCameraShape"/>
|
||||
</node>
|
||||
<node id="pointLight1" name="pointLight1">
|
||||
<translate sid="translate">3 4 10</translate>
|
||||
<rotate sid="rotateZ">0 0 1 0</rotate>
|
||||
<rotate sid="rotateY">0 1 0 0</rotate>
|
||||
<rotate sid="rotateX">1 0 0 0</rotate>
|
||||
<instance_light url="#pointLightShape1-lib"/>
|
||||
</node>
|
||||
</visual_scene>
|
||||
</library_visual_scenes>
|
||||
<scene>
|
||||
<instance_visual_scene url="#VisualSceneNode"/>
|
||||
</scene>
|
||||
</COLLADA>
|
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 768 KiB |
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 8.4 KiB |
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue