Merge branch 'master' into new_obj_stream_handling
commit
bf06ee3ed4
|
@ -29,6 +29,12 @@ cmake_uninstall.cmake
|
||||||
assimp-config.cmake
|
assimp-config.cmake
|
||||||
assimp-config-version.cmake
|
assimp-config-version.cmake
|
||||||
|
|
||||||
|
# MakeFile
|
||||||
|
Makefile
|
||||||
|
test/Makefile
|
||||||
|
test/headercheck/Makefile
|
||||||
|
tools/assimp_cmd/Makefile
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
test/results
|
test/results
|
||||||
|
|
||||||
|
|
|
@ -611,6 +611,8 @@ ADD_ASSIMP_IMPORTER( X
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_ASSIMP_IMPORTER(X3D
|
ADD_ASSIMP_IMPORTER(X3D
|
||||||
|
X3DExporter.cpp
|
||||||
|
X3DExporter.hpp
|
||||||
X3DImporter.cpp
|
X3DImporter.cpp
|
||||||
X3DImporter.hpp
|
X3DImporter.hpp
|
||||||
X3DImporter_Geometry2D.cpp
|
X3DImporter_Geometry2D.cpp
|
||||||
|
|
|
@ -91,6 +91,7 @@ void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportPropert
|
||||||
void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// global array of all export formats which Assimp supports in its current build
|
// global array of all export formats which Assimp supports in its current build
|
||||||
|
@ -151,6 +152,10 @@ Exporter::ExportFormatEntry gExporters[] =
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "assxml", "Assxml Document", "assxml" , &ExportSceneAssxml, 0),
|
Exporter::ExportFormatEntry( "assxml", "Assxml Document", "assxml" , &ExportSceneAssxml, 0),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
|
||||||
|
Exporter::ExportFormatEntry( "x3d", "Extensible 3D", "x3d" , &ExportSceneX3D, 0),
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0]))
|
#define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0]))
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -182,10 +182,15 @@ void ObjFileParser::parseFile()
|
||||||
|
|
||||||
case 'm': // Parse a material library or merging group ('mg')
|
case 'm': // Parse a material library or merging group ('mg')
|
||||||
{
|
{
|
||||||
if (*(m_DataIt + 1) == 'g')
|
std::string name;
|
||||||
|
|
||||||
|
getName(m_DataIt, m_DataItEnd, name);
|
||||||
|
if (name == "mg")
|
||||||
getGroupNumberAndResolution();
|
getGroupNumberAndResolution();
|
||||||
else
|
else if(name == "mtllib")
|
||||||
getMaterialLib();
|
getMaterialLib();
|
||||||
|
else
|
||||||
|
goto pf_skip_line;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -209,6 +214,8 @@ void ObjFileParser::parseFile()
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
pf_skip_line:
|
||||||
|
|
||||||
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -625,6 +632,10 @@ void ObjFileParser::getMaterialLib()
|
||||||
// Check for existence
|
// Check for existence
|
||||||
const std::string strMatName(pStart, &(*m_DataIt));
|
const std::string strMatName(pStart, &(*m_DataIt));
|
||||||
std::string absName;
|
std::string absName;
|
||||||
|
|
||||||
|
// Check if directive is valid.
|
||||||
|
if(!strMatName.length()) throw DeadlyImportError("File name of the material is absent.");
|
||||||
|
|
||||||
if ( m_pIO->StackSize() > 0 ) {
|
if ( m_pIO->StackSize() > 0 ) {
|
||||||
std::string path = m_pIO->CurrentDirectory();
|
std::string path = m_pIO->CurrentDirectory();
|
||||||
if ( '/' != *path.rbegin() ) {
|
if ( '/' != *path.rbegin() ) {
|
||||||
|
|
|
@ -1237,8 +1237,8 @@ void SceneCombiner::Copy (aiMetadata** _dest, const aiMetadata* src)
|
||||||
case AI_BOOL:
|
case AI_BOOL:
|
||||||
out.mData = new bool(*static_cast<bool*>(in.mData));
|
out.mData = new bool(*static_cast<bool*>(in.mData));
|
||||||
break;
|
break;
|
||||||
case AI_INT:
|
case AI_INT32:
|
||||||
out.mData = new int(*static_cast<int*>(in.mData));
|
out.mData = new int32_t(*static_cast<int32_t*>(in.mData));
|
||||||
break;
|
break;
|
||||||
case AI_UINT64:
|
case AI_UINT64:
|
||||||
out.mData = new uint64_t(*static_cast<uint64_t*>(in.mData));
|
out.mData = new uint64_t(*static_cast<uint64_t*>(in.mData));
|
||||||
|
|
|
@ -0,0 +1,730 @@
|
||||||
|
/// \file X3DExporter.cpp
|
||||||
|
/// \brief X3D-format files exporter for Assimp. Implementation.
|
||||||
|
/// \date 2016
|
||||||
|
/// \author smal.root@gmail.com
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
|
#ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
|
||||||
|
|
||||||
|
#include "X3DExporter.hpp"
|
||||||
|
|
||||||
|
// Header files, Assimp.
|
||||||
|
#include "Exceptional.h"
|
||||||
|
#include <assimp/Exporter.hpp>
|
||||||
|
#include <assimp/IOSystem.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
|
||||||
|
void ExportSceneX3D(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
|
{
|
||||||
|
X3DExporter exporter(pFile, pIOSystem, pScene, pProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
}// namespace Assimp
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
|
||||||
|
void X3DExporter::IndentationStringSet(const size_t pNewLevel)
|
||||||
|
{
|
||||||
|
if(pNewLevel > mIndentationString.size())
|
||||||
|
{
|
||||||
|
if(pNewLevel > mIndentationString.capacity()) mIndentationString.reserve(pNewLevel + 1);
|
||||||
|
|
||||||
|
for(size_t i = 0, i_e = pNewLevel - mIndentationString.size(); i < i_e; i++) mIndentationString.push_back('\t');
|
||||||
|
}
|
||||||
|
else if(pNewLevel < mIndentationString.size())
|
||||||
|
{
|
||||||
|
mIndentationString.resize(pNewLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::XML_Write(const string& pData)
|
||||||
|
{
|
||||||
|
if(pData.size() == 0) return;
|
||||||
|
if(mOutFile->Write((void*)pData.data(), pData.length(), 1) != 1) throw DeadlyExportError("Failed to write scene data!");
|
||||||
|
}
|
||||||
|
|
||||||
|
aiMatrix4x4 X3DExporter::Matrix_GlobalToCurrent(const aiNode& pNode) const
|
||||||
|
{
|
||||||
|
aiNode* cur_node;
|
||||||
|
std::list<aiMatrix4x4> matr;
|
||||||
|
aiMatrix4x4 out_matr;
|
||||||
|
|
||||||
|
// starting walk from current element to root
|
||||||
|
matr.push_back(pNode.mTransformation);
|
||||||
|
cur_node = pNode.mParent;
|
||||||
|
if(cur_node != nullptr)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
matr.push_back(cur_node->mTransformation);
|
||||||
|
cur_node = cur_node->mParent;
|
||||||
|
} while(cur_node != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// multiplicate all matrices in reverse order
|
||||||
|
for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); rit++) out_matr = out_matr * (*rit);
|
||||||
|
|
||||||
|
return out_matr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::AttrHelper_FloatToString(const float pValue, std::string& pTargetString)
|
||||||
|
{
|
||||||
|
pTargetString = to_string(pValue);
|
||||||
|
AttrHelper_CommaToPoint(pTargetString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, string& pTargetString)
|
||||||
|
{
|
||||||
|
pTargetString.clear();
|
||||||
|
pTargetString.reserve(pArray_Size * 6);// (Number + space) * 3.
|
||||||
|
for(size_t idx = 0; idx < pArray_Size; idx++)
|
||||||
|
pTargetString.append(to_string(pArray[idx].x) + " " + to_string(pArray[idx].y) + " " + to_string(pArray[idx].z) + " ");
|
||||||
|
|
||||||
|
// remove last space symbol.
|
||||||
|
pTargetString.resize(pTargetString.length() - 1);
|
||||||
|
AttrHelper_CommaToPoint(pTargetString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::AttrHelper_Vec2DArrToString(const aiVector2D* pArray, const size_t pArray_Size, std::string& pTargetString)
|
||||||
|
{
|
||||||
|
pTargetString.clear();
|
||||||
|
pTargetString.reserve(pArray_Size * 4);// (Number + space) * 2.
|
||||||
|
for(size_t idx = 0; idx < pArray_Size; idx++)
|
||||||
|
pTargetString.append(to_string(pArray[idx].x) + " " + to_string(pArray[idx].y) + " ");
|
||||||
|
|
||||||
|
// remove last space symbol.
|
||||||
|
pTargetString.resize(pTargetString.length() - 1);
|
||||||
|
AttrHelper_CommaToPoint(pTargetString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::AttrHelper_Vec3DAsVec2fArrToString(const aiVector3D* pArray, const size_t pArray_Size, string& pTargetString)
|
||||||
|
{
|
||||||
|
pTargetString.clear();
|
||||||
|
pTargetString.reserve(pArray_Size * 4);// (Number + space) * 2.
|
||||||
|
for(size_t idx = 0; idx < pArray_Size; idx++)
|
||||||
|
pTargetString.append(to_string(pArray[idx].x) + " " + to_string(pArray[idx].y) + " ");
|
||||||
|
|
||||||
|
// remove last space symbol.
|
||||||
|
pTargetString.resize(pTargetString.length() - 1);
|
||||||
|
AttrHelper_CommaToPoint(pTargetString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, string& pTargetString)
|
||||||
|
{
|
||||||
|
pTargetString.clear();
|
||||||
|
pTargetString.reserve(pArray_Size * 8);// (Number + space) * 4.
|
||||||
|
for(size_t idx = 0; idx < pArray_Size; idx++)
|
||||||
|
pTargetString.append(to_string(pArray[idx].r) + " " + to_string(pArray[idx].g) + " " + to_string(pArray[idx].b) + " " +
|
||||||
|
to_string(pArray[idx].a) + " ");
|
||||||
|
|
||||||
|
// remove last space symbol.
|
||||||
|
pTargetString.resize(pTargetString.length() - 1);
|
||||||
|
AttrHelper_CommaToPoint(pTargetString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString)
|
||||||
|
{
|
||||||
|
pTargetString.clear();
|
||||||
|
pTargetString.reserve(pArray_Size * 6);// (Number + space) * 3.
|
||||||
|
for(size_t idx = 0; idx < pArray_Size; idx++)
|
||||||
|
pTargetString.append(to_string(pArray[idx].r) + " " + to_string(pArray[idx].g) + " " + to_string(pArray[idx].b) + " ");
|
||||||
|
|
||||||
|
// remove last space symbol.
|
||||||
|
pTargetString.resize(pTargetString.length() - 1);
|
||||||
|
AttrHelper_CommaToPoint(pTargetString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::AttrHelper_Color3ToAttrList(std::list<SAttribute> pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue)
|
||||||
|
{
|
||||||
|
string tstr;
|
||||||
|
|
||||||
|
if(pValue == pDefaultValue) return;
|
||||||
|
|
||||||
|
AttrHelper_Col3DArrToString(&pValue, 1, tstr);
|
||||||
|
pList.push_back({pName, tstr});
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::AttrHelper_FloatToAttrList(std::list<SAttribute> pList, const string& pName, const float pValue, const float pDefaultValue)
|
||||||
|
{
|
||||||
|
string tstr;
|
||||||
|
|
||||||
|
if(pValue == pDefaultValue) return;
|
||||||
|
|
||||||
|
AttrHelper_FloatToString(pValue, tstr);
|
||||||
|
pList.push_back({pName, tstr});
|
||||||
|
};
|
||||||
|
|
||||||
|
void X3DExporter::NodeHelper_OpenNode(const string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const list<SAttribute>& pAttrList)
|
||||||
|
{
|
||||||
|
// Write indentation.
|
||||||
|
IndentationStringSet(pTabLevel);
|
||||||
|
XML_Write(mIndentationString);
|
||||||
|
// Begin of the element
|
||||||
|
XML_Write("<" + pNodeName);
|
||||||
|
// Write attributes
|
||||||
|
for(const SAttribute& attr: pAttrList) { XML_Write(" " + attr.Name + "='" + attr.Value + "'"); }
|
||||||
|
|
||||||
|
// End of the element
|
||||||
|
if(pEmptyElement)
|
||||||
|
{
|
||||||
|
XML_Write("/>\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XML_Write(">\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::NodeHelper_OpenNode(const string& pNodeName, const size_t pTabLevel, const bool pEmptyElement)
|
||||||
|
{
|
||||||
|
const list<SAttribute> attr_list;
|
||||||
|
|
||||||
|
NodeHelper_OpenNode(pNodeName, pTabLevel, pEmptyElement, attr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::NodeHelper_CloseNode(const string& pNodeName, const size_t pTabLevel)
|
||||||
|
{
|
||||||
|
// Write indentation.
|
||||||
|
IndentationStringSet(pTabLevel);
|
||||||
|
XML_Write(mIndentationString);
|
||||||
|
// Write element
|
||||||
|
XML_Write("</" + pNodeName + ">\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::Export_Node(const aiNode *pNode, const size_t pTabLevel)
|
||||||
|
{
|
||||||
|
bool transform = false;
|
||||||
|
list<SAttribute> attr_list;
|
||||||
|
|
||||||
|
// In Assimp lights is stored in next way: light source store in mScene->mLights and in node tree must present aiNode with name same as
|
||||||
|
// light source has. Considering it we must compare every aiNode name with light sources names. Why not to look where ligths is present
|
||||||
|
// and save them to fili? Because corresponding aiNode can be already written to file and we can only add information to file not to edit.
|
||||||
|
if(CheckAndExport_Light(*pNode, pTabLevel)) return;
|
||||||
|
|
||||||
|
// Check if need DEF.
|
||||||
|
if(pNode->mName.length) attr_list.push_back({"DEF", pNode->mName.C_Str()});
|
||||||
|
|
||||||
|
// Check if need <Transformation> node against <Group>.
|
||||||
|
if(!pNode->mTransformation.IsIdentity())
|
||||||
|
{
|
||||||
|
auto Vector2String = [this](const aiVector3D pVector) -> string
|
||||||
|
{
|
||||||
|
string tstr = to_string(pVector.x) + " " + to_string(pVector.y) + " " + to_string(pVector.z);
|
||||||
|
|
||||||
|
AttrHelper_CommaToPoint(tstr);
|
||||||
|
|
||||||
|
return tstr;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto Rotation2String = [this](const aiVector3D pAxis, const ai_real pAngle) -> string
|
||||||
|
{
|
||||||
|
string tstr = to_string(pAxis.x) + " " + to_string(pAxis.y) + " " + to_string(pAxis.z) + " " + to_string(pAngle);
|
||||||
|
|
||||||
|
AttrHelper_CommaToPoint(tstr);
|
||||||
|
|
||||||
|
return tstr;
|
||||||
|
};
|
||||||
|
|
||||||
|
aiVector3D scale, translate, rotate_axis;
|
||||||
|
ai_real rotate_angle;
|
||||||
|
|
||||||
|
transform = true;
|
||||||
|
pNode->mTransformation.Decompose(scale, rotate_axis, rotate_angle, translate);
|
||||||
|
// Check if values different from default
|
||||||
|
if((rotate_angle != 0) && (rotate_axis.Length() > 0))
|
||||||
|
attr_list.push_back({"rotation", Rotation2String(rotate_axis, rotate_angle)});
|
||||||
|
|
||||||
|
if(!scale.Equal({1, 1, 1})) attr_list.push_back({"scale", Vector2String(scale)});
|
||||||
|
if(translate.Length() > 0) attr_list.push_back({"translation", Vector2String(translate)});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin node if need.
|
||||||
|
if(transform)
|
||||||
|
NodeHelper_OpenNode("Transform", pTabLevel, false, attr_list);
|
||||||
|
else
|
||||||
|
NodeHelper_OpenNode("Group", pTabLevel);
|
||||||
|
|
||||||
|
// Export metadata
|
||||||
|
if(pNode->mMetaData != nullptr)
|
||||||
|
{
|
||||||
|
for(size_t idx_prop = 0; idx_prop < pNode->mMetaData->mNumProperties; idx_prop++)
|
||||||
|
{
|
||||||
|
const aiString* key;
|
||||||
|
const aiMetadataEntry* entry;
|
||||||
|
|
||||||
|
if(pNode->mMetaData->Get(idx_prop, key, entry))
|
||||||
|
{
|
||||||
|
switch(entry->mType)
|
||||||
|
{
|
||||||
|
case AI_BOOL:
|
||||||
|
Export_MetadataBoolean(*key, *static_cast<bool*>(entry->mData), pTabLevel + 1);
|
||||||
|
break;
|
||||||
|
case AI_DOUBLE:
|
||||||
|
Export_MetadataDouble(*key, *static_cast<double*>(entry->mData), pTabLevel + 1);
|
||||||
|
break;
|
||||||
|
case AI_FLOAT:
|
||||||
|
Export_MetadataFloat(*key, *static_cast<float*>(entry->mData), pTabLevel + 1);
|
||||||
|
break;
|
||||||
|
case AI_INT32:
|
||||||
|
Export_MetadataInteger(*key, *static_cast<int32_t*>(entry->mData), pTabLevel + 1);
|
||||||
|
break;
|
||||||
|
case AI_AISTRING:
|
||||||
|
Export_MetadataString(*key, *static_cast<aiString*>(entry->mData), pTabLevel + 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LogError("Unsupported metadata type: " + to_string(entry->mType));
|
||||||
|
break;
|
||||||
|
}// switch(entry->mType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}// if(pNode->mMetaData != nullptr)
|
||||||
|
|
||||||
|
// Export meshes.
|
||||||
|
for(size_t idx_mesh = 0; idx_mesh < pNode->mNumMeshes; idx_mesh++) Export_Mesh(pNode->mMeshes[idx_mesh], pTabLevel + 1);
|
||||||
|
// Export children.
|
||||||
|
for(size_t idx_node = 0; idx_node < pNode->mNumChildren; idx_node++) Export_Node(pNode->mChildren[idx_node], pTabLevel + 1);
|
||||||
|
|
||||||
|
// End node if need.
|
||||||
|
if(transform)
|
||||||
|
NodeHelper_CloseNode("Transform", pTabLevel);
|
||||||
|
else
|
||||||
|
NodeHelper_CloseNode("Group", pTabLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::Export_Mesh(const size_t pIdxMesh, const size_t pTabLevel)
|
||||||
|
{
|
||||||
|
const char* NodeName_IFS = "IndexedFaceSet";
|
||||||
|
const char* NodeName_Shape = "Shape";
|
||||||
|
|
||||||
|
list<SAttribute> attr_list;
|
||||||
|
aiMesh& mesh = *mScene->mMeshes[pIdxMesh];// create alias for conveniance.
|
||||||
|
|
||||||
|
// Check if mesh already defined early.
|
||||||
|
if(mDEF_Map_Mesh.find(pIdxMesh) != mDEF_Map_Mesh.end())
|
||||||
|
{
|
||||||
|
// Mesh already defined, just refer to it
|
||||||
|
attr_list.push_back({"USE", mDEF_Map_Mesh.at(pIdxMesh)});
|
||||||
|
NodeHelper_OpenNode(NodeName_Shape, pTabLevel, true, attr_list);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string mesh_name(mesh.mName.C_Str() + string("_IDX_") + to_string(pIdxMesh));// Create mesh name
|
||||||
|
|
||||||
|
// Define mesh name.
|
||||||
|
attr_list.push_back({"DEF", mesh_name});
|
||||||
|
mDEF_Map_Mesh[pIdxMesh] = mesh_name;
|
||||||
|
|
||||||
|
//
|
||||||
|
// "Shape" node.
|
||||||
|
//
|
||||||
|
NodeHelper_OpenNode(NodeName_Shape, pTabLevel, false, attr_list);
|
||||||
|
attr_list.clear();
|
||||||
|
|
||||||
|
//
|
||||||
|
// "Appearance" node.
|
||||||
|
//
|
||||||
|
Export_Material(mesh.mMaterialIndex, pTabLevel + 1);
|
||||||
|
|
||||||
|
//
|
||||||
|
// "IndexedFaceSet" node.
|
||||||
|
//
|
||||||
|
// Fill attributes which differ from default. In Assimp for colors, vertices and normals used one indices set. So, only "coordIndex" must be set.
|
||||||
|
string coordIndex;
|
||||||
|
|
||||||
|
// fill coordinates index.
|
||||||
|
coordIndex.reserve(mesh.mNumVertices * 4);// Index + space + Face delimiter
|
||||||
|
for(size_t idx_face = 0; idx_face < mesh.mNumFaces; idx_face++)
|
||||||
|
{
|
||||||
|
const aiFace& face_cur = mesh.mFaces[idx_face];
|
||||||
|
|
||||||
|
for(size_t idx_vert = 0; idx_vert < face_cur.mNumIndices; idx_vert++)
|
||||||
|
{
|
||||||
|
coordIndex.append(to_string(face_cur.mIndices[idx_vert]) + " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
coordIndex.append("-1 ");// face delimiter.
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove last space symbol.
|
||||||
|
coordIndex.resize(coordIndex.length() - 1);
|
||||||
|
attr_list.push_back({"coordIndex", coordIndex});
|
||||||
|
// create node
|
||||||
|
NodeHelper_OpenNode(NodeName_IFS, pTabLevel + 1, false, attr_list);
|
||||||
|
attr_list.clear();
|
||||||
|
// Child nodes for "IndexedFaceSet" needed when used colors, textures or normals.
|
||||||
|
string attr_value;
|
||||||
|
|
||||||
|
// Export <Coordinate>
|
||||||
|
AttrHelper_Vec3DArrToString(mesh.mVertices, mesh.mNumVertices, attr_value);
|
||||||
|
attr_list.push_back({"point", attr_value});
|
||||||
|
NodeHelper_OpenNode("Coordinate", pTabLevel + 2, true, attr_list);
|
||||||
|
attr_list.clear();
|
||||||
|
|
||||||
|
// Export <ColorRGBA>
|
||||||
|
if(mesh.HasVertexColors(0))
|
||||||
|
{
|
||||||
|
AttrHelper_Col4DArrToString(mesh.mColors[0], mesh.mNumVertices, attr_value);
|
||||||
|
attr_list.push_back({"color", attr_value});
|
||||||
|
NodeHelper_OpenNode("ColorRGBA", pTabLevel + 2, true, attr_list);
|
||||||
|
attr_list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export <TextureCoordinate>
|
||||||
|
if(mesh.HasTextureCoords(0))
|
||||||
|
{
|
||||||
|
AttrHelper_Vec3DAsVec2fArrToString(mesh.mTextureCoords[0], mesh.mNumVertices, attr_value);
|
||||||
|
attr_list.push_back({"point", attr_value});
|
||||||
|
NodeHelper_OpenNode("TextureCoordinate", pTabLevel + 2, true, attr_list);
|
||||||
|
attr_list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export <Normal>
|
||||||
|
if(mesh.HasNormals())
|
||||||
|
{
|
||||||
|
AttrHelper_Vec3DArrToString(mesh.mNormals, mesh.mNumVertices, attr_value);
|
||||||
|
attr_list.push_back({"vector", attr_value});
|
||||||
|
NodeHelper_OpenNode("Normal", pTabLevel + 2, true, attr_list);
|
||||||
|
attr_list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Close opened nodes.
|
||||||
|
//
|
||||||
|
NodeHelper_CloseNode(NodeName_IFS, pTabLevel + 1);
|
||||||
|
NodeHelper_CloseNode(NodeName_Shape, pTabLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::Export_Material(const size_t pIdxMaterial, const size_t pTabLevel)
|
||||||
|
{
|
||||||
|
const char* NodeName_A = "Appearance";
|
||||||
|
|
||||||
|
list<SAttribute> attr_list;
|
||||||
|
aiMaterial& material = *mScene->mMaterials[pIdxMaterial];// create alias for conveniance.
|
||||||
|
|
||||||
|
// Check if material already defined early.
|
||||||
|
if(mDEF_Map_Material.find(pIdxMaterial) != mDEF_Map_Material.end())
|
||||||
|
{
|
||||||
|
// Material already defined, just refer to it
|
||||||
|
attr_list.push_back({"USE", mDEF_Map_Material.at(pIdxMaterial)});
|
||||||
|
NodeHelper_OpenNode(NodeName_A, pTabLevel, true, attr_list);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string material_name(string("_IDX_") + to_string(pIdxMaterial));// Create material name
|
||||||
|
aiString ai_mat_name;
|
||||||
|
|
||||||
|
if(material.Get(AI_MATKEY_NAME, ai_mat_name) == AI_SUCCESS) material_name.insert(0, ai_mat_name.C_Str());
|
||||||
|
|
||||||
|
// Define material name.
|
||||||
|
attr_list.push_back({"DEF", material_name});
|
||||||
|
mDEF_Map_Material[pIdxMaterial] = material_name;
|
||||||
|
|
||||||
|
//
|
||||||
|
// "Appearance" node.
|
||||||
|
//
|
||||||
|
NodeHelper_OpenNode(NodeName_A, pTabLevel, false, attr_list);
|
||||||
|
attr_list.clear();
|
||||||
|
|
||||||
|
//
|
||||||
|
// "Material" node.
|
||||||
|
//
|
||||||
|
{
|
||||||
|
auto Color4ToAttrList = [&](const string& pAttrName, const aiColor4D& pAttrValue, const aiColor3D& pAttrDefaultValue)
|
||||||
|
{
|
||||||
|
string tstr;
|
||||||
|
|
||||||
|
if(aiColor3D(pAttrValue.r, pAttrValue.g, pAttrValue.b) != pAttrDefaultValue)
|
||||||
|
{
|
||||||
|
AttrHelper_Col4DArrToString(&pAttrValue, 1, tstr);
|
||||||
|
attr_list.push_back({pAttrName, tstr});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
float tvalf;
|
||||||
|
aiColor3D color3;
|
||||||
|
aiColor4D color4;
|
||||||
|
|
||||||
|
// ambientIntensity="0.2" SFFloat [inputOutput]
|
||||||
|
if(material.Get(AI_MATKEY_COLOR_AMBIENT, color3) == AI_SUCCESS)
|
||||||
|
AttrHelper_FloatToAttrList(attr_list, "ambientIntensity", (color3.r + color3.g + color3.b) / 3.0f, 0.2f);
|
||||||
|
else if(material.Get(AI_MATKEY_COLOR_AMBIENT, color4) == AI_SUCCESS)
|
||||||
|
AttrHelper_FloatToAttrList(attr_list, "ambientIntensity", (color4.r + color4.g + color4.b) / 3.0f, 0.2f);
|
||||||
|
|
||||||
|
// diffuseColor="0.8 0.8 0.8" SFColor [inputOutput]
|
||||||
|
if(material.Get(AI_MATKEY_COLOR_DIFFUSE, color3) == AI_SUCCESS)
|
||||||
|
AttrHelper_Color3ToAttrList(attr_list, "diffuseColor", color3, aiColor3D(0.8f, 0.8f, 0.8f));
|
||||||
|
else if(material.Get(AI_MATKEY_COLOR_DIFFUSE, color4) == AI_SUCCESS)
|
||||||
|
Color4ToAttrList("diffuseColor", color4, aiColor3D(0.8f, 0.8f, 0.8f));
|
||||||
|
|
||||||
|
// emissiveColor="0 0 0" SFColor [inputOutput]
|
||||||
|
if(material.Get(AI_MATKEY_COLOR_EMISSIVE, color3) == AI_SUCCESS)
|
||||||
|
AttrHelper_Color3ToAttrList(attr_list, "emissiveColor", color3, aiColor3D(0, 0, 0));
|
||||||
|
else if(material.Get(AI_MATKEY_COLOR_EMISSIVE, color4) == AI_SUCCESS)
|
||||||
|
Color4ToAttrList("emissiveColor", color4, aiColor3D(0, 0, 0));
|
||||||
|
|
||||||
|
// shininess="0.2" SFFloat [inputOutput]
|
||||||
|
if(material.Get(AI_MATKEY_SHININESS, tvalf) == AI_SUCCESS) AttrHelper_FloatToAttrList(attr_list, "shininess", tvalf, 0.2f);
|
||||||
|
|
||||||
|
// specularColor="0 0 0" SFColor [inputOutput]
|
||||||
|
if(material.Get(AI_MATKEY_COLOR_SPECULAR, color3) == AI_SUCCESS)
|
||||||
|
AttrHelper_Color3ToAttrList(attr_list, "specularColor", color3, aiColor3D(0, 0, 0));
|
||||||
|
else if(material.Get(AI_MATKEY_COLOR_SPECULAR, color4) == AI_SUCCESS)
|
||||||
|
Color4ToAttrList("specularColor", color4, aiColor3D(0, 0, 0));
|
||||||
|
|
||||||
|
// transparency="0" SFFloat [inputOutput]
|
||||||
|
if(material.Get(AI_MATKEY_OPACITY, tvalf) == AI_SUCCESS)
|
||||||
|
{
|
||||||
|
if(tvalf > 1) tvalf = 1;
|
||||||
|
|
||||||
|
tvalf = 1.0f - tvalf;
|
||||||
|
AttrHelper_FloatToAttrList(attr_list, "transparency", tvalf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeHelper_OpenNode("Material", pTabLevel + 1, true, attr_list);
|
||||||
|
attr_list.clear();
|
||||||
|
}// "Material" node. END.
|
||||||
|
|
||||||
|
//
|
||||||
|
// "ImageTexture" node.
|
||||||
|
//
|
||||||
|
{
|
||||||
|
auto RepeatToAttrList = [&](const string& pAttrName, const bool pAttrValue)
|
||||||
|
{
|
||||||
|
if(!pAttrValue) attr_list.push_back({pAttrName, "false"});
|
||||||
|
};
|
||||||
|
|
||||||
|
bool tvalb;
|
||||||
|
aiString tstring;
|
||||||
|
|
||||||
|
// url="" MFString
|
||||||
|
if(material.Get(AI_MATKEY_TEXTURE_DIFFUSE(0), tstring) == AI_SUCCESS)
|
||||||
|
{
|
||||||
|
if(strncmp(tstring.C_Str(), AI_EMBEDDED_TEXNAME_PREFIX, strlen(AI_EMBEDDED_TEXNAME_PREFIX)) == 0)
|
||||||
|
LogError("Embedded texture is not supported");
|
||||||
|
else
|
||||||
|
attr_list.push_back({"url", string("\"") + tstring.C_Str() + "\""});
|
||||||
|
}
|
||||||
|
|
||||||
|
// repeatS="true" SFBool
|
||||||
|
if(material.Get(AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0), tvalb) == AI_SUCCESS) RepeatToAttrList("repeatS", tvalb);
|
||||||
|
|
||||||
|
// repeatT="true" SFBool
|
||||||
|
if(material.Get(AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0), tvalb) == AI_SUCCESS) RepeatToAttrList("repeatT", tvalb);
|
||||||
|
|
||||||
|
NodeHelper_OpenNode("ImageTexture", pTabLevel + 1, true, attr_list);
|
||||||
|
attr_list.clear();
|
||||||
|
}// "ImageTexture" node. END.
|
||||||
|
|
||||||
|
//
|
||||||
|
// "TextureTransform" node.
|
||||||
|
//
|
||||||
|
{
|
||||||
|
auto Vec2ToAttrList = [&](const string& pAttrName, const aiVector2D& pAttrValue, const aiVector2D& pAttrDefaultValue)
|
||||||
|
{
|
||||||
|
string tstr;
|
||||||
|
|
||||||
|
if(pAttrValue != pAttrDefaultValue)
|
||||||
|
{
|
||||||
|
AttrHelper_Vec2DArrToString(&pAttrValue, 1, tstr);
|
||||||
|
attr_list.push_back({pAttrName, tstr});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
aiUVTransform transform;
|
||||||
|
|
||||||
|
if(material.Get(AI_MATKEY_UVTRANSFORM_DIFFUSE(0), transform) == AI_SUCCESS)
|
||||||
|
{
|
||||||
|
Vec2ToAttrList("translation", transform.mTranslation, aiVector2D(0, 0));
|
||||||
|
AttrHelper_FloatToAttrList(attr_list, "rotation", transform.mRotation, 0);
|
||||||
|
Vec2ToAttrList("scale", transform.mScaling, aiVector2D(1, 1));
|
||||||
|
|
||||||
|
NodeHelper_OpenNode("TextureTransform", pTabLevel + 1, true, attr_list);
|
||||||
|
attr_list.clear();
|
||||||
|
}
|
||||||
|
}// "TextureTransform" node. END.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Close opened nodes.
|
||||||
|
//
|
||||||
|
NodeHelper_CloseNode(NodeName_A, pTabLevel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
|
||||||
|
{
|
||||||
|
list<SAttribute> attr_list;
|
||||||
|
|
||||||
|
attr_list.push_back({"name", pKey.C_Str()});
|
||||||
|
attr_list.push_back({"value", pValue ? "true" : "false"});
|
||||||
|
NodeHelper_OpenNode("MetadataBoolean", pTabLevel, true, attr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::Export_MetadataDouble(const aiString& pKey, const double pValue, const size_t pTabLevel)
|
||||||
|
{
|
||||||
|
list<SAttribute> attr_list;
|
||||||
|
|
||||||
|
attr_list.push_back({"name", pKey.C_Str()});
|
||||||
|
attr_list.push_back({"value", to_string(pValue)});
|
||||||
|
NodeHelper_OpenNode("MetadataDouble", pTabLevel, true, attr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::Export_MetadataFloat(const aiString& pKey, const float pValue, const size_t pTabLevel)
|
||||||
|
{
|
||||||
|
list<SAttribute> attr_list;
|
||||||
|
|
||||||
|
attr_list.push_back({"name", pKey.C_Str()});
|
||||||
|
attr_list.push_back({"value", to_string(pValue)});
|
||||||
|
NodeHelper_OpenNode("MetadataFloat", pTabLevel, true, attr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::Export_MetadataInteger(const aiString& pKey, const int32_t pValue, const size_t pTabLevel)
|
||||||
|
{
|
||||||
|
list<SAttribute> attr_list;
|
||||||
|
|
||||||
|
attr_list.push_back({"name", pKey.C_Str()});
|
||||||
|
attr_list.push_back({"value", to_string(pValue)});
|
||||||
|
NodeHelper_OpenNode("MetadataInteger", pTabLevel, true, attr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DExporter::Export_MetadataString(const aiString& pKey, const aiString& pValue, const size_t pTabLevel)
|
||||||
|
{
|
||||||
|
list<SAttribute> attr_list;
|
||||||
|
|
||||||
|
attr_list.push_back({"name", pKey.C_Str()});
|
||||||
|
attr_list.push_back({"value", pValue.C_Str()});
|
||||||
|
NodeHelper_OpenNode("MetadataString", pTabLevel, true, attr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool X3DExporter::CheckAndExport_Light(const aiNode& pNode, const size_t pTabLevel)
|
||||||
|
{
|
||||||
|
list<SAttribute> attr_list;
|
||||||
|
|
||||||
|
auto Vec3ToAttrList = [&](const string& pAttrName, const aiVector3D& pAttrValue, const aiVector3D& pAttrDefaultValue)
|
||||||
|
{
|
||||||
|
string tstr;
|
||||||
|
|
||||||
|
if(pAttrValue != pAttrDefaultValue)
|
||||||
|
{
|
||||||
|
AttrHelper_Vec3DArrToString(&pAttrValue, 1, tstr);
|
||||||
|
attr_list.push_back({pAttrName, tstr});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t idx_light;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
// Name of the light source can not be empty.
|
||||||
|
if(pNode.mName.length == 0) return false;
|
||||||
|
|
||||||
|
// search for light with name like node has.
|
||||||
|
for(idx_light = 0; mScene->mNumLights; idx_light++)
|
||||||
|
{
|
||||||
|
if(pNode.mName == mScene->mLights[idx_light]->mName)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found) return false;
|
||||||
|
|
||||||
|
// Light source is found.
|
||||||
|
const aiLight& light = *mScene->mLights[idx_light];// Alias for conveniance.
|
||||||
|
|
||||||
|
aiMatrix4x4 trafo_mat = Matrix_GlobalToCurrent(pNode).Inverse();
|
||||||
|
|
||||||
|
attr_list.push_back({"DEF", light.mName.C_Str()});
|
||||||
|
attr_list.push_back({"global", "true"});// "false" is not supported.
|
||||||
|
// ambientIntensity="0" SFFloat [inputOutput]
|
||||||
|
AttrHelper_FloatToAttrList(attr_list, "ambientIntensity", aiVector3D(light.mColorAmbient.r, light.mColorAmbient.g, light.mColorAmbient.b).Length(), 0);
|
||||||
|
// color="1 1 1" SFColor [inputOutput]
|
||||||
|
AttrHelper_Color3ToAttrList(attr_list, "color", light.mColorDiffuse, aiColor3D(1, 1, 1));
|
||||||
|
|
||||||
|
switch(light.mType)
|
||||||
|
{
|
||||||
|
case aiLightSource_DIRECTIONAL:
|
||||||
|
{
|
||||||
|
aiVector3D direction = trafo_mat * light.mDirection;
|
||||||
|
|
||||||
|
Vec3ToAttrList("direction", direction, aiVector3D(0, 0, -1));
|
||||||
|
NodeHelper_OpenNode("DirectionalLight", pTabLevel, true, attr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case aiLightSource_POINT:
|
||||||
|
{
|
||||||
|
aiVector3D attenuation(light.mAttenuationConstant, light.mAttenuationLinear, light.mAttenuationQuadratic);
|
||||||
|
aiVector3D location = trafo_mat * light.mPosition;
|
||||||
|
|
||||||
|
Vec3ToAttrList("attenuation", attenuation, aiVector3D(1, 0, 0));
|
||||||
|
Vec3ToAttrList("location", location, aiVector3D(0, 0, 0));
|
||||||
|
NodeHelper_OpenNode("PointLight", pTabLevel, true, attr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case aiLightSource_SPOT:
|
||||||
|
{
|
||||||
|
aiVector3D attenuation(light.mAttenuationConstant, light.mAttenuationLinear, light.mAttenuationQuadratic);
|
||||||
|
aiVector3D location = trafo_mat * light.mPosition;
|
||||||
|
aiVector3D direction = trafo_mat * light.mDirection;
|
||||||
|
|
||||||
|
Vec3ToAttrList("attenuation", attenuation, aiVector3D(1, 0, 0));
|
||||||
|
Vec3ToAttrList("location", location, aiVector3D(0, 0, 0));
|
||||||
|
Vec3ToAttrList("direction", direction, aiVector3D(0, 0, -1));
|
||||||
|
AttrHelper_FloatToAttrList(attr_list, "beamWidth", light.mAngleInnerCone, 0.7854f);
|
||||||
|
AttrHelper_FloatToAttrList(attr_list, "cutOffAngle", light.mAngleOuterCone, 1.570796f);
|
||||||
|
NodeHelper_OpenNode("SpotLight", pTabLevel, true, attr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw DeadlyExportError("Unknown light type: " + to_string(light.mType));
|
||||||
|
}// switch(light.mType)
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
X3DExporter::X3DExporter(const char* pFileName, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
|
: mScene(pScene)
|
||||||
|
{
|
||||||
|
list<SAttribute> attr_list;
|
||||||
|
|
||||||
|
mOutFile = pIOSystem->Open(pFileName, "wt");
|
||||||
|
if(mOutFile == nullptr) throw DeadlyExportError("Could not open output .x3d file: " + string(pFileName));
|
||||||
|
|
||||||
|
// Begin document
|
||||||
|
XML_Write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||||
|
XML_Write("<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.3//EN\" \"http://www.web3d.org/specifications/x3d-3.3.dtd\">\n");
|
||||||
|
// Root node
|
||||||
|
attr_list.push_back({"profile", "Interchange"});
|
||||||
|
attr_list.push_back({"version", "3.3"});
|
||||||
|
attr_list.push_back({"xmlns:xsd", "http://www.w3.org/2001/XMLSchema-instance"});
|
||||||
|
attr_list.push_back({"xsd:noNamespaceSchemaLocation", "http://www.web3d.org/specifications/x3d-3.3.xsd"});
|
||||||
|
NodeHelper_OpenNode("X3D", 0, false, attr_list);
|
||||||
|
attr_list.clear();
|
||||||
|
// <head>: meta data.
|
||||||
|
NodeHelper_OpenNode("head", 1);
|
||||||
|
XML_Write(mIndentationString + "<!-- All \"meta\" from this section tou will found in <Scene> node as MetadataString nodes. -->\n");
|
||||||
|
NodeHelper_CloseNode("head", 1);
|
||||||
|
// Scene node.
|
||||||
|
NodeHelper_OpenNode("Scene", 1);
|
||||||
|
Export_Node(mScene->mRootNode, 2);
|
||||||
|
NodeHelper_CloseNode("Scene", 1);
|
||||||
|
// Close Root node.
|
||||||
|
NodeHelper_CloseNode("X3D", 0);
|
||||||
|
// Cleanup
|
||||||
|
pIOSystem->Close(mOutFile);
|
||||||
|
mOutFile = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}// namespace Assimp
|
||||||
|
|
||||||
|
#endif // ASSIMP_BUILD_NO_X3D_EXPORTER
|
||||||
|
#endif // ASSIMP_BUILD_NO_EXPORT
|
|
@ -0,0 +1,235 @@
|
||||||
|
/// \file X3DExporter.hpp
|
||||||
|
/// \brief X3D-format files exporter for Assimp.
|
||||||
|
/// \date 2016
|
||||||
|
/// \author smal.root@gmail.com
|
||||||
|
// Thanks to acorn89 for support.
|
||||||
|
|
||||||
|
#ifndef INCLUDED_AI_X3D_EXPORTER_H
|
||||||
|
#define INCLUDED_AI_X3D_EXPORTER_H
|
||||||
|
|
||||||
|
// Header files, Assimp.
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
#include <assimp/Exporter.hpp>
|
||||||
|
#include <assimp/material.h>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
|
// Header files, stdlib.
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \class X3DExporter
|
||||||
|
/// Class which export aiScene to X3D file.
|
||||||
|
///
|
||||||
|
/// Limitations.
|
||||||
|
///
|
||||||
|
/// Pay attention that X3D is format for interactive graphic and simulations for web browsers. aiScene can not contain all features of the X3D format.
|
||||||
|
/// Also, aiScene contain rasterized-like data. For example, X3D can describe circle all cylinder with one tag, but aiScene contain result of tesselation:
|
||||||
|
/// vertices, faces etc. Yes, you can use algorithm for detecting figures or shapes, but thats not good idea at all.
|
||||||
|
///
|
||||||
|
/// Supported nodes:
|
||||||
|
/// Core component:
|
||||||
|
/// "MetadataBoolean", "MetadataDouble", "MetadataFloat", "MetadataInteger", "MetadataSet", "MetadataString"
|
||||||
|
/// Geometry3D component:
|
||||||
|
/// "IndexedFaceSet"
|
||||||
|
/// Grouping component:
|
||||||
|
/// "Group", "Transform"
|
||||||
|
/// Lighting component:
|
||||||
|
/// "DirectionalLight", "PointLight", "SpotLight"
|
||||||
|
/// Rendering component:
|
||||||
|
/// "ColorRGBA", "Coordinate", "Normal"
|
||||||
|
/// Shape component:
|
||||||
|
/// "Shape", "Appearance", "Material"
|
||||||
|
/// Texturing component:
|
||||||
|
/// "ImageTexture", "TextureCoordinate", "TextureTransform"
|
||||||
|
///
|
||||||
|
class X3DExporter
|
||||||
|
{
|
||||||
|
/***********************************************/
|
||||||
|
/******************** Types ********************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
struct SAttribute
|
||||||
|
{
|
||||||
|
const std::string Name;
|
||||||
|
const std::string Value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/****************** Constants ******************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
const aiScene* const mScene;
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/****************** Variables ******************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
IOStream* mOutFile;
|
||||||
|
std::map<size_t, std::string> mDEF_Map_Mesh;
|
||||||
|
std::map<size_t, std::string> mDEF_Map_Material;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::string mIndentationString;
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/****************** Functions ******************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
/// \fn void IndentationStringSet(const size_t pNewLevel)
|
||||||
|
/// Set value of the indentation string.
|
||||||
|
/// \param [in] pNewLevel - new level of the indentation.
|
||||||
|
void IndentationStringSet(const size_t pNewLevel);
|
||||||
|
|
||||||
|
/// \fn void XML_Write(const std::string& pData)
|
||||||
|
/// Write data to XML-file.
|
||||||
|
/// \param [in] pData - reference to string which must be written.
|
||||||
|
void XML_Write(const std::string& pData);
|
||||||
|
|
||||||
|
/// \fn aiMatrix4x4 Matrix_GlobalToCurrent(const aiNode& pNode) const
|
||||||
|
/// Calculate transformation matrix for transformation from global coordinate system to pointed aiNode.
|
||||||
|
/// \param [in] pNode - reference to local node.
|
||||||
|
/// \return calculated matrix.
|
||||||
|
aiMatrix4x4 Matrix_GlobalToCurrent(const aiNode& pNode) const;
|
||||||
|
|
||||||
|
/// \fn void AttrHelper_CommaToPoint(std::string& pStringWithComma)
|
||||||
|
/// Convert commas in string to points. Thats need because "std::to_string" result depend on locale (regional settings).
|
||||||
|
/// \param [in, out] pStringWithComma - reference to string, which must be modified.
|
||||||
|
void AttrHelper_CommaToPoint(std::string& pStringWithComma) { for(char& c: pStringWithComma) { if(c == ',') c = '.'; } }
|
||||||
|
|
||||||
|
/// \fn void AttrHelper_FloatToString(const float pValue, std::string& pTargetString)
|
||||||
|
/// Converts float to string.
|
||||||
|
/// \param [in] pValue - value for converting.
|
||||||
|
/// \param [out] pTargetString - reference to string where result will be placed. Will be cleared before using.
|
||||||
|
void AttrHelper_FloatToString(const float pValue, std::string& pTargetString);
|
||||||
|
|
||||||
|
/// \fn void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
|
||||||
|
/// Converts array of vectors to string.
|
||||||
|
/// \param [in] pArray - pointer to array of vectors.
|
||||||
|
/// \param [in] pArray_Size - count of elements in array.
|
||||||
|
/// \param [out] pTargetString - reference to string where result will be placed. Will be cleared before using.
|
||||||
|
void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString);
|
||||||
|
|
||||||
|
/// \fn void AttrHelper_Vec2DArrToString(const aiVector2D* pArray, const size_t pArray_Size, std::string& pTargetString)
|
||||||
|
/// \overload void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
|
||||||
|
void AttrHelper_Vec2DArrToString(const aiVector2D* pArray, const size_t pArray_Size, std::string& pTargetString);
|
||||||
|
|
||||||
|
/// \fn void AttrHelper_Vec3DAsVec2fArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
|
||||||
|
/// \overload void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
|
||||||
|
/// Only x, y is used from aiVector3D.
|
||||||
|
void AttrHelper_Vec3DAsVec2fArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString);
|
||||||
|
|
||||||
|
/// \fn void AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, std::string& pTargetString)
|
||||||
|
/// \overload void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
|
||||||
|
/// Converts array of colors to string.
|
||||||
|
void AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, std::string& pTargetString);
|
||||||
|
|
||||||
|
/// \fn void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString)
|
||||||
|
/// \overload void AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, std::string& pTargetString)
|
||||||
|
/// Converts array of colors to string.
|
||||||
|
void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString);
|
||||||
|
|
||||||
|
/// \fn void AttrHelper_FloatToAttrList(std::list<SAttribute> pList, const std::string& pName, const float pValue, const float pDefaultValue)
|
||||||
|
/// \overload void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString)
|
||||||
|
void AttrHelper_FloatToAttrList(std::list<SAttribute> pList, const std::string& pName, const float pValue, const float pDefaultValue);
|
||||||
|
|
||||||
|
/// \fn void AttrHelper_Color3ToAttrList(std::list<SAttribute> pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue)
|
||||||
|
/// Add attribute to list if value not equal to default.
|
||||||
|
/// \param [in] pList - target list of the attributes.
|
||||||
|
/// \param [in] pName - name of new attribute.
|
||||||
|
/// \param [in] pValue - value of the new attribute.
|
||||||
|
/// \param [in] pDefaultValue - default value for checking: if pValue is equal to pDefaultValue then attribute will not be added.
|
||||||
|
void AttrHelper_Color3ToAttrList(std::list<SAttribute> pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue);
|
||||||
|
|
||||||
|
/// \fn void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList)
|
||||||
|
/// Begin new XML-node element.
|
||||||
|
/// \param [in] pNodeName - name of the element.
|
||||||
|
/// \param [in] pTabLevel - indentation level.
|
||||||
|
/// \param [in] pEmtyElement - if true then empty element will be created.
|
||||||
|
/// \param [in] pAttrList - list of the attributes for element.
|
||||||
|
void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList);
|
||||||
|
|
||||||
|
/// \fn void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement = false)
|
||||||
|
/// \overload void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList)
|
||||||
|
void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement = false);
|
||||||
|
|
||||||
|
/// \fn void NodeHelper_CloseNode(const std::string& pNodeName, const size_t pTabLevel)
|
||||||
|
/// End XML-node element.
|
||||||
|
/// \param [in] pNodeName - name of the element.
|
||||||
|
/// \param [in] pTabLevel - indentation level.
|
||||||
|
void NodeHelper_CloseNode(const std::string& pNodeName, const size_t pTabLevel);
|
||||||
|
|
||||||
|
/// \fn void Export_Node(const aiNode* pNode, const size_t pTabLevel)
|
||||||
|
/// Export data from scene to XML-file: aiNode.
|
||||||
|
/// \param [in] pNode - source aiNode.
|
||||||
|
/// \param [in] pTabLevel - indentation level.
|
||||||
|
void Export_Node(const aiNode* pNode, const size_t pTabLevel);
|
||||||
|
|
||||||
|
/// \fn void Export_Mesh(const size_t pIdxMesh, const size_t pTabLevel)
|
||||||
|
/// Export data from scene to XML-file: aiMesh.
|
||||||
|
/// \param [in] pMesh - index of the source aiMesh.
|
||||||
|
/// \param [in] pTabLevel - indentation level.
|
||||||
|
void Export_Mesh(const size_t pIdxMesh, const size_t pTabLevel);
|
||||||
|
|
||||||
|
/// \fn void Export_Material(const size_t pIdxMaterial, const size_t pTabLevel)
|
||||||
|
/// Export data from scene to XML-file: aiMaterial.
|
||||||
|
/// \param [in] pIdxMaterial - index of the source aiMaterial.
|
||||||
|
/// \param [in] pTabLevel - indentation level.
|
||||||
|
void Export_Material(const size_t pIdxMaterial, const size_t pTabLevel);
|
||||||
|
|
||||||
|
/// \fn void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
|
||||||
|
/// Export data from scene to XML-file: aiMetadata.
|
||||||
|
/// \param [in] pKey - source data: value of the metadata key.
|
||||||
|
/// \param [in] pValue - source data: value of the metadata value.
|
||||||
|
/// \param [in] pTabLevel - indentation level.
|
||||||
|
void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel);
|
||||||
|
|
||||||
|
/// \fn void Export_MetadataDouble(const aiString& pKey, const double pValue, const size_t pTabLevel)
|
||||||
|
/// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
|
||||||
|
void Export_MetadataDouble(const aiString& pKey, const double pValue, const size_t pTabLevel);
|
||||||
|
|
||||||
|
/// \fn void Export_MetadataFloat(const aiString& pKey, const float pValue, const size_t pTabLevel)
|
||||||
|
/// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
|
||||||
|
void Export_MetadataFloat(const aiString& pKey, const float pValue, const size_t pTabLevel);
|
||||||
|
|
||||||
|
/// \fn void Export_MetadataInteger(const aiString& pKey, const int32_t pValue, const size_t pTabLevel)
|
||||||
|
/// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
|
||||||
|
void Export_MetadataInteger(const aiString& pKey, const int32_t pValue, const size_t pTabLevel);
|
||||||
|
|
||||||
|
/// \fn void Export_MetadataString(const aiString& pKey, const aiString& pValue, const size_t pTabLevel)
|
||||||
|
/// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
|
||||||
|
void Export_MetadataString(const aiString& pKey, const aiString& pValue, const size_t pTabLevel);
|
||||||
|
|
||||||
|
/// \fn bool CheckAndExport_Light(const aiNode& pNode, const size_t pTabLevel)
|
||||||
|
/// Check if node point to light source. If yes then export light source.
|
||||||
|
/// \param [in] pNode - reference to node for checking.
|
||||||
|
/// \param [in] pTabLevel - indentation level.
|
||||||
|
/// \return true - if node assigned with light and it was exported, else - return false.
|
||||||
|
bool CheckAndExport_Light(const aiNode& pNode, const size_t pTabLevel);
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/************** Functions: LOG set *************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
/// \fn void LogError(const std::string& pMessage)
|
||||||
|
/// Short variant for calling \ref DefaultLogger::get()->error()
|
||||||
|
void LogError(const std::string& pMessage) { DefaultLogger::get()->error(pMessage); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \fn X3DExporter()
|
||||||
|
/// Default constructor.
|
||||||
|
X3DExporter(const char* pFileName, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties);
|
||||||
|
|
||||||
|
/// \fn ~X3DExporter()
|
||||||
|
/// Default destructor.
|
||||||
|
~X3DExporter() {}
|
||||||
|
|
||||||
|
};// class X3DExporter
|
||||||
|
|
||||||
|
}// namespace Assimp
|
||||||
|
|
||||||
|
#endif // INCLUDED_AI_X3D_EXPORTER_H
|
|
@ -1418,7 +1418,6 @@ void X3DImporter::ParseFile(const std::string& pFile, IOSystem* pIOHandler)
|
||||||
|
|
||||||
void X3DImporter::ParseNode_Root()
|
void X3DImporter::ParseNode_Root()
|
||||||
{
|
{
|
||||||
LogInfo("ParseNode_Root b");
|
|
||||||
// search for root tag <X3D>
|
// search for root tag <X3D>
|
||||||
if ( !XML_SearchNode( "X3D" ) )
|
if ( !XML_SearchNode( "X3D" ) )
|
||||||
{
|
{
|
||||||
|
@ -1427,7 +1426,6 @@ void X3DImporter::ParseNode_Root()
|
||||||
|
|
||||||
ParseHelper_Group_Begin();// create root node element.
|
ParseHelper_Group_Begin();// create root node element.
|
||||||
// parse other contents
|
// parse other contents
|
||||||
LogInfo("ParseNode_Root. read loop");
|
|
||||||
while(mReader->read())
|
while(mReader->read())
|
||||||
{
|
{
|
||||||
if ( mReader->getNodeType() != irr::io::EXN_ELEMENT )
|
if ( mReader->getNodeType() != irr::io::EXN_ELEMENT )
|
||||||
|
@ -1442,11 +1440,9 @@ void X3DImporter::ParseNode_Root()
|
||||||
else
|
else
|
||||||
XML_CheckNode_SkipUnsupported("Root");
|
XML_CheckNode_SkipUnsupported("Root");
|
||||||
}
|
}
|
||||||
LogInfo("ParseNode_Root. end loop");
|
|
||||||
|
|
||||||
// exit from root node element.
|
// exit from root node element.
|
||||||
ParseHelper_Node_Exit();
|
ParseHelper_Node_Exit();
|
||||||
LogInfo("ParseNode_Root e");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void X3DImporter::ParseNode_Head()
|
void X3DImporter::ParseNode_Head()
|
||||||
|
|
|
@ -397,12 +397,6 @@ private:
|
||||||
/// Short variant for calling \ref DefaultLogger::get()->info()
|
/// Short variant for calling \ref DefaultLogger::get()->info()
|
||||||
void LogInfo(const std::string& pMessage) { DefaultLogger::get()->info(pMessage); }
|
void LogInfo(const std::string& pMessage) { DefaultLogger::get()->info(pMessage); }
|
||||||
|
|
||||||
/// Short variant for calling \ref DefaultLogger::get()->warn()
|
|
||||||
void LogWarning(const std::string& pMessage) { DefaultLogger::get()->warn(pMessage); }
|
|
||||||
|
|
||||||
/// Short variant for calling \ref DefaultLogger::get()->error()
|
|
||||||
void LogError(const std::string& pMessage) { DefaultLogger::get()->error(pMessage); }
|
|
||||||
|
|
||||||
/***********************************************/
|
/***********************************************/
|
||||||
/************** Functions: XML set *************/
|
/************** Functions: XML set *************/
|
||||||
/***********************************************/
|
/***********************************************/
|
||||||
|
|
|
@ -780,24 +780,27 @@ void X3DImporter::Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pN
|
||||||
}
|
}
|
||||||
else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaDouble)
|
else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaDouble)
|
||||||
{
|
{
|
||||||
// at this case also converting double to float.
|
if(((CX3DImporter_NodeElement_MetaDouble*)cur_meta)->Value.size() > 0)
|
||||||
if(((CX3DImporter_NodeElement_MetaBoolean*)cur_meta)->Value.size() > 0)
|
|
||||||
pSceneNode.mMetaData->Set(meta_idx, cur_meta->Name, (float)*(((CX3DImporter_NodeElement_MetaDouble*)cur_meta)->Value.begin()));
|
pSceneNode.mMetaData->Set(meta_idx, cur_meta->Name, (float)*(((CX3DImporter_NodeElement_MetaDouble*)cur_meta)->Value.begin()));
|
||||||
}
|
}
|
||||||
else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaFloat)
|
else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaFloat)
|
||||||
{
|
{
|
||||||
if(((CX3DImporter_NodeElement_MetaBoolean*)cur_meta)->Value.size() > 0)
|
if(((CX3DImporter_NodeElement_MetaFloat*)cur_meta)->Value.size() > 0)
|
||||||
pSceneNode.mMetaData->Set(meta_idx, cur_meta->Name, *(((CX3DImporter_NodeElement_MetaFloat*)cur_meta)->Value.begin()));
|
pSceneNode.mMetaData->Set(meta_idx, cur_meta->Name, *(((CX3DImporter_NodeElement_MetaFloat*)cur_meta)->Value.begin()));
|
||||||
}
|
}
|
||||||
else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaInteger)
|
else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaInteger)
|
||||||
{
|
{
|
||||||
if(((CX3DImporter_NodeElement_MetaBoolean*)cur_meta)->Value.size() > 0)
|
if(((CX3DImporter_NodeElement_MetaInteger*)cur_meta)->Value.size() > 0)
|
||||||
pSceneNode.mMetaData->Set(meta_idx, cur_meta->Name, *(((CX3DImporter_NodeElement_MetaInteger*)cur_meta)->Value.begin()));
|
pSceneNode.mMetaData->Set(meta_idx, cur_meta->Name, *(((CX3DImporter_NodeElement_MetaInteger*)cur_meta)->Value.begin()));
|
||||||
}
|
}
|
||||||
else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaString)
|
else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaString)
|
||||||
{
|
{
|
||||||
if(((CX3DImporter_NodeElement_MetaBoolean*)cur_meta)->Value.size() > 0)
|
if(((CX3DImporter_NodeElement_MetaString*)cur_meta)->Value.size() > 0)
|
||||||
pSceneNode.mMetaData->Set(meta_idx, cur_meta->Name, ((CX3DImporter_NodeElement_MetaString*)cur_meta)->Value.begin()->data());
|
{
|
||||||
|
aiString tstr(((CX3DImporter_NodeElement_MetaString*)cur_meta)->Value.begin()->data());
|
||||||
|
|
||||||
|
pSceneNode.mMetaData->Set(meta_idx, cur_meta->Name, tstr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -941,7 +941,6 @@ void X3DImporter::ParseNode_Rendering_Normal()
|
||||||
std::string use, def;
|
std::string use, def;
|
||||||
std::list<aiVector3D> vector;
|
std::list<aiVector3D> vector;
|
||||||
CX3DImporter_NodeElement* ne;
|
CX3DImporter_NodeElement* ne;
|
||||||
LogInfo("TRACE: scene rendering Normal b");
|
|
||||||
|
|
||||||
MACRO_ATTRREAD_LOOPBEG;
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
|
MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
|
||||||
|
@ -968,7 +967,6 @@ LogInfo("TRACE: scene rendering Normal b");
|
||||||
|
|
||||||
NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
|
NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
|
||||||
}// if(!use.empty()) else
|
}// if(!use.empty()) else
|
||||||
LogInfo("TRACE: scene rendering Normal e");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}// namespace Assimp
|
}// namespace Assimp
|
||||||
|
|
|
@ -128,6 +128,7 @@ namespace glTF
|
||||||
struct BufferView; // here due to cross-reference
|
struct BufferView; // here due to cross-reference
|
||||||
struct Texture;
|
struct Texture;
|
||||||
struct Light;
|
struct Light;
|
||||||
|
struct Skin;
|
||||||
|
|
||||||
|
|
||||||
// Vec/matrix types, as raw float arrays
|
// Vec/matrix types, as raw float arrays
|
||||||
|
@ -455,25 +456,6 @@ namespace glTF
|
||||||
void Read(Value& obj, Asset& r);
|
void Read(Value& obj, Asset& r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Animation : public Object
|
|
||||||
{
|
|
||||||
struct Channel
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Target
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Sampler
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
//! A buffer points to binary geometry, animation, or skins.
|
//! A buffer points to binary geometry, animation, or skins.
|
||||||
struct Buffer : public Object
|
struct Buffer : public Object
|
||||||
{
|
{
|
||||||
|
@ -825,6 +807,10 @@ namespace glTF
|
||||||
Ref<Camera> camera;
|
Ref<Camera> camera;
|
||||||
Ref<Light> light;
|
Ref<Light> light;
|
||||||
|
|
||||||
|
std::vector< Ref<Node> > skeletons; //!< The ID of skeleton nodes. Each of which is the root of a node hierarchy.
|
||||||
|
Ref<Skin> skin; //!< The ID of the skin referenced by this node.
|
||||||
|
std::string jointName; //!< Name used when this node is a joint in a skin.
|
||||||
|
|
||||||
Node() {}
|
Node() {}
|
||||||
void Read(Value& obj, Asset& r);
|
void Read(Value& obj, Asset& r);
|
||||||
};
|
};
|
||||||
|
@ -864,6 +850,11 @@ namespace glTF
|
||||||
|
|
||||||
struct Skin : public Object
|
struct Skin : public Object
|
||||||
{
|
{
|
||||||
|
Nullable<mat4> bindShapeMatrix; //!< Floating-point 4x4 transformation matrix stored in column-major order.
|
||||||
|
Ref<Accessor> inverseBindMatrices; //!< The ID of the accessor containing the floating-point 4x4 inverse-bind matrices.
|
||||||
|
std::vector<std::string/*Ref<Node>*/> jointNames; //!< Joint names of the joints (nodes with a jointName property) in this skin.
|
||||||
|
std::string name; //!< The user-defined name of this object.
|
||||||
|
|
||||||
Skin() {}
|
Skin() {}
|
||||||
void Read(Value& obj, Asset& r);
|
void Read(Value& obj, Asset& r);
|
||||||
};
|
};
|
||||||
|
@ -934,6 +925,44 @@ namespace glTF
|
||||||
void SetDefaults();
|
void SetDefaults();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Animation : public Object
|
||||||
|
{
|
||||||
|
struct AnimSampler {
|
||||||
|
std::string id; //!< The ID of this sampler.
|
||||||
|
std::string input; //!< The ID of a parameter in this animation to use as key-frame input.
|
||||||
|
std::string interpolation; //!< Type of interpolation algorithm to use between key-frames.
|
||||||
|
std::string output; //!< The ID of a parameter in this animation to use as key-frame output.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AnimChannel {
|
||||||
|
std::string sampler; //!< The ID of one sampler present in the containing animation's samplers property.
|
||||||
|
|
||||||
|
struct AnimTarget {
|
||||||
|
Ref<Node> id; //!< The ID of the node to animate.
|
||||||
|
std::string path; //!< The name of property of the node to animate ("translation", "rotation", or "scale").
|
||||||
|
} target;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AnimParameters {
|
||||||
|
Ref<Accessor> TIME; //!< Accessor reference to a buffer storing a array of floating point scalar values.
|
||||||
|
Ref<Accessor> rotation; //!< Accessor reference to a buffer storing a array of four-component floating-point vectors.
|
||||||
|
Ref<Accessor> scale; //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
|
||||||
|
Ref<Accessor> translation; //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
|
||||||
|
};
|
||||||
|
|
||||||
|
// AnimChannel Channels[3]; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
|
||||||
|
// AnimParameters Parameters; //!< The samplers that interpolate between the key-frames.
|
||||||
|
// AnimSampler Samplers[3]; //!< The parameterized inputs representing the key-frame data.
|
||||||
|
|
||||||
|
std::vector<AnimChannel> Channels; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
|
||||||
|
AnimParameters Parameters; //!< The samplers that interpolate between the key-frames.
|
||||||
|
std::vector<AnimSampler> Samplers; //!< The parameterized inputs representing the key-frame data.
|
||||||
|
|
||||||
|
Animation() {}
|
||||||
|
void Read(Value& obj, Asset& r);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//! Base class for LazyDict that acts as an interface
|
//! Base class for LazyDict that acts as an interface
|
||||||
class LazyDictBase
|
class LazyDictBase
|
||||||
{
|
{
|
||||||
|
@ -966,7 +995,7 @@ namespace glTF
|
||||||
typedef typename std::gltf_unordered_map< std::string, unsigned int > Dict;
|
typedef typename std::gltf_unordered_map< std::string, unsigned int > Dict;
|
||||||
|
|
||||||
std::vector<T*> mObjs; //! The read objects
|
std::vector<T*> mObjs; //! The read objects
|
||||||
Dict mObjsById; //! The read objects accesible by id
|
Dict mObjsById; //! The read objects accessible by id
|
||||||
const char* mDictId; //! ID of the dictionary object
|
const char* mDictId; //! ID of the dictionary object
|
||||||
const char* mExtId; //! ID of the extension defining the dictionary
|
const char* mExtId; //! ID of the extension defining the dictionary
|
||||||
Value* mDict; //! JSON dictionary object
|
Value* mDict; //! JSON dictionary object
|
||||||
|
@ -986,7 +1015,7 @@ namespace glTF
|
||||||
|
|
||||||
Ref<T> Get(const char* id);
|
Ref<T> Get(const char* id);
|
||||||
Ref<T> Get(unsigned int i);
|
Ref<T> Get(unsigned int i);
|
||||||
Ref<T> Get(const std::string& pID) { return Get(pID.c_str()); }
|
Ref<T> Get(const std::string& pID) { return Get(pID.c_str()); }
|
||||||
|
|
||||||
Ref<T> Create(const char* id);
|
Ref<T> Create(const char* id);
|
||||||
Ref<T> Create(const std::string& id)
|
Ref<T> Create(const std::string& id)
|
||||||
|
@ -1084,7 +1113,7 @@ namespace glTF
|
||||||
LazyDict<Sampler> samplers;
|
LazyDict<Sampler> samplers;
|
||||||
LazyDict<Scene> scenes;
|
LazyDict<Scene> scenes;
|
||||||
//LazyDict<Shader> shaders;
|
//LazyDict<Shader> shaders;
|
||||||
//LazyDict<Skin> skins;
|
LazyDict<Skin> skins;
|
||||||
//LazyDict<Technique> techniques;
|
//LazyDict<Technique> techniques;
|
||||||
LazyDict<Texture> textures;
|
LazyDict<Texture> textures;
|
||||||
|
|
||||||
|
@ -1109,7 +1138,7 @@ namespace glTF
|
||||||
, samplers (*this, "samplers")
|
, samplers (*this, "samplers")
|
||||||
, scenes (*this, "scenes")
|
, scenes (*this, "scenes")
|
||||||
//, shaders (*this, "shaders")
|
//, shaders (*this, "shaders")
|
||||||
//, skins (*this, "skins")
|
, skins (*this, "skins")
|
||||||
//, techniques (*this, "techniques")
|
//, techniques (*this, "techniques")
|
||||||
, textures (*this, "textures")
|
, textures (*this, "textures")
|
||||||
, lights (*this, "lights", "KHR_materials_common")
|
, lights (*this, "lights", "KHR_materials_common")
|
||||||
|
|
|
@ -102,7 +102,65 @@ namespace glTF {
|
||||||
|
|
||||||
inline void Write(Value& obj, Animation& a, AssetWriter& w)
|
inline void Write(Value& obj, Animation& a, AssetWriter& w)
|
||||||
{
|
{
|
||||||
|
/****************** Channels *******************/
|
||||||
|
Value channels;
|
||||||
|
channels.SetArray();
|
||||||
|
channels.Reserve(unsigned(a.Channels.size()), w.mAl);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < unsigned(a.Channels.size()); ++i) {
|
||||||
|
Animation::AnimChannel& c = a.Channels[i];
|
||||||
|
Value valChannel;
|
||||||
|
valChannel.SetObject();
|
||||||
|
{
|
||||||
|
valChannel.AddMember("sampler", c.sampler, w.mAl);
|
||||||
|
|
||||||
|
Value valTarget;
|
||||||
|
valTarget.SetObject();
|
||||||
|
{
|
||||||
|
valTarget.AddMember("id", StringRef(c.target.id->id), w.mAl);
|
||||||
|
valTarget.AddMember("path", c.target.path, w.mAl);
|
||||||
|
}
|
||||||
|
valChannel.AddMember("target", valTarget, w.mAl);
|
||||||
|
}
|
||||||
|
channels.PushBack(valChannel, w.mAl);
|
||||||
|
}
|
||||||
|
obj.AddMember("channels", channels, w.mAl);
|
||||||
|
|
||||||
|
/****************** Parameters *******************/
|
||||||
|
Value valParameters;
|
||||||
|
valParameters.SetObject();
|
||||||
|
{
|
||||||
|
if (a.Parameters.TIME) {
|
||||||
|
valParameters.AddMember("TIME", StringRef(a.Parameters.TIME->id), w.mAl);
|
||||||
|
}
|
||||||
|
if (a.Parameters.rotation) {
|
||||||
|
valParameters.AddMember("rotation", StringRef(a.Parameters.rotation->id), w.mAl);
|
||||||
|
}
|
||||||
|
if (a.Parameters.scale) {
|
||||||
|
valParameters.AddMember("scale", StringRef(a.Parameters.scale->id), w.mAl);
|
||||||
|
}
|
||||||
|
if (a.Parameters.translation) {
|
||||||
|
valParameters.AddMember("translation", StringRef(a.Parameters.translation->id), w.mAl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
obj.AddMember("parameters", valParameters, w.mAl);
|
||||||
|
|
||||||
|
/****************** Samplers *******************/
|
||||||
|
Value valSamplers;
|
||||||
|
valSamplers.SetObject();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < unsigned(a.Samplers.size()); ++i) {
|
||||||
|
Animation::AnimSampler& s = a.Samplers[i];
|
||||||
|
Value valSampler;
|
||||||
|
valSampler.SetObject();
|
||||||
|
{
|
||||||
|
valSampler.AddMember("input", s.input, w.mAl);
|
||||||
|
valSampler.AddMember("interpolation", s.interpolation, w.mAl);
|
||||||
|
valSampler.AddMember("output", s.output, w.mAl);
|
||||||
|
}
|
||||||
|
valSamplers.AddMember(StringRef(s.id), valSampler, w.mAl);
|
||||||
|
}
|
||||||
|
obj.AddMember("samplers", valSamplers, w.mAl);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Write(Value& obj, Buffer& b, AssetWriter& w)
|
inline void Write(Value& obj, Buffer& b, AssetWriter& w)
|
||||||
|
@ -327,6 +385,16 @@ namespace glTF {
|
||||||
AddRefsVector(obj, "children", n.children, w.mAl);
|
AddRefsVector(obj, "children", n.children, w.mAl);
|
||||||
|
|
||||||
AddRefsVector(obj, "meshes", n.meshes, w.mAl);
|
AddRefsVector(obj, "meshes", n.meshes, w.mAl);
|
||||||
|
|
||||||
|
AddRefsVector(obj, "skeletons", n.skeletons, w.mAl);
|
||||||
|
|
||||||
|
if (n.skin) {
|
||||||
|
obj.AddMember("skin", Value(n.skin->id, w.mAl).Move(), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!n.jointName.empty()) {
|
||||||
|
obj.AddMember("jointName", n.jointName, w.mAl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Write(Value& obj, Program& b, AssetWriter& w)
|
inline void Write(Value& obj, Program& b, AssetWriter& w)
|
||||||
|
@ -362,6 +430,24 @@ namespace glTF {
|
||||||
|
|
||||||
inline void Write(Value& obj, Skin& b, AssetWriter& w)
|
inline void Write(Value& obj, Skin& b, AssetWriter& w)
|
||||||
{
|
{
|
||||||
|
/****************** jointNames *******************/
|
||||||
|
Value vJointNames;
|
||||||
|
vJointNames.SetArray();
|
||||||
|
vJointNames.Reserve(unsigned(b.jointNames.size()), w.mAl);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < unsigned(b.jointNames.size()); ++i) {
|
||||||
|
vJointNames.PushBack(StringRef(b.jointNames[i]), w.mAl);
|
||||||
|
}
|
||||||
|
obj.AddMember("jointNames", vJointNames, w.mAl);
|
||||||
|
|
||||||
|
if (b.bindShapeMatrix.isPresent) {
|
||||||
|
Value val;
|
||||||
|
obj.AddMember("bindShapeMatrix", MakeValue(val, b.bindShapeMatrix.value, w.mAl).Move(), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.inverseBindMatrices) {
|
||||||
|
obj.AddMember("inverseBindMatrices", Value(b.inverseBindMatrices->id, w.mAl).Move(), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,6 @@ namespace Assimp {
|
||||||
// Worker function for exporting a scene to GLTF. Prototyped and registered in Exporter.cpp
|
// Worker function for exporting a scene to GLTF. Prototyped and registered in Exporter.cpp
|
||||||
void ExportSceneGLTF(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
void ExportSceneGLTF(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
|
|
||||||
// invoke the exporter
|
// invoke the exporter
|
||||||
glTFExporter exporter(pFile, pIOSystem, pScene, pProperties, false);
|
glTFExporter exporter(pFile, pIOSystem, pScene, pProperties, false);
|
||||||
}
|
}
|
||||||
|
@ -126,26 +125,24 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
|
||||||
|
|
||||||
ExportMetadata();
|
ExportMetadata();
|
||||||
|
|
||||||
//for (unsigned int i = 0; i < pScene->mNumAnimations; ++i) {}
|
|
||||||
|
|
||||||
//for (unsigned int i = 0; i < pScene->mNumCameras; ++i) {}
|
//for (unsigned int i = 0; i < pScene->mNumCameras; ++i) {}
|
||||||
|
|
||||||
//for (unsigned int i = 0; i < pScene->mNumLights; ++i) {}
|
//for (unsigned int i = 0; i < pScene->mNumLights; ++i) {}
|
||||||
|
|
||||||
|
|
||||||
ExportMaterials();
|
ExportMaterials();
|
||||||
|
|
||||||
ExportMeshes();
|
|
||||||
|
|
||||||
//for (unsigned int i = 0; i < pScene->mNumTextures; ++i) {}
|
|
||||||
|
|
||||||
|
|
||||||
if (mScene->mRootNode) {
|
if (mScene->mRootNode) {
|
||||||
ExportNode(mScene->mRootNode);
|
ExportNode(mScene->mRootNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExportMeshes();
|
||||||
|
|
||||||
|
//for (unsigned int i = 0; i < pScene->mNumTextures; ++i) {}
|
||||||
|
|
||||||
ExportScene();
|
ExportScene();
|
||||||
|
|
||||||
|
ExportAnimations();
|
||||||
|
|
||||||
glTF::AssetWriter writer(*mAsset);
|
glTF::AssetWriter writer(*mAsset);
|
||||||
|
|
||||||
if (isBinary) {
|
if (isBinary) {
|
||||||
|
@ -164,6 +161,14 @@ static void CopyValue(const aiMatrix4x4& v, glTF::mat4& o)
|
||||||
o[12] = v.a4; o[13] = v.b4; o[14] = v.c4; o[15] = v.d4;
|
o[12] = v.a4; o[13] = v.b4; o[14] = v.c4; o[15] = v.d4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void IdentityMatrix4(glTF::mat4& o)
|
||||||
|
{
|
||||||
|
o[ 0] = 1; o[ 1] = 0; o[ 2] = 0; o[ 3] = 0;
|
||||||
|
o[ 4] = 0; o[ 5] = 1; o[ 6] = 0; o[ 7] = 0;
|
||||||
|
o[ 8] = 0; o[ 9] = 0; o[10] = 1; o[11] = 0;
|
||||||
|
o[12] = 0; o[13] = 0; o[14] = 0; o[15] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& buffer,
|
inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& buffer,
|
||||||
unsigned int count, void* data, AttribType::Value typeIn, AttribType::Value typeOut, ComponentType compType, bool isIndices = false)
|
unsigned int count, void* data, AttribType::Value typeIn, AttribType::Value typeOut, ComponentType compType, bool isIndices = false)
|
||||||
{
|
{
|
||||||
|
@ -359,6 +364,78 @@ void glTFExporter::ExportMaterials()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer>& bufferRef)
|
||||||
|
{
|
||||||
|
std::string skinName = aim->mName.C_Str();
|
||||||
|
skinName = mAsset.FindUniqueID(skinName, "skin");
|
||||||
|
Ref<Skin> skinRef = mAsset.skins.Create(skinName);
|
||||||
|
skinRef->name = skinName;
|
||||||
|
|
||||||
|
mat4* inverseBindMatricesData = new mat4[aim->mNumBones];
|
||||||
|
|
||||||
|
//-------------------------------------------------------
|
||||||
|
// Store the vertex joint and weight data.
|
||||||
|
vec4* vertexJointData = new vec4[aim->mNumVertices];
|
||||||
|
vec4* vertexWeightData = new vec4[aim->mNumVertices];
|
||||||
|
unsigned int* jointsPerVertex = new unsigned int[aim->mNumVertices];
|
||||||
|
for (size_t i = 0; i < aim->mNumVertices; ++i) {
|
||||||
|
jointsPerVertex[i] = 0;
|
||||||
|
for (size_t j = 0; j < 4; ++j) {
|
||||||
|
vertexJointData[i][j] = 0;
|
||||||
|
vertexWeightData[i][j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int idx_bone = 0; idx_bone < aim->mNumBones; ++idx_bone) {
|
||||||
|
const aiBone* aib = aim->mBones[idx_bone];
|
||||||
|
|
||||||
|
// aib->mName =====> skinRef->jointNames
|
||||||
|
// Find the node with id = mName.
|
||||||
|
Ref<Node> nodeRef = mAsset.nodes.Get(aib->mName.C_Str());
|
||||||
|
nodeRef->jointName = "joint_" + std::to_string(idx_bone);
|
||||||
|
skinRef->jointNames.push_back("joint_" + std::to_string(idx_bone));
|
||||||
|
|
||||||
|
// Identity Matrix =====> skinRef->bindShapeMatrix
|
||||||
|
// Temporary. Hard-coded identity matrix here
|
||||||
|
skinRef->bindShapeMatrix.isPresent = true;
|
||||||
|
IdentityMatrix4(skinRef->bindShapeMatrix.value);
|
||||||
|
|
||||||
|
// aib->mOffsetMatrix =====> skinRef->inverseBindMatrices
|
||||||
|
CopyValue(aib->mOffsetMatrix, inverseBindMatricesData[idx_bone]);
|
||||||
|
|
||||||
|
// aib->mWeights =====> vertexWeightData
|
||||||
|
for (unsigned int idx_weights = 0; idx_weights < aib->mNumWeights; ++idx_weights) {
|
||||||
|
aiVertexWeight tmpVertWeight = aib->mWeights[idx_weights];
|
||||||
|
vertexJointData[tmpVertWeight.mVertexId][jointsPerVertex[tmpVertWeight.mVertexId]] = idx_bone;
|
||||||
|
vertexWeightData[tmpVertWeight.mVertexId][jointsPerVertex[tmpVertWeight.mVertexId]] = tmpVertWeight.mWeight;
|
||||||
|
|
||||||
|
jointsPerVertex[tmpVertWeight.mVertexId] += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End: for-loop mNumMeshes
|
||||||
|
|
||||||
|
// Create the Accessor for skinRef->inverseBindMatrices
|
||||||
|
Ref<Accessor> invBindMatrixAccessor = ExportData(mAsset, skinName, bufferRef, aim->mNumBones, inverseBindMatricesData, AttribType::MAT4, AttribType::MAT4, ComponentType_FLOAT);
|
||||||
|
if (invBindMatrixAccessor) skinRef->inverseBindMatrices = invBindMatrixAccessor;
|
||||||
|
|
||||||
|
|
||||||
|
Mesh::Primitive& p = meshRef->primitives.back();
|
||||||
|
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinName, bufferRef, aim->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||||
|
if (vertexJointAccessor) p.attributes.joint.push_back(vertexJointAccessor);
|
||||||
|
|
||||||
|
Ref<Accessor> vertexWeightAccessor = ExportData(mAsset, skinName, bufferRef, aim->mNumVertices, vertexWeightData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||||
|
if (vertexWeightAccessor) p.attributes.weight.push_back(vertexWeightAccessor);
|
||||||
|
|
||||||
|
|
||||||
|
// Create the skinned mesh instance node.
|
||||||
|
Ref<Node> node = mAsset.nodes.Create(mAsset.FindUniqueID(skinName, "node"));
|
||||||
|
// Ref<Node> node = mAsset.nodes.Get(aim->mBones[0]->mName.C_Str());
|
||||||
|
node->meshes.push_back(meshRef);
|
||||||
|
node->name = node->id;
|
||||||
|
node->skeletons.push_back(mAsset.nodes.Get(aim->mBones[0]->mName.C_Str()));
|
||||||
|
node->skin = skinRef;
|
||||||
|
}
|
||||||
|
|
||||||
void glTFExporter::ExportMeshes()
|
void glTFExporter::ExportMeshes()
|
||||||
{
|
{
|
||||||
// Not for
|
// Not for
|
||||||
|
@ -369,7 +446,7 @@ void glTFExporter::ExportMeshes()
|
||||||
typedef unsigned short IndicesType;
|
typedef unsigned short IndicesType;
|
||||||
|
|
||||||
// Variables needed for compression. BEGIN.
|
// Variables needed for compression. BEGIN.
|
||||||
// Indices, not pointers - because pointer to buffer is changin while writing to it.
|
// Indices, not pointers - because pointer to buffer is changing while writing to it.
|
||||||
size_t idx_srcdata_begin;// Index of buffer before writing mesh data. Also, index of begin of coordinates array in buffer.
|
size_t idx_srcdata_begin;// Index of buffer before writing mesh data. Also, index of begin of coordinates array in buffer.
|
||||||
size_t idx_srcdata_normal = SIZE_MAX;// Index of begin of normals array in buffer. SIZE_MAX - mean that mesh has no normals.
|
size_t idx_srcdata_normal = SIZE_MAX;// Index of begin of normals array in buffer. SIZE_MAX - mean that mesh has no normals.
|
||||||
std::vector<size_t> idx_srcdata_tc;// Array of indices. Every index point to begin of texture coordinates array in buffer.
|
std::vector<size_t> idx_srcdata_tc;// Array of indices. Every index point to begin of texture coordinates array in buffer.
|
||||||
|
@ -480,6 +557,12 @@ void glTFExporter::ExportMeshes()
|
||||||
p.mode = PrimitiveMode_TRIANGLES;
|
p.mode = PrimitiveMode_TRIANGLES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************** Skins ****************/
|
||||||
|
///TODO: Fix skinning animation
|
||||||
|
// if(aim->HasBones()) {
|
||||||
|
// ExportSkin(*mAsset, aim, m, b);
|
||||||
|
// }
|
||||||
|
|
||||||
/****************** Compression ******************/
|
/****************** Compression ******************/
|
||||||
///TODO: animation: weights, joints.
|
///TODO: animation: weights, joints.
|
||||||
if(comp_allow)
|
if(comp_allow)
|
||||||
|
@ -571,7 +654,7 @@ void glTFExporter::ExportMeshes()
|
||||||
m->Extension.push_back(ext);
|
m->Extension.push_back(ext);
|
||||||
#endif
|
#endif
|
||||||
}// if(comp_allow)
|
}// if(comp_allow)
|
||||||
}// for (unsigned int i = 0; i < mScene->mNumMeshes; ++i) {
|
}// for (unsigned int i = 0; i < mScene->mNumMeshes; ++i)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int glTFExporter::ExportNode(const aiNode* n)
|
unsigned int glTFExporter::ExportNode(const aiNode* n)
|
||||||
|
@ -622,10 +705,134 @@ void glTFExporter::ExportMetadata()
|
||||||
asset.generator = buffer;
|
asset.generator = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animation>& animRef, Ref<Buffer>& buffer, const aiNodeAnim* nodeChannel)
|
||||||
|
{
|
||||||
|
// Loop over the data and check to see if it exactly matches an existing buffer.
|
||||||
|
// If yes, then reference the existing corresponding accessor.
|
||||||
|
// Otherwise, add to the buffer and create a new accessor.
|
||||||
|
|
||||||
|
//-------------------------------------------------------
|
||||||
|
// Extract TIME parameter data.
|
||||||
|
// Check if the timeStamps are the same for mPositionKeys, mRotationKeys, and mScalingKeys.
|
||||||
|
if(nodeChannel->mNumPositionKeys > 0) {
|
||||||
|
typedef float TimeType;
|
||||||
|
std::vector<TimeType> timeData;
|
||||||
|
timeData.resize(nodeChannel->mNumPositionKeys);
|
||||||
|
for (size_t i = 0; i < nodeChannel->mNumPositionKeys; ++i) {
|
||||||
|
timeData[i] = nodeChannel->mPositionKeys[i].mTime; // Check if we have to cast type here. e.g. uint16_t()
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Accessor> timeAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumPositionKeys, &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT);
|
||||||
|
if (timeAccessor) animRef->Parameters.TIME = timeAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------
|
||||||
|
// Extract translation parameter data
|
||||||
|
if(nodeChannel->mNumPositionKeys > 0) {
|
||||||
|
C_STRUCT aiVector3D* translationData = new aiVector3D[nodeChannel->mNumPositionKeys];
|
||||||
|
for (size_t i = 0; i < nodeChannel->mNumPositionKeys; ++i) {
|
||||||
|
translationData[i] = nodeChannel->mPositionKeys[i].mValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Accessor> tranAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumPositionKeys, translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
|
||||||
|
if (tranAccessor) animRef->Parameters.translation = tranAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------
|
||||||
|
// Extract scale parameter data
|
||||||
|
if(nodeChannel->mNumScalingKeys > 0) {
|
||||||
|
C_STRUCT aiVector3D* scaleData = new aiVector3D[nodeChannel->mNumScalingKeys];
|
||||||
|
for (size_t i = 0; i < nodeChannel->mNumScalingKeys; ++i) {
|
||||||
|
scaleData[i] = nodeChannel->mScalingKeys[i].mValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Accessor> scaleAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumScalingKeys, scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
|
||||||
|
if (scaleAccessor) animRef->Parameters.scale = scaleAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------
|
||||||
|
// Extract rotation parameter data
|
||||||
|
if(nodeChannel->mNumRotationKeys > 0) {
|
||||||
|
C_STRUCT aiQuaternion* rotationData = new aiQuaternion[nodeChannel->mNumRotationKeys];
|
||||||
|
for (size_t i = 0; i < nodeChannel->mNumRotationKeys; ++i) {
|
||||||
|
rotationData[i] = nodeChannel->mRotationKeys[i].mValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Accessor> rotAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumRotationKeys, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||||
|
if (rotAccessor) animRef->Parameters.rotation = rotAccessor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTFExporter::ExportAnimations()
|
||||||
|
{
|
||||||
|
Ref<Buffer> bufferRef = mAsset->buffers.Get(unsigned (0));
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < mScene->mNumAnimations; ++i) {
|
||||||
|
const aiAnimation* anim = mScene->mAnimations[i];
|
||||||
|
|
||||||
|
std::string nameAnim = "anim";
|
||||||
|
if (anim->mName.length > 0) {
|
||||||
|
nameAnim = anim->mName.C_Str();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int channelIndex = 0; channelIndex < anim->mNumChannels; ++channelIndex) {
|
||||||
|
const aiNodeAnim* nodeChannel = anim->mChannels[channelIndex];
|
||||||
|
|
||||||
|
// It appears that assimp stores this type of animation as multiple animations.
|
||||||
|
// where each aiNodeAnim in mChannels animates a specific node.
|
||||||
|
std::string name = nameAnim + "_" + std::to_string(channelIndex);
|
||||||
|
name = mAsset->FindUniqueID(name, "animation");
|
||||||
|
Ref<Animation> animRef = mAsset->animations.Create(name);
|
||||||
|
|
||||||
|
/******************* Parameters ********************/
|
||||||
|
ExtractAnimationData(*mAsset, name, animRef, bufferRef, nodeChannel);
|
||||||
|
|
||||||
|
for (unsigned int j = 0; j < 3; ++j) {
|
||||||
|
std::string channelType;
|
||||||
|
int channelSize;
|
||||||
|
switch (j) {
|
||||||
|
case 0:
|
||||||
|
channelType = "rotation";
|
||||||
|
channelSize = nodeChannel->mNumRotationKeys;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
channelType = "scale";
|
||||||
|
channelSize = nodeChannel->mNumScalingKeys;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
channelType = "translation";
|
||||||
|
channelSize = nodeChannel->mNumPositionKeys;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channelSize < 1) { continue; }
|
||||||
|
|
||||||
|
Animation::AnimChannel tmpAnimChannel;
|
||||||
|
Animation::AnimSampler tmpAnimSampler;
|
||||||
|
|
||||||
|
tmpAnimChannel.sampler = name + "_" + channelType;
|
||||||
|
tmpAnimChannel.target.path = channelType;
|
||||||
|
tmpAnimSampler.output = channelType;
|
||||||
|
tmpAnimSampler.id = name + "_" + channelType;
|
||||||
|
|
||||||
|
tmpAnimChannel.target.id = mAsset->nodes.Get(nodeChannel->mNodeName.C_Str());
|
||||||
|
|
||||||
|
tmpAnimSampler.input = "TIME";
|
||||||
|
tmpAnimSampler.interpolation = "LINEAR";
|
||||||
|
|
||||||
|
animRef->Channels.push_back(tmpAnimChannel);
|
||||||
|
animRef->Samplers.push_back(tmpAnimSampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assimp documentation staes this is not used (not implemented)
|
||||||
|
// for (unsigned int channelIndex = 0; channelIndex < anim->mNumMeshChannels; ++channelIndex) {
|
||||||
|
// const aiMeshAnim* meshChannel = anim->mMeshChannels[channelIndex];
|
||||||
|
// }
|
||||||
|
|
||||||
|
} // End: for-loop mNumAnimations
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_GLTF_EXPORTER
|
#endif // ASSIMP_BUILD_NO_GLTF_EXPORTER
|
||||||
|
|
|
@ -59,7 +59,6 @@ struct aiMaterial;
|
||||||
namespace glTF
|
namespace glTF
|
||||||
{
|
{
|
||||||
class Asset;
|
class Asset;
|
||||||
|
|
||||||
struct TexProperty;
|
struct TexProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +100,7 @@ namespace Assimp
|
||||||
void ExportMeshes();
|
void ExportMeshes();
|
||||||
unsigned int ExportNode(const aiNode* node);
|
unsigned int ExportNode(const aiNode* node);
|
||||||
void ExportScene();
|
void ExportScene();
|
||||||
|
void ExportAnimations();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,15 @@ public:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// array access operators
|
// array access operators
|
||||||
|
/** @fn TReal* operator[] (unsigned int p_iIndex)
|
||||||
|
* @param [in] p_iIndex - index of the row.
|
||||||
|
* @return pointer to pointed row.
|
||||||
|
*/
|
||||||
TReal* operator[] (unsigned int p_iIndex);
|
TReal* operator[] (unsigned int p_iIndex);
|
||||||
|
|
||||||
|
/** @fn const TReal* operator[] (unsigned int p_iIndex) const
|
||||||
|
* @overload TReal* operator[] (unsigned int p_iIndex)
|
||||||
|
*/
|
||||||
const TReal* operator[] (unsigned int p_iIndex) const;
|
const TReal* operator[] (unsigned int p_iIndex) const;
|
||||||
|
|
||||||
// comparison operators
|
// comparison operators
|
||||||
|
@ -140,6 +148,27 @@ public:
|
||||||
void Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
|
void Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
|
||||||
aiVector3t<TReal>& position) const;
|
aiVector3t<TReal>& position) const;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** @fn void Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const
|
||||||
|
* @brief Decompose a trafo matrix into its original components.
|
||||||
|
* Thx to good FAQ at http://www.gamedev.ru/code/articles/faq_matrix_quat
|
||||||
|
* @param [out] pScaling - Receives the output scaling for the x,y,z axes.
|
||||||
|
* @param [out] pRotation - Receives the output rotation as a Euler angles.
|
||||||
|
* @param [out] pPosition - Receives the output position for the x,y,z axes.
|
||||||
|
*/
|
||||||
|
void Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** @fn void Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle, aiVector3t<TReal>& pPosition) const
|
||||||
|
* @brief Decompose a trafo matrix into its original components
|
||||||
|
* Thx to good FAQ at http://www.gamedev.ru/code/articles/faq_matrix_quat
|
||||||
|
* @param [out] pScaling - Receives the output scaling for the x,y,z axes.
|
||||||
|
* @param [out] pRotationAxis - Receives the output rotation axis.
|
||||||
|
* @param [out] pRotationAngle - Receives the output rotation angle for @ref pRotationAxis.
|
||||||
|
* @param [out] pPosition - Receives the output position for the x,y,z axes.
|
||||||
|
*/
|
||||||
|
void Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle, aiVector3t<TReal>& pPosition) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Decompose a trafo matrix with no scaling into its
|
/** @brief Decompose a trafo matrix with no scaling into its
|
||||||
* original components
|
* original components
|
||||||
|
|
|
@ -299,57 +299,126 @@ inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define ASSIMP_MATRIX4_4_DECOMPOSE_PART \
|
||||||
|
const aiMatrix4x4t<TReal>& _this = *this;/* Create alias for conveniance. */ \
|
||||||
|
\
|
||||||
|
/* extract translation */ \
|
||||||
|
pPosition.x = _this[0][3]; \
|
||||||
|
pPosition.y = _this[1][3]; \
|
||||||
|
pPosition.z = _this[2][3]; \
|
||||||
|
\
|
||||||
|
/* extract the columns of the matrix. */ \
|
||||||
|
aiVector3t<TReal> vCols[3] = { \
|
||||||
|
aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]), \
|
||||||
|
aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]), \
|
||||||
|
aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2]) \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
/* extract the scaling factors */ \
|
||||||
|
pScaling.x = vCols[0].Length(); \
|
||||||
|
pScaling.y = vCols[1].Length(); \
|
||||||
|
pScaling.z = vCols[2].Length(); \
|
||||||
|
\
|
||||||
|
/* and the sign of the scaling */ \
|
||||||
|
if (Determinant() < 0) pScaling = -pScaling; \
|
||||||
|
\
|
||||||
|
/* and remove all scaling from the matrix */ \
|
||||||
|
if(pScaling.x) vCols[0] /= pScaling.x; \
|
||||||
|
if(pScaling.y) vCols[1] /= pScaling.y; \
|
||||||
|
if(pScaling.z) vCols[2] /= pScaling.z; \
|
||||||
|
\
|
||||||
|
do {} while(false)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename TReal>
|
template <typename TReal>
|
||||||
inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
|
inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation,
|
||||||
aiVector3t<TReal>& position) const
|
aiVector3t<TReal>& pPosition) const
|
||||||
{
|
{
|
||||||
const aiMatrix4x4t<TReal>& _this = *this;
|
ASSIMP_MATRIX4_4_DECOMPOSE_PART;
|
||||||
|
|
||||||
// extract translation
|
|
||||||
position.x = _this[0][3];
|
|
||||||
position.y = _this[1][3];
|
|
||||||
position.z = _this[2][3];
|
|
||||||
|
|
||||||
// extract the rows of the matrix
|
|
||||||
aiVector3t<TReal> vRows[3] = {
|
|
||||||
aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]),
|
|
||||||
aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]),
|
|
||||||
aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2])
|
|
||||||
};
|
|
||||||
|
|
||||||
// extract the scaling factors
|
|
||||||
scaling.x = vRows[0].Length();
|
|
||||||
scaling.y = vRows[1].Length();
|
|
||||||
scaling.z = vRows[2].Length();
|
|
||||||
|
|
||||||
// and the sign of the scaling
|
|
||||||
if (Determinant() < 0) {
|
|
||||||
scaling.x = -scaling.x;
|
|
||||||
scaling.y = -scaling.y;
|
|
||||||
scaling.z = -scaling.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
// and remove all scaling from the matrix
|
|
||||||
if(scaling.x)
|
|
||||||
{
|
|
||||||
vRows[0] /= scaling.x;
|
|
||||||
}
|
|
||||||
if(scaling.y)
|
|
||||||
{
|
|
||||||
vRows[1] /= scaling.y;
|
|
||||||
}
|
|
||||||
if(scaling.z)
|
|
||||||
{
|
|
||||||
vRows[2] /= scaling.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
// build a 3x3 rotation matrix
|
// build a 3x3 rotation matrix
|
||||||
aiMatrix3x3t<TReal> m(vRows[0].x,vRows[1].x,vRows[2].x,
|
aiMatrix3x3t<TReal> m(vCols[0].x,vCols[1].x,vCols[2].x,
|
||||||
vRows[0].y,vRows[1].y,vRows[2].y,
|
vCols[0].y,vCols[1].y,vCols[2].y,
|
||||||
vRows[0].z,vRows[1].z,vRows[2].z);
|
vCols[0].z,vCols[1].z,vCols[2].z);
|
||||||
|
|
||||||
// and generate the rotation quaternion from it
|
// and generate the rotation quaternion from it
|
||||||
rotation = aiQuaterniont<TReal>(m);
|
pRotation = aiQuaterniont<TReal>(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TReal>
|
||||||
|
inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const
|
||||||
|
{
|
||||||
|
ASSIMP_MATRIX4_4_DECOMPOSE_PART;
|
||||||
|
|
||||||
|
/*
|
||||||
|
| CE -CF D 0 |
|
||||||
|
M = | BDE+AF -BDF+AE -BC 0 |
|
||||||
|
| -ADE+BF -ADF+BE AC 0 |
|
||||||
|
| 0 0 0 1 |
|
||||||
|
|
||||||
|
A = cos(angle_x), B = sin(angle_x);
|
||||||
|
C = cos(angle_y), D = sin(angle_y);
|
||||||
|
E = cos(angle_z), F = sin(angle_z);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Use a small epsilon to solve floating-point inaccuracies
|
||||||
|
const TReal epsilon = 10e-3f;
|
||||||
|
|
||||||
|
pRotation.y = asin(vCols[2].x);// D. Angle around oY.
|
||||||
|
|
||||||
|
TReal C = cos(pRotation.y);
|
||||||
|
|
||||||
|
if(fabs(C) > epsilon)
|
||||||
|
{
|
||||||
|
// Finding angle around oX.
|
||||||
|
TReal tan_x = vCols[2].z / C;// A
|
||||||
|
TReal tan_y = -vCols[2].y / C;// B
|
||||||
|
|
||||||
|
pRotation.x = atan2(tan_y, tan_x);
|
||||||
|
// Finding angle around oZ.
|
||||||
|
tan_x = vCols[0].x / C;// E
|
||||||
|
tan_y = -vCols[1].x / C;// F
|
||||||
|
pRotation.z = atan2(tan_y, tan_x);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{// oY is fixed.
|
||||||
|
pRotation.x = 0;// Set angle around oX to 0. => A == 1, B == 0, C == 0, D == 1.
|
||||||
|
|
||||||
|
// And finding angle around oZ.
|
||||||
|
TReal tan_x = vCols[1].y;// -BDF+AE => E
|
||||||
|
TReal tan_y = vCols[0].y;// BDE+AF => F
|
||||||
|
|
||||||
|
pRotation.z = atan2(tan_y, tan_x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ASSIMP_MATRIX4_4_DECOMPOSE_PART
|
||||||
|
|
||||||
|
template <typename TReal>
|
||||||
|
inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle,
|
||||||
|
aiVector3t<TReal>& pPosition) const
|
||||||
|
{
|
||||||
|
aiQuaterniont<TReal> pRotation;
|
||||||
|
|
||||||
|
Decompose(pScaling, pRotation, pPosition);
|
||||||
|
pRotation.Normalize();
|
||||||
|
|
||||||
|
TReal angle_cos = pRotation.w;
|
||||||
|
TReal angle_sin = sqrt(1.0f - angle_cos * angle_cos);
|
||||||
|
|
||||||
|
pRotationAngle = acos(angle_cos) * 2;
|
||||||
|
|
||||||
|
// Use a small epsilon to solve floating-point inaccuracies
|
||||||
|
const TReal epsilon = 10e-3f;
|
||||||
|
|
||||||
|
if(fabs(angle_sin) < epsilon) angle_sin = 1;
|
||||||
|
|
||||||
|
pRotationAxis.x = pRotation.x / angle_sin;
|
||||||
|
pRotationAxis.y = pRotation.y / angle_sin;
|
||||||
|
pRotationAxis.z = pRotation.z / angle_sin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -64,12 +64,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
typedef enum aiMetadataType
|
typedef enum aiMetadataType
|
||||||
{
|
{
|
||||||
AI_BOOL = 0,
|
AI_BOOL = 0,
|
||||||
AI_INT = 1,
|
AI_INT32 = 1,
|
||||||
AI_UINT64 = 2,
|
AI_UINT64 = 2,
|
||||||
AI_FLOAT = 3,
|
AI_FLOAT = 3,
|
||||||
AI_DOUBLE = 4,
|
AI_DOUBLE = 4,
|
||||||
AI_AISTRING = 5,
|
AI_AISTRING = 5,
|
||||||
AI_AIVECTOR3D = 6,
|
AI_AIVECTOR3D = 6,
|
||||||
|
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
|
@ -106,7 +106,7 @@ struct aiMetadataEntry
|
||||||
*/
|
*/
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
inline aiMetadataType GetAiType( bool ) { return AI_BOOL; }
|
inline aiMetadataType GetAiType( bool ) { return AI_BOOL; }
|
||||||
inline aiMetadataType GetAiType( int ) { return AI_INT; }
|
inline aiMetadataType GetAiType( int32_t ) { return AI_INT32; }
|
||||||
inline aiMetadataType GetAiType( uint64_t ) { return AI_UINT64; }
|
inline aiMetadataType GetAiType( uint64_t ) { return AI_UINT64; }
|
||||||
inline aiMetadataType GetAiType( float ) { return AI_FLOAT; }
|
inline aiMetadataType GetAiType( float ) { return AI_FLOAT; }
|
||||||
inline aiMetadataType GetAiType( double ) { return AI_DOUBLE; }
|
inline aiMetadataType GetAiType( double ) { return AI_DOUBLE; }
|
||||||
|
@ -165,8 +165,8 @@ struct aiMetadata
|
||||||
case AI_BOOL:
|
case AI_BOOL:
|
||||||
delete static_cast<bool*>(data);
|
delete static_cast<bool*>(data);
|
||||||
break;
|
break;
|
||||||
case AI_INT:
|
case AI_INT32:
|
||||||
delete static_cast<int*>(data);
|
delete static_cast<int32_t*>(data);
|
||||||
break;
|
break;
|
||||||
case AI_UINT64:
|
case AI_UINT64:
|
||||||
delete static_cast<uint64_t*>(data);
|
delete static_cast<uint64_t*>(data);
|
||||||
|
@ -248,6 +248,22 @@ struct aiMetadata
|
||||||
return Get(aiString(key), value);
|
return Get(aiString(key), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \fn inline bool Get(size_t pIndex, const aiString*& pKey, const aiMetadataEntry*& pEntry)
|
||||||
|
/// Return metadata entry for analyzing it by user.
|
||||||
|
/// \param [in] pIndex - index of the entry.
|
||||||
|
/// \param [out] pKey - pointer to the key value.
|
||||||
|
/// \param [out] pEntry - pointer to the entry: type and value.
|
||||||
|
/// \return false - if pIndex is out of range, else - true.
|
||||||
|
inline bool Get(size_t pIndex, const aiString*& pKey, const aiMetadataEntry*& pEntry)
|
||||||
|
{
|
||||||
|
if(pIndex >= mNumProperties) return false;
|
||||||
|
|
||||||
|
pKey = &mKeys[pIndex];
|
||||||
|
pEntry = &mValues[pIndex];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -155,8 +155,8 @@ struct aiTexture
|
||||||
* absent color channel and just use 0 for bitness. For example:
|
* absent color channel and just use 0 for bitness. For example:
|
||||||
* 1. Image contain RGBA and 8 bit per channel, achFormatHint == "rgba8888";
|
* 1. Image contain RGBA and 8 bit per channel, achFormatHint == "rgba8888";
|
||||||
* 2. Image contain ARGB and 8 bit per channel, achFormatHint == "argb8888";
|
* 2. Image contain ARGB and 8 bit per channel, achFormatHint == "argb8888";
|
||||||
* 2. Image contain RGB and 5 bit for R and B channels and 6 bit for G channel, achFormatHint == "rgba5650";
|
* 3. Image contain RGB and 5 bit for R and B channels and 6 bit for G channel, achFormatHint == "rgba5650";
|
||||||
* 3. One color image with B channel and 1 bit for it, achFormatHint == "rgba0010";
|
* 4. One color image with B channel and 1 bit for it, achFormatHint == "rgba0010";
|
||||||
* If mHeight == 0 then achFormatHint is set set to '\\0\\0\\0\\0' if the loader has no additional
|
* If mHeight == 0 then achFormatHint is set set to '\\0\\0\\0\\0' if the loader has no additional
|
||||||
* information about the texture file format used OR the
|
* information about the texture file format used OR the
|
||||||
* file extension of the format without a trailing dot. If there
|
* file extension of the format without a trailing dot. If there
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
AppName=Open Asset Import Library - SDK
|
AppName=Open Asset Import Library - SDK
|
||||||
AppVerName=Open Asset Import Library - SDK (v2.0)
|
AppVerName=Open Asset Import Library - SDK (v3.3.1)
|
||||||
DefaultDirName={pf}\Assimp
|
DefaultDirName={pf}\Assimp
|
||||||
DefaultGroupName=Assimp
|
DefaultGroupName=Assimp
|
||||||
UninstallDisplayIcon={app}\bin\x86\assimp.exe
|
UninstallDisplayIcon={app}\bin\x86\assimp.exe
|
||||||
|
@ -12,9 +12,9 @@ SetupIconFile=..\..\tools\shared\assimp_tools_icon.ico
|
||||||
WizardImageFile=compiler:WizModernImage-IS.BMP
|
WizardImageFile=compiler:WizModernImage-IS.BMP
|
||||||
WizardSmallImageFile=compiler:WizModernSmallImage-IS.BMP
|
WizardSmallImageFile=compiler:WizModernSmallImage-IS.BMP
|
||||||
LicenseFile=License.rtf
|
LicenseFile=License.rtf
|
||||||
OutputBaseFileName=assimp-sdk-2.0-setup
|
OutputBaseFileName=assimp-sdk-3.3.1-setup
|
||||||
VersionInfoVersion=2.0.0.0
|
VersionInfoVersion=3.3.1.0
|
||||||
VersionInfoTextVersion=2.0
|
VersionInfoTextVersion=3.3.1
|
||||||
VersionInfoCompany=Assimp Development Team
|
VersionInfoCompany=Assimp Development Team
|
||||||
ArchitecturesInstallIn64BitMode=x64
|
ArchitecturesInstallIn64BitMode=x64
|
||||||
|
|
||||||
|
@ -38,8 +38,8 @@ Name: "assimp_net"; Description: "C#/.NET Bindings"; Types: full
|
||||||
;Name: "vc9"; Description: "VC9 project files"; Types: full
|
;Name: "vc9"; Description: "VC9 project files"; Types: full
|
||||||
|
|
||||||
[Run]
|
[Run]
|
||||||
Filename: "{app}\stub\vcredist_x86.exe"; Parameters: "/qb"; StatusMsg: "Installing VS2008 SP1 redistributable package (32 Bit)"; Check: not IsWin64
|
Filename: "{app}\stub\vcredist_x86.exe"; Parameters: "/qb"; StatusMsg: "Installing VS2012 SP1 redistributable package (32 Bit)"; Check: not IsWin64
|
||||||
Filename: "{app}\stub\vcredist_x64.exe"; Parameters: "/qb"; StatusMsg: "Installing VS2008 SP1 redistributable package (64 Bit)"; Check: IsWin64
|
Filename: "{app}\stub\vcredist_x64.exe"; Parameters: "/qb"; StatusMsg: "Installing VS2012 SP1 redistributable package (64 Bit)"; Check: IsWin64
|
||||||
|
|
||||||
[Files]
|
[Files]
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
|
@ -0,0 +1,367 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "http://www.web3d.org/specifications/x3d-3.0.dtd">
|
||||||
|
<X3D profile='Immersive' version='3.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-3.0.xsd'>
|
||||||
|
<head>
|
||||||
|
<meta content='ChevyTahoe.x3d' name='title'/>
|
||||||
|
<meta content='30 May 2007' name='created'/>
|
||||||
|
<meta content='04 SEP 2015' name='modified'/>
|
||||||
|
<meta content='Chevy Tahoe' name='description'/>
|
||||||
|
<meta content='https://savage.nps.edu/Savage/GroundVehicles/Chevy/ChevyTahoe.x3d' name='identifier'/>
|
||||||
|
<meta content='Yumetech, Inc.' name='author of car body:'/>
|
||||||
|
<meta content='../../license.html' name='license'/>
|
||||||
|
</head>
|
||||||
|
<Scene>
|
||||||
|
<WorldInfo title='SavageVehicleMetadataTemplate'>
|
||||||
|
<MetadataSet name='SMAL' reference='https://savage.nps.edu/Savage/Tools/SMAL/SMAL.html'>
|
||||||
|
<MetadataString containerField='value' name='version' value='"1.0"'>
|
||||||
|
<MetadataString name='appinfo' value='"This is the version of SMAL employed, not of the model."'/>
|
||||||
|
</MetadataString>
|
||||||
|
<MetadataSet containerField='value' name='EntityDefinition'>
|
||||||
|
<!-- Identifying metadata for the current simulation of interest -->
|
||||||
|
<MetadataSet containerField='value' name='Classification'>
|
||||||
|
<MetadataString containerField='value' name='level' value='"UNCLASSIFIED"'>
|
||||||
|
<MetadataString name='appinfo' value='"UNCLASSIFIED" "FOUO" "CONFIDENTIAL" "SECRET" "TOPSECRET"'/>
|
||||||
|
</MetadataString>
|
||||||
|
<MetadataString containerField='value' name='reference'>
|
||||||
|
<MetadataString name='appinfo' value='"The published source of classified information, if any, contained in the Metadata."'/>
|
||||||
|
</MetadataString>
|
||||||
|
<MetadataString containerField='value' name='rationale'>
|
||||||
|
<MetadataString name='appinfo' value='"The specific element which contains the information classifying this document."'/>
|
||||||
|
</MetadataString>
|
||||||
|
</MetadataSet>
|
||||||
|
<MetadataSet containerField='value' name='IdentificationParameters'>
|
||||||
|
<MetadataString containerField='value' name='name' value='"ChevyTahoe"'>
|
||||||
|
<MetadataString name='appinfo' value='"The plain language name of the vehicle this model represents, i.e. the base class (DDG-51), or vehicle designation (M1A2)."'/>
|
||||||
|
</MetadataString>
|
||||||
|
</MetadataSet>
|
||||||
|
<MetadataSet containerField='value' name='X3DArchiveModel'>
|
||||||
|
<MetadataString name='appinfo' value='"This is a placeholder element which ensures the proper validation of autogenerated SMAL code."'/>
|
||||||
|
</MetadataSet>
|
||||||
|
<MetadataSet containerField='value' name='PhysicalParameters'>
|
||||||
|
<MetadataSet containerField='value' name='PhysicalConstraints'>
|
||||||
|
<MetadataFloat containerField='value' name='height' value='2.22'>
|
||||||
|
<MetadataString name='appinfo' value='"The maximum structural height of the object in meters. This may be used for clearance checking or other calculations."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='width' value='2.397'>
|
||||||
|
<MetadataString name='appinfo' value='"The maximum width, beam, or wingspan of the vehicle in meters. This may be used for clearance checking or other calculations."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='length' value='5.465'>
|
||||||
|
<MetadataString name='appinfo' value='"The maximum structural length of the object in meters. This may be used for clearance checking or other calculations."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='draft' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The vertical distance in meters from the deepest point (keel or other structure) to the waterline of a vehicle at its stated displacement or gross weight."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='wheelbase' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The longitudinal distance in meters from the center of the forwardmost roadwheel axle to the center of the rearmost roadwheel axle on this vehicle."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='trackWidth' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The horizontal distance in meters from the rightmost edge of the right wheel or track to the leftmost edge of the left wheel or track on this vehicle."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='grossWeight' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The standard operational weight of the vehicle in pounds or kilograms. This may be used in physics calculations."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
</MetadataSet>
|
||||||
|
<MetadataSet containerField='value' name='DynamicResponseConstraints'>
|
||||||
|
<MetadataFloat containerField='value' name='centerOfGravity' value='0 0 0'>
|
||||||
|
<MetadataString name='appinfo' value='"Sets the Center of Gravity of the object as an (x, y, z) distance in meters from the physical center of the object, which is located at (0, 0, 0)."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='aerodynamicCenter' value='0 0 0'>
|
||||||
|
<MetadataString name='appinfo' value='"Sets the Aerodynamic Center of the object as an (x, y, z) distance in meters from the physical center of the object, which is located at (0, 0, 0)."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='centerOfBuoyancy' value='0 0 0'>
|
||||||
|
<MetadataString name='appinfo' value='"Sets the Center of Buoyancy of the object as an (x, y, z) distance in meters from the physical center of the object, which is located at (0, 0, 0)."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='maximumSpeed' value='100'>
|
||||||
|
<MetadataString name='appinfo' value='"The maximum rated speed for this vehicle in mph or kph."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='cruiseSpeed' value='55'>
|
||||||
|
<MetadataString name='appinfo' value='The published cruise speed for this vehicle in mph or kph.'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='maximumAltitude' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The absolute ceiling for this aircraft in feet or meters."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='cruiseAltitude' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The cruise ceiling for this aircraft in feet or meters."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='maximumDepth' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The absolute depth for this submersible in feet or meters."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='cruiseDepth' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The cruise depth for this submersible in feet or meters."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='maximumAcceleration' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The ideal maximum acceleration achievable by this vehicle in feet or meters per second squared, as in at maximum Power excess for aircraft."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='maximumDeceleration' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The ideal best braking performance achievable by this vehicle in feet or meters per second squared."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='minimumTurnRadius' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The minimum turning radius for this vehicle in feet or meters, as in at best cornering speed for aircraft."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='maximumTurnRate' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The maximum turning rate for this vehicle in degrees per second, as in at best cornering speed for aircraft."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='maximumFuelCapacity' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The maximum usable internal fuel capacity of this vehicle in liters."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
</MetadataSet>
|
||||||
|
<MetadataSet containerField='value' name='TacticalConstraints'>
|
||||||
|
<MetadataFloat containerField='value' name='maximumAirThreatRange' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The maximum effective range in miles or kilometers of the longest-range anti-aircraft weapon on this platform."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='maximumSurfaceThreatRange' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The maximum effective range in miles or kilometers of the longest-range anti-surface weapon on this platform."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='maximumSubsurfaceThreatRange' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The maximum effective range in miles or kilometers of the longest-range anti-submarine weapon on this platform."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='maximumAirDetectionRange' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The maximum detection range of the longest-range air detection sensor on this platform."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='maximumSurfaceDetectionRange' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The DIS enumeration for the overall type of this object (for vehicles this value should be 1)."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
<MetadataFloat containerField='value' name='maximumSubsurfaceDetectionRange' value='0'>
|
||||||
|
<MetadataString name='appinfo' value='"The maximum detection range of the longest-range subsurface detection sensor on this platform."'/>
|
||||||
|
</MetadataFloat>
|
||||||
|
</MetadataSet>
|
||||||
|
</MetadataSet>
|
||||||
|
<MetadataSet containerField='value' name='CurrentConditionParameters'>
|
||||||
|
<!-- <MetadataString name="appinfo" value="This is a placeholder element which ensures the proper validation of autogenerated SMAL code."/> -->
|
||||||
|
</MetadataSet>
|
||||||
|
<MetadataSet containerField='value' name='NetworkedCommunicationParameterSet'>
|
||||||
|
<MetadataSet containerField='value' name='DisConfiguration'>
|
||||||
|
<MetadataInteger containerField='value' name='entityKind' value='1'>
|
||||||
|
<MetadataString name='appinfo' value='"The DIS enumeration for the overall type of this object (for vehicles this value should be 1)."'/>
|
||||||
|
</MetadataInteger>
|
||||||
|
<MetadataInteger containerField='value' name='entityDomain' value='1'>
|
||||||
|
<MetadataString name='appinfo' value='"The DIS enumeration for the domain of operations of this object (air, surface, sub-surface, etc.)."'/>
|
||||||
|
</MetadataInteger>
|
||||||
|
<MetadataInteger containerField='value' name='entityCountry' value='225'>
|
||||||
|
<MetadataString name='appinfo' value='"The DIS enumeration for the country of origin of this object (the value for United States is 225)."'/>
|
||||||
|
</MetadataInteger>
|
||||||
|
<MetadataInteger containerField='value' name='entityCategory' value='1'>
|
||||||
|
<MetadataString name='appinfo' value='"The DIS enumeration for the type of this vehicle (cruiser or destroyer, tank or truck, bomber or fighter, etc.)."'/>
|
||||||
|
</MetadataInteger>
|
||||||
|
<MetadataInteger containerField='value' name='entitySubCategory' value='1'>
|
||||||
|
<MetadataString name='appinfo' value='"The DIS enumeration for the class designation of this vehicle (CG-47 Ticonderoga, DDG-51 Arleigh Burke, M1A2, M880, B-52, F-22, etc."'/>
|
||||||
|
</MetadataInteger>
|
||||||
|
<MetadataInteger containerField='value' name='entitySpecific' value='1'>
|
||||||
|
<MetadataString name='appinfo' value='"The DIS enumeration for the specific unit or variant of this object (CG-68, DDG-77, HMMVW w/TOW package, etc.)."'/>
|
||||||
|
</MetadataInteger>
|
||||||
|
<MetadataInteger containerField='value' name='entityExtra' value='1'>
|
||||||
|
<MetadataString name='appinfo' value='"The DIS enumeration for optional equipment or configurations for this vehicle."'/>
|
||||||
|
</MetadataInteger>
|
||||||
|
</MetadataSet>
|
||||||
|
</MetadataSet>
|
||||||
|
</MetadataSet>
|
||||||
|
</MetadataSet>
|
||||||
|
</WorldInfo>
|
||||||
|
<NavigationInfo/>
|
||||||
|
<Viewpoint DEF='ChevySideView' description='Chevy Side View' orientation='-6.13026E-4 0.998247 0.0591875 3.12092' position='0.260696 2.06618 -7.64563'/>
|
||||||
|
<Viewpoint DEF='ChevyRearView' description='Chevy Rear View' orientation='-0.0161194 0.999737 -0.0162893 4.70164' position='-7.40297 1.39539 -0.0463563'/>
|
||||||
|
<Viewpoint DEF='ChevyFrontView' description='Chevy Front View' orientation='0.0244909 0.999394 -0.0247425 1.58163' position='7.39543 1.27018 -0.0443344'/>
|
||||||
|
<Viewpoint DEF='ChevyTopView' description='Chevy Top View' orientation='1.0 0.0 0.0 -1.578' position='0.0 9.0 0.0'/>
|
||||||
|
<Transform DEF='ChevyTahoe' rotation='0 1 0 3.1416'>
|
||||||
|
<Transform DEF='Body' rotation='-6.29487E-11 1.0 2.59312E-10 3.14159' scale='0.016483 0.0172362 0.016483' translation='0.102525 1.13227 -0.011915'>
|
||||||
|
<Transform rotation='0.0 -0.707107 -0.707107 3.142' scale='0.8311 0.7947 0.8484' translation='133.8 -18.08 -71.34'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='1.0' diffuseColor='0.5882 0.5882 0.5882' shininess='0.145'/>
|
||||||
|
<ImageTexture url='"textures/ChevyTahoeTexture.jpg" "https://savage.nps.edu/Savage/GroundVehicles/Chevy/textures/ChevyTahoeTexture.jpg"'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='0 7 6 -1 7 0 2 -1 2 9 7 -1 2 3 9 -1 10 3 4 -1 4 11 10 -1 11 4 5 -1 5 12 11 -1 6 14 0 -1 14 6 8 -1 8 1 14 -1 12 5 15 -1 15 13 12 -1 22 23 16 -1 18 16 23 -1 23 25 18 -1 19 18 25 -1 20 19 26 -1 26 27 20 -1 21 20 27 -1 27 28 21 -1 30 6 7 -1 23 22 30 -1 7 31 30 -1 30 31 23 -1 31 7 9 -1 25 23 31 -1 32 8 6 -1 6 30 32 -1 32 30 22 -1 22 24 32 -1 9 33 31 -1 31 33 25 -1 35 11 12 -1 28 27 35 -1 12 36 35 -1 35 36 28 -1 36 12 13 -1 29 28 36 -1 13 37 36 -1 36 37 29 -1 16 38 22 -1 24 22 38 -1 38 17 24 -1 28 29 39 -1 39 21 28 -1 40 26 19 -1 40 19 25 -1 41 33 9 -1 25 33 41 -1 41 40 25 -1 3 10 42 -1 3 42 9 -1 9 42 41 -1 43 11 35 -1 34 44 43 -1 11 43 44 -1 44 10 11 -1 45 44 34 -1 10 44 45 -1 45 42 10 -1 34 46 45 -1 42 45 46 -1 46 41 42 -1 41 46 47 -1 47 40 41 -1 46 34 48 -1 48 47 46 -1 40 47 48 -1 48 26 40 -1 49 48 34 -1 26 48 49 -1 49 27 26 -1 43 50 34 -1 34 50 49 -1 35 50 43 -1 27 49 50 -1 50 35 27 -1' creaseAngle='3.0' texCoordIndex='0 7 6 -1 7 0 2 -1 2 9 7 -1 2 3 9 -1 10 3 4 -1 4 11 10 -1 11 4 5 -1 5 12 11 -1 6 14 0 -1 14 6 8 -1 8 1 14 -1 12 5 15 -1 15 13 12 -1 22 23 16 -1 18 16 23 -1 23 25 18 -1 19 18 25 -1 20 19 26 -1 26 27 20 -1 21 20 27 -1 27 28 21 -1 30 6 7 -1 23 22 30 -1 7 31 30 -1 30 31 23 -1 31 7 9 -1 25 23 31 -1 32 8 6 -1 6 30 32 -1 32 30 22 -1 22 24 32 -1 9 33 31 -1 31 33 25 -1 35 11 12 -1 28 27 35 -1 12 36 35 -1 35 36 28 -1 36 12 13 -1 29 28 36 -1 13 37 36 -1 36 37 29 -1 16 38 22 -1 24 22 38 -1 38 17 24 -1 28 29 39 -1 39 21 28 -1 40 26 19 -1 40 19 25 -1 41 33 9 -1 25 33 41 -1 41 40 25 -1 3 10 42 -1 3 42 9 -1 9 42 41 -1 43 11 35 -1 34 44 43 -1 11 43 44 -1 44 10 11 -1 45 44 34 -1 10 44 45 -1 45 42 10 -1 34 46 45 -1 42 45 46 -1 46 41 42 -1 41 46 47 -1 47 40 41 -1 46 34 48 -1 48 47 46 -1 40 47 48 -1 48 26 40 -1 49 48 34 -1 26 48 49 -1 49 27 26 -1 43 50 34 -1 34 50 49 -1 35 50 43 -1 27 49 50 -1 50 35 27 -1'>
|
||||||
|
<Coordinate point='-24.12 20.08 -17.52 -17.39 20.1 -33.04 -29.73 20.1 -4.018 -28.6 20.1 5.862 -25.16 20.1 9.376 -22.97 20.1 31.0 -24.16 47.77 -27.94 -33.12 47.77 -21.26 -23.84 47.77 -31.96 -38.45 47.77 -6.731 -35.75 47.77 5.233 -31.04 47.77 8.073 -30.39 47.77 33.01 -23.48 47.77 39.63 -17.39 20.09 -26.84 -16.1 20.1 37.05 -24.12 159.5 -17.52 -17.39 159.5 -33.04 -29.73 159.5 -4.018 -28.6 159.5 5.862 -25.16 159.5 9.376 -22.88 159.6 31.71 -24.16 131.8 -27.94 -33.12 131.8 -21.26 -23.84 131.8 -31.96 -38.45 131.8 -6.731 -35.75 131.8 5.233 -31.04 131.8 8.073 -30.39 135.6 33.54 -23.48 131.8 39.63 -24.16 90.9 -27.94 -33.12 90.9 -21.26 -23.84 90.9 -31.96 -38.45 90.9 -6.731 -32.02 90.91 1.202 -31.04 90.9 6.098 -30.39 90.9 30.77 -23.48 90.9 39.63 -17.39 159.5 -26.84 -16.1 159.5 37.05 -36.66 131.8 1.207 -36.66 90.9 -0.7638 -36.66 47.77 1.216 -30.44 48.64 5.147 -31.14 48.67 2.66 -33.73 48.72 1.514 -33.73 90.9 -0.4213 -33.74 130.9 1.503 -31.14 130.9 2.658 -30.44 131.0 5.145 -30.44 90.91 3.216'/>
|
||||||
|
<TextureCoordinate point='0.9473 0.8207 0.9473 0.7762 0.9473 0.8595 0.9473 0.8892 0.9473 0.9004 0.9473 0.9652 0.8732 0.7897 0.8732 0.8075 0.8732 0.7779 0.8732 0.8494 0.8732 0.8856 0.8732 0.8952 0.8732 0.9694 0.8732 0.9907 0.9473 0.7946 0.9473 0.9848 0.5742 0.8207 0.5742 0.7762 0.5742 0.8595 0.5742 0.8892 0.5742 0.9004 0.5739 0.9673 0.6483 0.7897 0.6483 0.8075 0.6483 0.7779 0.6483 0.8494 0.6483 0.8856 0.6483 0.8952 0.6382 0.971 0.6483 0.9907 0.7578 0.7897 0.7578 0.8075 0.7578 0.7779 0.7578 0.8494 0.7578 0.8745 0.7578 0.8893 0.7578 0.9628 0.7578 0.9907 0.5742 0.7946 0.5742 0.9848 0.6483 0.8734 0.7578 0.8676 0.8732 0.8735 0.8709 0.8866 0.8708 0.879 0.8707 0.875 0.7578 0.8693 0.6508 0.875 0.6507 0.879 0.6506 0.8866 0.7578 0.8809'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='0.0 0.215692 -0.976462 3.142' scale='0.8311 0.8484 0.7947' scaleOrientation='1.0 0.0 0.0 0.4348' translation='-113.2 60.44 -45.87'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='0.0' diffuseColor='0.2431 0.2431 0.2431' shininess='0.145'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='0 2 3 -1 3 1 0 -1 4 5 7 -1 7 6 4 -1 0 1 9 -1 5 4 0 -1 1 3 8 -1 47 46 49 -1 3 2 6 -1 6 8 3 -1 2 0 4 -1 4 6 2 -1 1 8 9 -1 6 7 8 -1 49 48 47 -1 0 9 5 -1 7 5 10 -1 10 11 7 -1 5 9 13 -1 13 10 5 -1 9 8 12 -1 12 13 9 -1 8 7 11 -1 11 12 8 -1 11 10 14 -1 14 15 11 -1 10 13 17 -1 17 14 10 -1 13 12 16 -1 16 17 13 -1 12 11 15 -1 15 16 12 -1 15 14 18 -1 18 19 15 -1 14 17 21 -1 21 18 14 -1 17 16 20 -1 20 21 17 -1 16 15 19 -1 19 20 16 -1 19 18 22 -1 22 23 19 -1 18 21 25 -1 25 22 18 -1 27 26 28 -1 28 29 27 -1 20 19 23 -1 23 24 20 -1 24 25 29 -1 29 28 24 -1 21 20 26 -1 26 27 21 -1 25 21 27 -1 27 29 25 -1 20 24 28 -1 28 26 20 -1 23 22 30 -1 30 31 23 -1 22 25 33 -1 33 30 22 -1 25 24 32 -1 32 33 25 -1 24 23 31 -1 31 32 24 -1 31 30 34 -1 34 35 31 -1 30 33 37 -1 37 34 30 -1 33 32 36 -1 36 37 33 -1 32 31 35 -1 35 36 32 -1 35 34 38 -1 38 39 35 -1 34 37 41 -1 41 38 34 -1 37 36 40 -1 40 41 37 -1 36 35 39 -1 39 40 36 -1 39 38 42 -1 42 43 39 -1 38 41 45 -1 45 42 38 -1 41 40 44 -1 44 45 41 -1 40 39 43 -1 43 44 40 -1 43 42 46 -1 46 47 43 -1 42 45 49 -1 49 46 42 -1 45 44 48 -1 48 49 45 -1 44 43 47 -1 47 48 44 -1'>
|
||||||
|
<Coordinate point='10.28 5.649 -1.264 -7.151 3.257 -1.346 10.28 5.649 1.52 -7.151 3.257 1.437 5.75 0.5812 -0.8577 -5.328 -2.493 -0.575 5.75 0.5812 0.8577 -5.328 -2.493 0.561 -6.461 0.7407 1.127 -6.456 0.732 -1.126 -12.0 -3.886 -0.561 -12.0 -3.886 0.575 -12.29 -1.372 0.7365 -12.29 -1.38 -0.7554 -20.91 -4.678 -0.5802 -20.91 -4.678 0.5558 -21.2 -2.298 0.734 -21.2 -2.306 -0.7578 -36.08 -5.824 -0.5828 -36.08 -5.824 0.5532 -36.36 -3.226 0.7314 -36.36 -3.234 -0.7604 -42.48 -6.135 -0.5947 -42.48 -6.135 0.5413 -42.77 -3.538 0.7196 -42.77 -3.545 -0.7723 -36.38 0.5337 1.104 -36.38 0.5264 -1.149 -43.03 0.497 1.101 -43.02 0.4897 -1.151 -85.7 -6.587 -0.5009 -85.7 -6.587 0.635 -85.98 -4.373 0.7865 -85.98 -4.38 -0.7053 -122.6 -4.126 -0.4483 -122.6 -4.126 0.6876 -122.2 -2.069 0.8659 -122.2 -2.077 -0.6259 -130.9 -3.057 -0.4504 -130.9 -3.057 0.6856 -128.1 -1.094 0.8639 -128.1 -1.103 -0.628 -137.5 -0.9042 -0.4521 -137.5 -0.9042 0.6839 -130.1 0.004005 0.8622 -130.1 -0.008795 -0.6297 -143.1 4.839 -0.6669 -143.1 4.839 1.048 -130.5 2.575 1.233 -130.5 2.562 -1.02'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='-0.999993 0.00261798 0.00261798 1.571' scale='0.4124 0.7947 0.8484' scaleOrientation='0.0 0.0 -1.0 0.00521342' translation='8.795 61.86 -30.11'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='1.0' diffuseColor='0.0 0.0 0.0' shininess='0.145'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='0 2 3 -1 3 1 0 -1 4 5 7 -1 7 6 4 -1 1 3 7 -1 7 5 1 -1 3 2 6 -1 6 7 3 -1 8 9 2 -1 2 0 8 -1 10 11 4 -1 4 6 10 -1 9 10 6 -1 6 2 9 -1'>
|
||||||
|
<Coordinate point='-0.3273 0.0 -3.53 -8.307 0.0 -3.53 0.6075 -0.923 2.247 -7.358 -0.923 1.849 -0.3273 -4.154 -3.53 -8.307 -4.154 -3.53 0.6075 -3.231 2.247 -7.358 -3.231 1.849 7.668 0.0 -1.871 7.668 -0.923 0.1461 7.668 -3.231 0.1461 7.668 -4.154 -1.871'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='-0.473894 0.74059 0.476394 1.872' scale='0.9298 0.9724 0.9927' scaleOrientation='-0.999924 -0.00261706 -0.0120603 0.4276' translation='33.48 20.12 30.93'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='0.0' diffuseColor='0.2353 0.2353 0.2353' shininess='0.145'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='0 6 5 -1 0 1 6 -1 1 7 6 -1 1 2 7 -1 2 8 7 -1 2 3 8 -1 3 9 8 -1 3 4 9 -1 4 5 9 -1 4 0 5 -1 5 11 10 -1 5 6 11 -1 6 12 11 -1 6 7 12 -1 7 13 12 -1 7 8 13 -1 8 14 13 -1 8 9 14 -1 9 10 14 -1 9 5 10 -1 10 16 15 -1 10 11 16 -1 11 17 16 -1 11 12 17 -1 12 18 17 -1 12 13 18 -1 13 19 18 -1 13 14 19 -1 14 15 19 -1 14 10 15 -1 15 21 20 -1 15 16 21 -1 16 22 21 -1 16 17 22 -1 17 23 22 -1 17 18 23 -1 18 24 23 -1 18 19 24 -1 19 20 24 -1 19 15 20 -1 20 26 25 -1 20 21 26 -1 21 27 26 -1 21 22 27 -1 22 28 27 -1 22 23 28 -1 23 29 28 -1 23 24 29 -1 24 25 29 -1 24 20 25 -1 25 31 30 -1 25 26 31 -1 26 32 31 -1 26 27 32 -1 27 33 32 -1 27 28 33 -1 28 34 33 -1 28 29 34 -1 29 30 34 -1 29 25 30 -1 30 36 35 -1 30 31 36 -1 31 37 36 -1 31 32 37 -1 32 38 37 -1 32 33 38 -1 33 39 38 -1 33 34 39 -1 34 35 39 -1 34 30 35 -1 35 41 40 -1 35 36 41 -1 36 42 41 -1 36 37 42 -1 37 43 42 -1 37 38 43 -1 38 44 43 -1 38 39 44 -1 39 40 44 -1 39 35 40 -1 40 46 45 -1 40 41 46 -1 41 47 46 -1 41 42 47 -1 42 48 47 -1 42 43 48 -1 43 49 48 -1 43 44 49 -1 44 45 49 -1 44 40 45 -1 45 51 50 -1 45 46 51 -1 46 52 51 -1 46 47 52 -1 47 53 52 -1 47 48 53 -1 48 54 53 -1 48 49 54 -1 49 50 54 -1 49 45 50 -1 50 56 55 -1 50 51 56 -1 51 57 56 -1 51 52 57 -1 52 58 57 -1 52 53 58 -1 53 59 58 -1 53 54 59 -1 54 55 59 -1 54 50 55 -1 60 1 0 -1 60 2 1 -1 60 3 2 -1 60 4 3 -1 60 0 4 -1 61 55 56 -1 61 56 57 -1 61 57 58 -1 61 58 59 -1 61 59 55 -1'>
|
||||||
|
<Coordinate point='15.36 0.0 -1.209 14.3 -1.464 -1.126 12.59 -0.905 -0.9907 12.59 0.905 -0.9907 14.3 1.464 -1.126 15.06 0.0 3.264 14.02 -1.464 3.039 12.34 -0.905 2.674 12.34 0.905 2.674 14.02 1.464 3.039 13.49 0.0 7.461 12.55 -1.464 6.946 11.05 -0.905 6.113 11.05 0.905 6.113 12.55 1.464 6.946 10.77 0.0 11.03 10.02 -1.464 10.27 8.822 -0.905 9.034 8.822 0.905 9.034 10.02 1.464 10.27 7.138 0.0 13.66 6.645 -1.464 12.72 5.848 -0.905 11.19 5.848 0.905 11.19 6.645 1.464 12.72 2.905 0.0 15.14 2.704 -1.464 14.09 2.38 -0.905 12.4 2.38 0.905 12.4 2.704 1.464 14.09 -1.575 0.0 15.33 -1.466 -1.464 14.27 -1.29 -0.905 12.56 -1.29 0.905 12.56 -1.466 1.464 14.27 -5.921 0.0 14.23 -5.512 -1.464 13.25 -4.851 -0.905 11.66 -4.851 0.905 11.66 -5.512 1.464 13.25 -9.766 0.0 11.92 -9.091 -1.464 11.1 -8.001 -0.905 9.769 -8.001 0.905 9.769 -9.091 1.464 11.1 -12.78 0.0 8.608 -11.9 -1.464 8.014 -10.47 -0.905 7.053 -10.47 0.905 7.053 -11.9 1.464 8.014 -14.72 0.0 4.565 -13.7 -1.464 4.249 -12.06 -0.905 3.74 -12.06 0.905 3.74 -13.7 1.464 4.249 -15.41 0.0 0.1345 -14.35 -1.464 0.1252 -12.63 -0.905 0.1102 -12.63 0.905 0.1102 -14.35 1.464 0.1252 13.83 0.0 -1.088 -13.87 0.0 0.1211'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='-1.0 0.0 0.0 0.4348' scale='0.8311 0.8484 0.7947' scaleOrientation='1.0 0.0 0.0 0.4348' translation='-113.2 60.44 45.45'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='0.0' diffuseColor='0.2431 0.2431 0.2431' shininess='0.145'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='0 2 3 -1 3 1 0 -1 4 5 7 -1 7 6 4 -1 0 1 9 -1 5 4 0 -1 1 3 8 -1 47 46 49 -1 3 2 6 -1 6 8 3 -1 2 0 4 -1 4 6 2 -1 1 8 9 -1 6 7 8 -1 49 48 47 -1 0 9 5 -1 7 5 10 -1 10 11 7 -1 5 9 13 -1 13 10 5 -1 9 8 12 -1 12 13 9 -1 8 7 11 -1 11 12 8 -1 11 10 14 -1 14 15 11 -1 10 13 17 -1 17 14 10 -1 13 12 16 -1 16 17 13 -1 12 11 15 -1 15 16 12 -1 15 14 18 -1 18 19 15 -1 14 17 21 -1 21 18 14 -1 17 16 20 -1 20 21 17 -1 16 15 19 -1 19 20 16 -1 19 18 22 -1 22 23 19 -1 18 21 25 -1 25 22 18 -1 27 26 28 -1 28 29 27 -1 20 19 23 -1 23 24 20 -1 24 25 29 -1 29 28 24 -1 21 20 26 -1 26 27 21 -1 25 21 27 -1 27 29 25 -1 20 24 28 -1 28 26 20 -1 23 22 30 -1 30 31 23 -1 22 25 33 -1 33 30 22 -1 25 24 32 -1 32 33 25 -1 24 23 31 -1 31 32 24 -1 31 30 34 -1 34 35 31 -1 30 33 37 -1 37 34 30 -1 33 32 36 -1 36 37 33 -1 32 31 35 -1 35 36 32 -1 35 34 38 -1 38 39 35 -1 34 37 41 -1 41 38 34 -1 37 36 40 -1 40 41 37 -1 36 35 39 -1 39 40 36 -1 39 38 42 -1 42 43 39 -1 38 41 45 -1 45 42 38 -1 41 40 44 -1 44 45 41 -1 40 39 43 -1 43 44 40 -1 43 42 46 -1 46 47 43 -1 42 45 49 -1 49 46 42 -1 45 44 48 -1 48 49 45 -1 44 43 47 -1 47 48 44 -1'>
|
||||||
|
<Coordinate point='-10.28 -5.649 1.264 7.151 -3.257 1.346 -10.28 -5.649 -1.52 7.151 -3.257 -1.437 -5.75 -0.5812 0.8577 5.328 2.493 0.575 -5.75 -0.5812 -0.8577 5.328 2.493 -0.561 6.461 -0.7407 -1.127 6.456 -0.732 1.126 12.0 3.886 0.561 12.0 3.886 -0.575 12.29 1.372 -0.7365 12.29 1.38 0.7554 20.91 4.678 0.5802 20.91 4.678 -0.5558 21.2 2.298 -0.734 21.2 2.306 0.7578 36.08 5.824 0.5828 36.08 5.824 -0.5532 36.36 3.226 -0.7314 36.36 3.234 0.7604 42.48 6.135 0.5947 42.48 6.135 -0.5413 42.77 3.538 -0.7196 42.77 3.545 0.7723 36.38 -0.5337 -1.104 36.38 -0.5264 1.149 43.03 -0.497 -1.101 43.02 -0.4897 1.151 85.7 6.587 0.5009 85.7 6.587 -0.635 85.98 4.373 -0.7865 85.98 4.38 0.7053 122.6 4.126 0.4483 122.6 4.126 -0.6876 122.2 2.069 -0.8659 122.2 2.077 0.6259 130.9 3.057 0.4504 130.9 3.057 -0.6856 128.1 1.094 -0.8639 128.1 1.103 0.628 137.5 0.9042 0.4521 137.5 0.9042 -0.6839 130.1 -0.004005 -0.8622 130.1 0.008795 0.6297 143.1 -4.839 0.6669 143.1 -4.839 -1.048 130.5 -2.575 -1.233 130.5 -2.562 1.02'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform scale='0.8311 0.8484 0.7947' translation='18.78 2.128 15.21'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='0.0' diffuseColor='0.2431 0.2431 0.2431' shininess='0.145'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='0 2 3 -1 3 1 0 -1 0 1 5 -1 5 4 0 -1 1 3 7 -1 7 5 1 -1 3 2 6 -1 6 7 3 -1 2 0 4 -1 4 6 2 -1' solid='false'>
|
||||||
|
<Coordinate point='-190.0 -47.32 53.25 140.9 -54.86 49.24 -190.0 -47.32 -85.16 140.9 -54.86 -89.17 -188.1 19.41 53.25 136.9 1.872 49.24 -188.1 19.41 -85.16 136.9 1.872 -89.17'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='0.0 0.707107 0.707107 3.142' scale='0.8311 0.7947 0.8484' translation='133.8 -18.08 -71.34'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='1.0' diffuseColor='0.5882 0.5882 0.5882' shininess='0.145'/>
|
||||||
|
<ImageTexture url='"textures/ChevyTahoeTexture.jpg" "https://savage.nps.edu/Savage/GroundVehicles/Chevy/textures/ChevyTahoeTexture.jpg"'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet ccw='false' coordIndex='7 0 1 -1 1 2 7 -1 8 7 2 -1 2 3 8 -1 9 8 3 -1 3 4 9 -1 10 9 4 -1 4 5 10 -1 11 10 5 -1 5 6 11 -1 2 1 19 -1 19 20 2 -1 3 2 20 -1 20 21 3 -1 4 3 21 -1 21 22 4 -1 5 4 22 -1 22 23 5 -1 6 5 23 -1 23 24 6 -1 25 14 13 -1 13 12 25 -1 26 15 14 -1 14 25 26 -1 27 16 15 -1 15 26 27 -1 28 17 16 -1 16 27 28 -1 29 18 17 -1 17 28 29 -1 14 20 19 -1 19 13 14 -1 15 21 20 -1 20 14 15 -1 16 22 21 -1 21 15 16 -1 17 23 22 -1 22 16 17 -1 18 24 23 -1 23 17 18 -1' creaseAngle='2.0' texCoordIndex='7 0 1 -1 1 2 7 -1 8 7 2 -1 2 3 8 -1 9 8 3 -1 3 4 9 -1 10 9 4 -1 4 5 10 -1 11 10 5 -1 5 6 11 -1 2 1 19 -1 19 20 2 -1 3 2 20 -1 20 21 3 -1 4 3 21 -1 21 22 4 -1 5 4 22 -1 22 23 5 -1 6 5 23 -1 23 24 6 -1 25 14 13 -1 13 12 25 -1 26 15 14 -1 14 25 26 -1 27 16 15 -1 15 26 27 -1 28 17 16 -1 16 27 28 -1 29 18 17 -1 17 28 29 -1 14 20 19 -1 19 13 14 -1 15 21 20 -1 20 14 15 -1 16 22 21 -1 21 15 16 -1 17 23 22 -1 22 16 17 -1 18 24 23 -1 23 17 18 -1'>
|
||||||
|
<Coordinate point='125.3 28.22 83.92 121.9 47.81 86.29 147.8 47.78 92.45 232.3 47.78 94.88 276.6 47.78 94.48 302.7 47.81 92.61 330.8 47.81 86.8 149.8 27.74 89.8 231.6 26.37 91.29 275.6 26.32 90.92 301.5 28.93 88.77 329.4 28.39 82.73 125.3 151.4 83.92 121.9 131.8 86.29 147.8 131.8 92.45 232.3 131.8 94.88 276.6 131.8 94.48 302.7 131.8 92.61 330.8 131.8 86.8 122.0 90.9 88.18 147.8 90.9 92.45 232.3 90.9 94.88 276.6 90.9 94.48 302.7 90.9 92.61 330.8 90.9 86.8 149.8 151.9 89.8 231.6 153.2 91.29 275.6 153.3 90.92 301.5 150.7 88.77 329.4 151.2 82.73'/>
|
||||||
|
<TextureCoordinate point='0.5115 0.7006 0.5192 0.656 0.4602 0.6561 0.2682 0.6561 0.1674 0.6561 0.108 0.656 0.04401 0.656 0.4558 0.7017 0.2697 0.7048 0.1697 0.7049 0.1107 0.699 0.04726 0.7002 0.5115 0.4204 0.5192 0.465 0.4602 0.4649 0.2682 0.4649 0.1674 0.4649 0.108 0.465 0.04401 0.465 0.519 0.558 0.4602 0.558 0.2682 0.558 0.1674 0.558 0.108 0.558 0.04401 0.558 0.4558 0.4193 0.2697 0.4162 0.1697 0.4161 0.1107 0.422 0.04726 0.4208'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='0.0 -0.707107 -0.707107 3.142' scale='0.8311 0.7947 0.8484' translation='133.8 -18.08 -71.34'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='1.0' diffuseColor='0.5882 0.5882 0.5882' shininess='0.145'/>
|
||||||
|
<ImageTexture url='"textures/ChevyTahoeTexture.jpg" "https://savage.nps.edu/Savage/GroundVehicles/Chevy/textures/ChevyTahoeTexture.jpg"'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='10 11 8 -1 11 10 13 -1 13 14 11 -1 5 14 13 -1 13 4 5 -1 2 5 4 -1 4 1 2 -1 1 4 3 -1 12 3 4 -1 4 13 12 -1 12 13 10 -1 10 9 12 -1 9 10 7 -1 8 7 10 -1 7 6 9 -1 3 0 1 -1' creaseAngle='2.0' texCoordIndex='10 11 8 -1 11 10 13 -1 13 14 11 -1 5 14 13 -1 13 4 5 -1 2 5 4 -1 4 1 2 -1 1 4 3 -1 12 3 4 -1 4 13 12 -1 12 13 10 -1 10 9 12 -1 9 10 7 -1 8 7 10 -1 7 6 9 -1 3 0 1 -1'>
|
||||||
|
<Coordinate point='79.01 20.1 48.32 103.2 23.96 68.61 125.3 28.22 83.92 73.17 47.77 52.4 100.2 47.77 71.11 121.9 47.81 86.29 79.01 159.5 48.32 103.2 155.7 68.61 125.3 151.4 83.92 73.17 131.8 52.4 100.2 131.8 71.11 121.9 131.8 86.29 70.78 90.9 53.88 97.87 90.9 72.72 122.0 90.9 88.18'/>
|
||||||
|
<TextureCoordinate point='0.6844 0.7386 0.6087 0.729 0.5443 0.7184 0.6896 0.6698 0.6107 0.6698 0.5473 0.6697 0.6844 0.3919 0.6087 0.4014 0.5443 0.412 0.6896 0.4607 0.6107 0.4607 0.5473 0.4608 0.6921 0.5625 0.6129 0.5625 0.5445 0.5625'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='0.0 -0.707107 -0.707107 3.142' scale='0.8311 0.7947 0.8484' translation='133.8 -18.08 -71.34'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='1.0' diffuseColor='0.5882 0.5882 0.5882' shininess='0.145'/>
|
||||||
|
<ImageTexture url='"textures/ChevyTahoeTexture.jpg" "https://savage.nps.edu/Savage/GroundVehicles/Chevy/textures/ChevyTahoeTexture.jpg"'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='13 14 10 -1 14 13 17 -1 17 18 14 -1 16 17 13 -1 5 17 16 -1 16 4 5 -1 17 5 6 -1 6 18 17 -1 2 6 5 -1 1 5 4 -1 5 1 2 -1 4 0 1 -1 0 4 3 -1 15 3 4 -1 4 16 15 -1 13 12 16 -1 15 16 12 -1 12 11 15 -1 11 12 8 -1 8 19 11 -1 12 13 9 -1 10 9 13 -1 9 8 12 -1 3 7 0 -1' creaseAngle='3.0' texCoordIndex='13 14 10 -1 14 13 17 -1 17 18 14 -1 16 17 13 -1 5 17 16 -1 16 4 5 -1 17 5 6 -1 6 18 17 -1 2 6 5 -1 1 5 4 -1 5 1 2 -1 4 0 1 -1 0 4 3 -1 15 3 4 -1 4 16 15 -1 13 12 16 -1 15 16 12 -1 12 11 15 -1 11 12 8 -1 8 19 11 -1 12 13 9 -1 10 9 13 -1 9 8 12 -1 3 7 0 -1'>
|
||||||
|
<Coordinate point='12.36 20.1 44.84 43.16 20.1 46.3 79.01 20.1 48.32 -23.48 47.77 39.63 5.52 47.77 47.19 42.21 47.77 51.55 73.17 47.77 52.4 -16.1 20.1 37.05 12.36 159.5 44.84 43.16 159.5 46.3 79.01 159.5 48.32 -23.48 131.8 39.63 5.52 131.8 47.19 42.21 131.8 51.55 73.17 131.8 52.4 -23.48 90.9 39.63 5.52 90.9 47.19 42.21 90.9 51.55 70.78 90.9 53.88 -16.1 159.5 37.05'/>
|
||||||
|
<TextureCoordinate point='0.8807 0.7337 0.8107 0.7337 0.7291 0.7337 0.9622 0.6707 0.8963 0.6707 0.8128 0.6707 0.7424 0.6707 0.9454 0.7337 0.8807 0.4165 0.8107 0.4165 0.7291 0.4165 0.9622 0.4795 0.8963 0.4795 0.8128 0.4795 0.7424 0.4795 0.9622 0.5726 0.8963 0.5726 0.8128 0.5726 0.7479 0.5726 0.9454 0.4165'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='-0.605206 0.562906 0.562906 2.053' scale='0.7947 0.8311 0.8484' scaleOrientation='-4.317E-5 0.0 1.0 0.0722696' translation='38.31 25.25 -64.47'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='1.0' diffuseColor='0.5882 0.5882 0.5882' shininess='0.145'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet ccw='false' coordIndex='0 2 3 -1 0 3 1 -1 0 4 5 -1 0 5 6 -1 0 6 7 -1 0 7 2 -1 2 7 8 -1 2 8 9 -1 2 9 3 -1 3 9 10 -1 3 10 1 -1 1 4 0 -1 4 11 12 -1 4 12 5 -1 5 12 13 -1 5 13 6 -1 6 13 14 -1 6 14 7 -1 7 14 15 -1 7 15 8 -1 8 15 16 -1 8 16 9 -1 10 17 18 -1 10 18 1 -1 1 18 19 -1 1 19 11 -1 1 11 4 -1 13 20 14 -1 14 20 15 -1' creaseAngle='2.0' solid='false'>
|
||||||
|
<Coordinate point='5.819 -8.879 7.786 -1.262 -12.53 11.05 8.114 -9.076 1.355 -1.022 -14.67 0.9557 4.43 -8.357 10.65 6.934 -6.375 8.467 8.242 -6.0 5.673 9.356 -5.915 1.611 8.47 -5.914 -0.6059 -3.349 -12.46 -1.298 -4.536 -13.34 0.6932 4.691 -4.076 11.17 7.786 -2.141 8.832 9.067 -1.267 5.673 10.43 -0.421 1.611 8.515 -0.2266 -1.713 -6.767 -8.148 -1.739 -8.222 -9.224 0.6932 -7.483 -9.836 10.84 -4.182 -8.951 12.28 10.43 -0.411 1.611'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='-0.575282 0.578382 0.578382 2.097' scale='0.7947 0.8311 0.8484' scaleOrientation='4.092E-4 2.421E-4 -1.0 0.00525895' translation='37.23 25.25 -63.71'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='0.0' diffuseColor='0.01961 0.01961 0.01961' shininess='0.145'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='4 6 7 -1 4 7 5 -1 1 0 4 -1 4 5 1 -1 0 2 6 -1 6 4 0 -1 2 3 7 -1 7 6 2 -1 3 1 5 -1 5 7 3 -1'>
|
||||||
|
<Coordinate point='-3.71 -13.89 -1.372 -4.542 -14.5 1.889 -7.272 -9.686 -1.737 -8.225 -10.39 0.6932 -8.82 -17.06 -6.148 -9.652 -17.68 2.293 -12.37 -10.95 -6.513 -13.34 -13.57 2.293'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='0.0 -0.707107 -0.707107 3.142' scale='0.8311 0.7947 0.8484' translation='133.8 -18.08 -71.34'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='1.0' diffuseColor='0.5882 0.5882 0.5882' shininess='0.145'/>
|
||||||
|
<ImageTexture url='"textures/ChevyTahoeTexture.jpg" "https://savage.nps.edu/Savage/GroundVehicles/Chevy/textures/ChevyTahoeTexture.jpg"'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet ccw='false' coordIndex='10 13 2 -1 2 3 10 -1 13 14 4 -1 4 2 13 -1 0 10 3 -1 3 5 0 -1 1 0 5 -1 5 6 1 -1 15 1 6 -1 6 7 15 -1 11 15 7 -1 40 8 11 -1 12 11 8 -1 8 9 12 -1 3 2 26 -1 26 27 3 -1 2 4 28 -1 28 26 2 -1 5 3 27 -1 27 29 5 -1 6 5 29 -1 29 30 6 -1 44 43 47 -1 47 31 44 -1 8 40 41 -1 41 32 8 -1 9 8 32 -1 32 33 9 -1 34 19 18 -1 18 37 34 -1 37 18 20 -1 20 38 37 -1 16 21 19 -1 19 34 16 -1 17 22 21 -1 21 16 17 -1 39 23 22 -1 22 17 39 -1 35 24 42 -1 23 39 35 -1 36 25 24 -1 24 35 36 -1 19 27 26 -1 26 18 19 -1 18 26 28 -1 28 20 18 -1 21 29 27 -1 27 19 21 -1 22 30 29 -1 29 21 22 -1 46 31 47 -1 47 45 46 -1 24 32 41 -1 31 46 50 -1 25 33 32 -1 32 24 25 -1 48 44 31 -1 7 40 11 -1 31 49 48 -1 24 41 42 -1 50 49 31 -1 35 42 23 -1 7 6 43 -1 43 44 7 -1 6 30 47 -1 47 43 6 -1 41 40 48 -1 48 49 41 -1 22 23 46 -1 46 45 22 -1 30 22 45 -1 45 47 30 -1 23 42 50 -1 50 46 23 -1 40 7 44 -1 44 48 40 -1 42 41 49 -1 49 50 42 -1' creaseAngle='2.0' texCoordIndex='10 13 2 -1 2 3 10 -1 13 14 4 -1 4 2 13 -1 0 10 3 -1 3 5 0 -1 1 0 5 -1 5 6 1 -1 15 1 6 -1 6 7 15 -1 11 15 7 -1 40 8 11 -1 12 11 8 -1 8 9 12 -1 3 2 26 -1 26 27 3 -1 2 4 28 -1 28 26 2 -1 5 3 27 -1 27 29 5 -1 6 5 29 -1 29 30 6 -1 44 43 47 -1 47 31 44 -1 8 40 41 -1 41 32 8 -1 9 8 32 -1 32 33 9 -1 34 19 18 -1 18 37 34 -1 37 18 20 -1 20 38 37 -1 16 21 19 -1 19 34 16 -1 17 22 21 -1 21 16 17 -1 39 23 22 -1 22 17 39 -1 35 24 42 -1 23 39 35 -1 36 25 24 -1 24 35 36 -1 19 27 26 -1 26 18 19 -1 18 26 28 -1 28 20 18 -1 21 29 27 -1 27 19 21 -1 22 30 29 -1 29 21 22 -1 46 31 47 -1 47 45 46 -1 24 32 41 -1 31 46 50 -1 25 33 32 -1 32 24 25 -1 48 44 31 -1 7 40 11 -1 31 49 48 -1 24 41 42 -1 50 49 31 -1 35 42 23 -1 7 6 43 -1 43 44 7 -1 6 30 47 -1 47 43 6 -1 41 40 48 -1 48 49 41 -1 22 23 46 -1 46 45 22 -1 30 22 45 -1 45 47 30 -1 23 42 50 -1 50 46 23 -1 40 7 44 -1 44 48 40 -1 42 41 49 -1 49 50 42 -1'>
|
||||||
|
<Coordinate point='354.0 20.11 27.32 351.9 21.6 12.56 339.8 47.77 75.17 353.5 47.77 49.49 330.8 47.81 86.8 355.6 47.77 26.88 353.6 34.16 11.24 360.3 30.16 7.567 360.4 29.95 -10.42 350.8 47.74 -20.28 351.9 20.1 48.74 358.7 20.11 -7.922 349.2 17.22 -18.78 338.2 24.09 73.88 329.4 28.39 82.73 358.6 20.1 9.221 354.0 159.5 27.32 351.9 158.0 12.56 339.8 131.8 75.17 353.5 131.8 49.49 330.8 131.8 86.8 355.6 131.8 26.88 353.6 145.5 11.24 360.3 151.0 7.567 360.4 145.7 -10.42 350.8 131.9 -20.28 339.8 90.9 75.17 353.5 90.9 49.49 330.8 90.9 86.8 355.6 90.9 26.88 353.6 90.9 11.24 350.9 90.9 -1.02 360.4 90.9 -12.47 350.8 90.9 -21.03 351.9 159.5 48.74 358.7 159.5 -7.922 349.2 162.4 -18.78 338.2 155.5 73.88 329.4 151.2 82.73 358.6 159.5 9.221 360.4 30.08 -6.154 360.4 91.77 -8.546 360.4 151.1 -5.923 352.9 34.16 5.957 350.9 34.1 -1.02 352.9 145.5 5.957 350.9 145.5 -1.02 352.9 90.9 5.957 348.7 34.03 -5.665 348.7 90.9 -8.057 348.7 145.6 -5.434'/>
|
||||||
|
<TextureCoordinate point='0.09429 0.842 0.09801 0.8085 0.1632 0.9636 0.1632 0.8945 0.1633 0.9966 0.1632 0.8399 0.1293 0.8043 0.1193 0.7915 0.1188 0.749 0.1631 0.7317 0.09426 0.8938 0.0943 0.7559 0.08709 0.7363 0.1042 0.9615 0.1149 0.9879 0.09427 0.7964 0.4413 0.842 0.4376 0.8085 0.3725 0.9636 0.3725 0.8945 0.3724 0.9966 0.3725 0.8399 0.4064 0.8043 0.4202 0.7915 0.407 0.749 0.3726 0.7317 0.2705 0.9636 0.2705 0.8945 0.2705 0.9966 0.2705 0.8399 0.2705 0.8043 0.2705 0.7771 0.2705 0.7442 0.2705 0.7299 0.4414 0.8938 0.4413 0.7559 0.4485 0.7363 0.4314 0.9615 0.4207 0.9879 0.4414 0.7964 0.1191 0.7591 0.2727 0.7535 0.4204 0.7596 0.1293 0.7923 0.1291 0.7771 0.4064 0.7923 0.4065 0.7771 0.2705 0.7923 0.1289 0.7675 0.2705 0.7619 0.4067 0.7681'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='0.0 -0.707107 -0.707107 3.142' scale='0.8311 0.7947 0.8484' translation='133.8 -18.08 -71.34'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='1.0' diffuseColor='0.5882 0.5882 0.5882' shininess='0.145'/>
|
||||||
|
<ImageTexture url='"textures/ChevyTahoeTexture.jpg" "https://savage.nps.edu/Savage/GroundVehicles/Chevy/textures/ChevyTahoeTexture.jpg"'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet ccw='false' coordIndex='0 2 98 -1 98 1 0 -1 1 99 4 -1 4 0 1 -1 2 7 100 -1 100 98 2 -1 101 100 7 -1 7 9 59 -1 101 7 59 -1 102 101 59 -1 59 58 65 -1 102 59 65 -1 66 64 125 -1 125 120 66 -1 120 102 65 -1 65 66 120 -1 64 63 104 -1 104 12 64 -1 63 62 105 -1 105 104 63 -1 62 61 107 -1 107 105 62 -1 60 21 20 -1 61 60 20 -1 61 20 106 -1 61 106 107 -1 53 52 96 -1 96 60 53 -1 22 21 60 -1 60 96 22 -1 23 94 95 -1 95 52 23 -1 52 95 93 -1 52 93 92 -1 92 22 96 -1 52 92 96 -1 26 20 21 -1 21 77 78 -1 26 21 78 -1 76 28 27 -1 27 75 76 -1 77 76 75 -1 22 76 77 -1 22 77 21 -1 91 90 28 -1 91 28 76 -1 91 76 22 -1 91 22 92 -1 74 73 79 -1 79 78 74 -1 73 72 80 -1 80 79 73 -1 81 80 72 -1 72 71 81 -1 89 85 122 -1 122 109 81 -1 89 122 81 -1 37 124 123 -1 123 87 37 -1 20 41 112 -1 112 106 20 -1 26 42 41 -1 41 20 26 -1 30 43 42 -1 42 26 30 -1 32 44 43 -1 43 30 32 -1 34 45 44 -1 44 32 34 -1 41 47 114 -1 114 112 41 -1 42 48 47 -1 47 41 42 -1 43 49 48 -1 48 42 43 -1 44 50 49 -1 49 43 44 -1 45 51 50 -1 50 44 45 -1 19 23 52 -1 52 53 19 -1 61 54 53 -1 53 60 61 -1 19 53 54 -1 17 19 54 -1 54 55 17 -1 15 17 55 -1 55 56 15 -1 13 15 56 -1 56 57 13 -1 11 13 57 -1 57 58 11 -1 9 11 58 -1 58 59 9 -1 55 54 61 -1 61 62 55 -1 56 55 62 -1 62 63 56 -1 57 56 63 -1 63 64 57 -1 66 65 58 -1 64 66 58 -1 64 58 57 -1 69 37 87 -1 70 69 87 -1 70 87 86 -1 84 69 70 -1 70 83 84 -1 83 71 33 -1 33 84 83 -1 33 71 72 -1 31 33 72 -1 72 73 31 -1 27 31 73 -1 73 74 27 -1 77 75 74 -1 74 78 77 -1 74 75 27 -1 30 26 78 -1 78 79 30 -1 32 30 79 -1 79 80 32 -1 81 109 34 -1 80 81 34 -1 80 34 32 -1 86 68 122 -1 122 85 86 -1 89 83 70 -1 85 89 70 -1 85 70 86 -1 36 68 86 -1 86 87 36 -1 38 36 87 -1 87 123 38 -1 71 83 89 -1 89 81 71 -1 91 92 24 -1 90 91 24 -1 90 24 29 -1 95 94 25 -1 24 92 93 -1 25 24 93 -1 95 25 93 -1 18 107 106 -1 1 98 3 -1 3 97 1 -1 99 1 97 -1 97 5 99 -1 98 100 6 -1 6 3 98 -1 100 101 8 -1 8 6 100 -1 101 102 10 -1 10 8 101 -1 102 120 67 -1 67 10 102 -1 12 104 14 -1 14 103 12 -1 104 105 16 -1 16 14 104 -1 105 107 18 -1 18 16 105 -1 106 112 40 -1 40 18 106 -1 45 34 108 -1 108 113 45 -1 114 47 115 -1 115 46 114 -1 112 114 46 -1 46 40 112 -1 47 48 116 -1 116 115 47 -1 48 49 117 -1 117 116 48 -1 49 50 118 -1 118 117 49 -1 50 51 119 -1 119 118 50 -1 51 45 113 -1 113 119 51 -1 120 125 67 -1 34 109 35 -1 35 108 34 -1 109 122 82 -1 82 35 109 -1 122 68 121 -1 121 82 122 -1 68 36 110 -1 110 121 68 -1 36 38 111 -1 111 110 36 -1 88 123 124 -1 124 39 88 -1 12 125 64 -1 125 12 103 -1 67 125 103 -1' creaseAngle='3.0' texCoordIndex='0 2 98 -1 98 1 0 -1 1 99 4 -1 4 0 1 -1 2 7 100 -1 100 98 2 -1 101 100 7 -1 7 9 59 -1 101 7 59 -1 102 101 59 -1 59 58 65 -1 102 59 65 -1 66 64 125 -1 125 120 66 -1 120 102 65 -1 65 66 120 -1 64 63 104 -1 104 12 64 -1 63 62 105 -1 105 104 63 -1 62 61 107 -1 107 105 62 -1 60 21 20 -1 61 60 20 -1 61 20 106 -1 61 106 107 -1 53 52 96 -1 96 60 53 -1 22 21 60 -1 60 96 22 -1 23 94 95 -1 95 52 23 -1 52 95 93 -1 52 93 92 -1 92 22 96 -1 52 92 96 -1 26 20 21 -1 21 77 78 -1 26 21 78 -1 76 28 27 -1 27 75 76 -1 77 76 75 -1 22 76 77 -1 22 77 21 -1 91 90 28 -1 91 28 76 -1 91 76 22 -1 91 22 92 -1 74 73 79 -1 79 78 74 -1 73 72 80 -1 80 79 73 -1 81 80 72 -1 72 71 81 -1 89 85 122 -1 122 109 81 -1 89 122 81 -1 37 124 123 -1 123 87 37 -1 20 41 112 -1 112 106 20 -1 26 42 41 -1 41 20 26 -1 30 43 42 -1 42 26 30 -1 32 44 43 -1 43 30 32 -1 34 45 44 -1 44 32 34 -1 41 47 114 -1 114 112 41 -1 42 48 47 -1 47 41 42 -1 43 49 48 -1 48 42 43 -1 44 50 49 -1 49 43 44 -1 45 51 50 -1 50 44 45 -1 19 23 52 -1 52 53 19 -1 61 54 53 -1 53 60 61 -1 19 53 54 -1 17 19 54 -1 54 55 17 -1 15 17 55 -1 55 56 15 -1 13 15 56 -1 56 57 13 -1 11 13 57 -1 57 58 11 -1 9 11 58 -1 58 59 9 -1 55 54 61 -1 61 62 55 -1 56 55 62 -1 62 63 56 -1 57 56 63 -1 63 64 57 -1 66 65 58 -1 64 66 58 -1 64 58 57 -1 69 37 87 -1 70 69 87 -1 70 87 86 -1 84 69 70 -1 70 83 84 -1 83 71 33 -1 33 84 83 -1 33 71 72 -1 31 33 72 -1 72 73 31 -1 27 31 73 -1 73 74 27 -1 77 75 74 -1 74 78 77 -1 74 75 27 -1 30 26 78 -1 78 79 30 -1 32 30 79 -1 79 80 32 -1 81 109 34 -1 80 81 34 -1 80 34 32 -1 86 68 122 -1 122 85 86 -1 89 83 70 -1 85 89 70 -1 85 70 86 -1 36 68 86 -1 86 87 36 -1 38 36 87 -1 87 123 38 -1 71 83 89 -1 89 81 71 -1 91 92 24 -1 90 91 24 -1 90 24 29 -1 95 94 25 -1 24 92 93 -1 25 24 93 -1 95 25 93 -1 18 107 106 -1 1 98 3 -1 3 97 1 -1 99 1 97 -1 97 5 99 -1 98 100 6 -1 6 3 98 -1 100 101 8 -1 8 6 100 -1 101 102 10 -1 10 8 101 -1 102 120 67 -1 67 10 102 -1 12 104 14 -1 14 103 12 -1 104 105 16 -1 16 14 104 -1 105 107 18 -1 18 16 105 -1 106 112 40 -1 40 18 106 -1 45 34 108 -1 108 113 45 -1 114 47 115 -1 115 46 114 -1 112 114 46 -1 46 40 112 -1 47 48 116 -1 116 115 47 -1 48 49 117 -1 117 116 48 -1 49 50 118 -1 118 117 49 -1 50 51 119 -1 119 118 50 -1 51 45 113 -1 113 119 51 -1 120 125 67 -1 34 109 35 -1 35 108 34 -1 109 122 82 -1 82 35 109 -1 122 68 121 -1 121 82 122 -1 68 36 110 -1 110 121 68 -1 36 38 111 -1 111 110 36 -1 88 123 124 -1 124 39 88 -1 12 125 64 -1 125 12 103 -1 67 125 103 -1'>
|
||||||
|
<Coordinate point='0.0 163.7 -27.17 -12.52 163.7 -26.53 -0.1354 168.6 -7.924 -24.12 159.5 -17.52 0.0 163.7 -32.4 -17.39 159.5 -33.04 -29.73 159.5 -4.018 1.786 169.9 2.792 -28.6 159.5 5.862 5.594 171.8 8.566 -25.16 159.5 9.376 7.769 171.8 12.3 -9.587 164.6 35.37 16.6 171.8 18.45 12.36 159.5 44.84 31.96 171.8 20.92 43.16 159.5 46.3 54.64 171.8 20.52 79.01 159.5 48.32 65.89 171.8 18.12 162.1 169.5 44.58 160.4 174.7 21.41 160.4 173.9 2.695 72.91 171.8 6.737 162.6 159.1 -29.85 77.87 159.1 -29.94 234.4 169.5 44.58 251.4 174.7 15.63 243.0 173.2 2.695 236.6 159.1 -29.85 274.3 165.1 48.24 275.5 174.7 19.7 299.5 165.1 48.63 298.9 173.1 17.4 347.3 163.8 48.63 354.0 159.5 27.32 353.6 164.7 -7.809 311.0 169.5 -8.593 345.2 166.9 -18.44 311.7 162.0 -24.97 103.2 155.7 68.61 152.6 162.6 79.37 233.1 160.7 78.39 275.0 160.0 77.93 302.9 160.5 76.83 334.3 159.8 74.1 125.3 151.4 83.92 150.7 157.6 86.34 230.8 158.4 87.42 275.3 158.2 87.0 301.8 156.6 85.09 327.0 156.4 79.29 83.08 168.1 4.352 76.3 171.8 17.43 65.4 171.8 23.33 52.19 171.8 26.07 27.66 171.8 25.78 7.89 171.8 21.67 0.2513 171.8 12.06 -1.617 168.1 8.199 82.7 168.1 18.18 71.5 168.1 33.74 48.19 168.1 35.14 20.36 168.1 34.02 -3.75 168.1 32.0 -9.323 169.4 10.92 -6.74 169.7 19.43 -22.88 159.6 31.71 353.9 164.8 6.688 308.8 171.0 4.167 313.7 171.0 6.518 309.3 173.1 18.18 303.4 174.7 25.68 275.2 174.7 28.62 245.7 174.7 24.8 241.8 174.7 17.34 235.9 173.2 2.695 223.5 169.1 18.26 240.7 170.2 33.52 274.8 168.1 37.77 301.8 168.1 35.11 320.2 168.1 25.97 351.9 158.0 12.56 313.3 171.9 11.47 307.3 171.9 11.2 340.6 165.7 11.86 343.3 167.6 5.887 342.8 167.0 -8.378 328.7 165.7 -24.39 320.6 167.6 11.22 239.3 168.7 -17.64 190.2 168.7 -17.58 161.8 169.0 -17.55 132.3 167.8 -17.51 76.18 167.8 -17.45 84.92 167.8 -17.46 88.25 168.4 4.241 -17.39 159.5 -26.84 -19.95 164.4 -15.71 -13.02 163.7 -32.46 -25.35 164.4 -2.898 -23.74 164.4 6.436 -20.42 164.6 9.737 -16.1 159.5 37.05 15.13 165.1 41.19 44.98 165.2 42.42 92.58 164.1 44.84 76.96 164.9 44.13 351.9 159.5 48.74 349.6 164.2 27.21 358.7 159.5 -7.922 349.2 162.4 -18.78 110.3 160.9 67.88 338.2 155.5 73.88 127.8 158.2 79.66 149.8 151.9 89.8 231.6 153.2 91.29 275.6 153.3 90.92 301.5 150.7 88.77 329.4 151.2 82.73 -18.84 165.2 30.05 358.6 159.5 6.785 346.9 163.1 12.38 339.6 166.8 -18.75 311.7 167.8 -16.25 -15.54 165.3 32.16'/>
|
||||||
|
<TextureCoordinate point='0.9253 0.0175 0.9576 0.01922 0.9257 0.06855 0.9876 0.04426 0.9253 0.00337 0.9702 0.002399 1.002 0.08072 0.9207 0.09724 0.9992 0.1074 0.9109 0.1125 0.9903 0.1169 0.9053 0.1226 0.9501 0.1861 0.8825 0.1392 0.8934 0.2126 0.8428 0.1458 0.8139 0.2166 0.7842 0.1448 0.7213 0.222 0.7552 0.1383 0.5068 0.2101 0.5111 0.1466 0.5111 0.09626 0.737 0.1076 0.5056 0.01107 0.7242 0.01083 0.32 0.2101 0.2761 0.1311 0.2978 0.09639 0.3143 0.01107 0.2171 0.2208 0.214 0.142 0.152 0.2218 0.1537 0.1361 0.02865 0.2221 0.01137 0.1653 0.01241 0.06956 0.1222 0.06658 0.03386 0.04047 0.1206 0.02372 0.6588 0.2774 0.5312 0.3053 0.3235 0.303 0.2153 0.3018 0.1431 0.2988 0.06216 0.2915 0.6018 0.3195 0.5361 0.325 0.3292 0.3277 0.2145 0.3266 0.146 0.3218 0.081 0.3061 0.7108 0.1018 0.7283 0.1364 0.7564 0.1523 0.7906 0.1598 0.8539 0.159 0.9049 0.1479 0.9247 0.1219 0.9295 0.1122 0.7118 0.1391 0.7407 0.1811 0.8009 0.1849 0.8727 0.1819 0.935 0.1764 0.9494 0.1193 0.9427 0.1422 0.9844 0.1771 0.01162 0.1087 0.1281 0.1008 0.1154 0.1071 0.1267 0.1382 0.1418 0.1582 0.2147 0.1661 0.291 0.1558 0.301 0.1357 0.3162 0.09639 0.3483 0.1391 0.3038 0.1801 0.2158 0.192 0.146 0.1848 0.09846 0.1601 0.01658 0.1257 0.1164 0.1203 0.1318 0.1196 0.04584 0.1225 0.03881 0.106 0.04007 0.0676 0.07663 0.02462 0.09757 0.1204 0.3074 0.04232 0.4342 0.04247 0.5077 0.04251 0.5836 0.04281 0.7286 0.04299 0.706 0.04296 0.6974 0.1014 0.9702 0.01912 0.9768 0.04827 0.9589 0.003221 0.9908 0.08286 0.9866 0.1081 0.978 0.1169 0.9669 0.1916 0.8862 0.2018 0.8092 0.2051 0.6863 0.2118 0.7266 0.2097 0.0167 0.2231 0.02271 0.1642 -9.659E-4 0.07019 0.02373 0.04037 0.6406 0.2745 0.05193 0.2917 0.5954 0.3068 0.5386 0.3353 0.3273 0.3391 0.2138 0.3381 0.1468 0.3328 0.07478 0.3164 0.974 0.1717 -7.082E-4 0.1099 0.02966 0.1243 0.04855 0.03967 0.1206 0.04622 0.9654 0.1773'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='1.0 0.0 0.0 1.571' scale='0.8311 0.7947 0.8484' translation='133.8 -18.08 71.34'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='1.0' diffuseColor='0.5882 0.5882 0.5882' shininess='0.145'/>
|
||||||
|
<ImageTexture url='"textures/ChevyTahoeTexture.jpg" "https://savage.nps.edu/Savage/GroundVehicles/Chevy/textures/ChevyTahoeTexture.jpg"'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='0 2 98 -1 98 1 0 -1 1 99 4 -1 4 0 1 -1 2 7 100 -1 100 98 2 -1 101 100 7 -1 7 9 59 -1 101 7 59 -1 102 101 59 -1 59 58 65 -1 102 59 65 -1 66 64 125 -1 125 120 66 -1 120 102 65 -1 65 66 120 -1 64 63 104 -1 104 12 64 -1 63 62 105 -1 105 104 63 -1 62 61 107 -1 107 105 62 -1 60 21 20 -1 61 60 20 -1 61 20 106 -1 61 106 107 -1 53 52 96 -1 96 60 53 -1 22 21 60 -1 60 96 22 -1 23 94 95 -1 95 52 23 -1 52 95 93 -1 52 93 92 -1 92 22 96 -1 52 92 96 -1 26 20 21 -1 21 77 78 -1 26 21 78 -1 76 28 27 -1 27 75 76 -1 77 76 75 -1 22 76 77 -1 22 77 21 -1 91 90 28 -1 91 28 76 -1 91 76 22 -1 91 22 92 -1 74 73 79 -1 79 78 74 -1 73 72 80 -1 80 79 73 -1 81 80 72 -1 72 71 81 -1 89 85 122 -1 122 109 81 -1 89 122 81 -1 37 124 123 -1 123 87 37 -1 20 41 112 -1 112 106 20 -1 26 42 41 -1 41 20 26 -1 30 43 42 -1 42 26 30 -1 32 44 43 -1 43 30 32 -1 34 45 44 -1 44 32 34 -1 41 47 114 -1 114 112 41 -1 42 48 47 -1 47 41 42 -1 43 49 48 -1 48 42 43 -1 44 50 49 -1 49 43 44 -1 45 51 50 -1 50 44 45 -1 19 23 52 -1 52 53 19 -1 61 54 53 -1 53 60 61 -1 19 53 54 -1 17 19 54 -1 54 55 17 -1 15 17 55 -1 55 56 15 -1 13 15 56 -1 56 57 13 -1 11 13 57 -1 57 58 11 -1 9 11 58 -1 58 59 9 -1 55 54 61 -1 61 62 55 -1 56 55 62 -1 62 63 56 -1 57 56 63 -1 63 64 57 -1 66 65 58 -1 64 66 58 -1 64 58 57 -1 69 37 87 -1 70 69 87 -1 70 87 86 -1 84 69 70 -1 70 83 84 -1 83 71 33 -1 33 84 83 -1 33 71 72 -1 31 33 72 -1 72 73 31 -1 27 31 73 -1 73 74 27 -1 77 75 74 -1 74 78 77 -1 74 75 27 -1 30 26 78 -1 78 79 30 -1 32 30 79 -1 79 80 32 -1 81 109 34 -1 80 81 34 -1 80 34 32 -1 86 68 122 -1 122 85 86 -1 89 83 70 -1 85 89 70 -1 85 70 86 -1 36 68 86 -1 86 87 36 -1 38 36 87 -1 87 123 38 -1 71 83 89 -1 89 81 71 -1 91 92 24 -1 90 91 24 -1 90 24 29 -1 95 94 25 -1 24 92 93 -1 25 24 93 -1 95 25 93 -1 18 107 106 -1 1 98 3 -1 3 97 1 -1 99 1 97 -1 97 5 99 -1 98 100 6 -1 6 3 98 -1 100 101 8 -1 8 6 100 -1 101 102 10 -1 10 8 101 -1 102 120 67 -1 67 10 102 -1 12 104 14 -1 14 103 12 -1 104 105 16 -1 16 14 104 -1 105 107 18 -1 18 16 105 -1 106 112 40 -1 40 18 106 -1 45 34 108 -1 108 113 45 -1 114 47 115 -1 115 46 114 -1 112 114 46 -1 46 40 112 -1 47 48 116 -1 116 115 47 -1 48 49 117 -1 117 116 48 -1 49 50 118 -1 118 117 49 -1 50 51 119 -1 119 118 50 -1 51 45 113 -1 113 119 51 -1 120 125 67 -1 34 109 35 -1 35 108 34 -1 109 122 82 -1 82 35 109 -1 122 68 121 -1 121 82 122 -1 68 36 110 -1 110 121 68 -1 36 38 111 -1 111 110 36 -1 88 123 124 -1 124 39 88 -1 12 125 64 -1 125 12 103 -1 67 125 103 -1' creaseAngle='3.0' texCoordIndex='0 2 98 -1 98 1 0 -1 1 99 4 -1 4 0 1 -1 2 7 100 -1 100 98 2 -1 101 100 7 -1 7 9 59 -1 101 7 59 -1 102 101 59 -1 59 58 65 -1 102 59 65 -1 66 64 125 -1 125 120 66 -1 120 102 65 -1 65 66 120 -1 64 63 104 -1 104 12 64 -1 63 62 105 -1 105 104 63 -1 62 61 107 -1 107 105 62 -1 60 21 20 -1 61 60 20 -1 61 20 106 -1 61 106 107 -1 53 52 96 -1 96 60 53 -1 22 21 60 -1 60 96 22 -1 23 94 95 -1 95 52 23 -1 52 95 93 -1 52 93 92 -1 92 22 96 -1 52 92 96 -1 26 20 21 -1 21 77 78 -1 26 21 78 -1 76 28 27 -1 27 75 76 -1 77 76 75 -1 22 76 77 -1 22 77 21 -1 91 90 28 -1 91 28 76 -1 91 76 22 -1 91 22 92 -1 74 73 79 -1 79 78 74 -1 73 72 80 -1 80 79 73 -1 81 80 72 -1 72 71 81 -1 89 85 122 -1 122 109 81 -1 89 122 81 -1 37 124 123 -1 123 87 37 -1 20 41 112 -1 112 106 20 -1 26 42 41 -1 41 20 26 -1 30 43 42 -1 42 26 30 -1 32 44 43 -1 43 30 32 -1 34 45 44 -1 44 32 34 -1 41 47 114 -1 114 112 41 -1 42 48 47 -1 47 41 42 -1 43 49 48 -1 48 42 43 -1 44 50 49 -1 49 43 44 -1 45 51 50 -1 50 44 45 -1 19 23 52 -1 52 53 19 -1 61 54 53 -1 53 60 61 -1 19 53 54 -1 17 19 54 -1 54 55 17 -1 15 17 55 -1 55 56 15 -1 13 15 56 -1 56 57 13 -1 11 13 57 -1 57 58 11 -1 9 11 58 -1 58 59 9 -1 55 54 61 -1 61 62 55 -1 56 55 62 -1 62 63 56 -1 57 56 63 -1 63 64 57 -1 66 65 58 -1 64 66 58 -1 64 58 57 -1 69 37 87 -1 70 69 87 -1 70 87 86 -1 84 69 70 -1 70 83 84 -1 83 71 33 -1 33 84 83 -1 33 71 72 -1 31 33 72 -1 72 73 31 -1 27 31 73 -1 73 74 27 -1 77 75 74 -1 74 78 77 -1 74 75 27 -1 30 26 78 -1 78 79 30 -1 32 30 79 -1 79 80 32 -1 81 109 34 -1 80 81 34 -1 80 34 32 -1 86 68 122 -1 122 85 86 -1 89 83 70 -1 85 89 70 -1 85 70 86 -1 36 68 86 -1 86 87 36 -1 38 36 87 -1 87 123 38 -1 71 83 89 -1 89 81 71 -1 91 92 24 -1 90 91 24 -1 90 24 29 -1 95 94 25 -1 24 92 93 -1 25 24 93 -1 95 25 93 -1 18 107 106 -1 1 98 3 -1 3 97 1 -1 99 1 97 -1 97 5 99 -1 98 100 6 -1 6 3 98 -1 100 101 8 -1 8 6 100 -1 101 102 10 -1 10 8 101 -1 102 120 67 -1 67 10 102 -1 12 104 14 -1 14 103 12 -1 104 105 16 -1 16 14 104 -1 105 107 18 -1 18 16 105 -1 106 112 40 -1 40 18 106 -1 45 34 108 -1 108 113 45 -1 114 47 115 -1 115 46 114 -1 112 114 46 -1 46 40 112 -1 47 48 116 -1 116 115 47 -1 48 49 117 -1 117 116 48 -1 49 50 118 -1 118 117 49 -1 50 51 119 -1 119 118 50 -1 51 45 113 -1 113 119 51 -1 120 125 67 -1 34 109 35 -1 35 108 34 -1 109 122 82 -1 82 35 109 -1 122 68 121 -1 121 82 122 -1 68 36 110 -1 110 121 68 -1 36 38 111 -1 111 110 36 -1 88 123 124 -1 124 39 88 -1 12 125 64 -1 125 12 103 -1 67 125 103 -1'>
|
||||||
|
<Coordinate point='0.0 -163.7 27.17 12.52 -163.7 26.53 0.1354 -168.6 7.924 24.12 -159.5 17.52 0.0 -163.7 32.4 17.39 -159.5 33.04 29.73 -159.5 4.018 -1.786 -169.9 -2.792 28.6 -159.5 -5.862 -5.594 -171.8 -8.566 25.16 -159.5 -9.376 -7.769 -171.8 -12.3 9.587 -164.6 -35.37 -16.6 -171.8 -18.45 -12.36 -159.5 -44.84 -31.96 -171.8 -20.92 -43.16 -159.5 -46.3 -54.64 -171.8 -20.52 -79.01 -159.5 -48.32 -65.89 -171.8 -18.12 -162.1 -169.5 -44.58 -160.4 -174.7 -21.41 -160.4 -173.9 -2.695 -72.91 -171.8 -6.737 -162.6 -159.1 29.85 -77.87 -159.1 29.94 -234.4 -169.5 -44.58 -251.4 -174.7 -15.63 -243.0 -173.2 -2.695 -236.6 -159.1 29.85 -274.3 -165.1 -48.24 -275.5 -174.7 -19.7 -299.5 -165.1 -48.63 -298.9 -173.1 -17.4 -347.3 -163.8 -48.63 -354.0 -159.5 -27.32 -353.6 -164.7 7.809 -311.0 -169.5 8.593 -345.2 -166.9 18.44 -311.7 -162.0 24.97 -103.2 -155.7 -68.61 -152.6 -162.6 -79.37 -233.1 -160.7 -78.39 -275.0 -160.0 -77.93 -302.9 -160.5 -76.83 -334.3 -159.8 -74.1 -125.3 -151.4 -83.92 -150.7 -157.6 -86.34 -230.8 -158.4 -87.42 -275.3 -158.2 -87.0 -301.8 -156.6 -85.09 -327.0 -156.4 -79.29 -83.08 -168.1 -4.352 -76.3 -171.8 -17.43 -65.4 -171.8 -23.33 -52.19 -171.8 -26.07 -27.66 -171.8 -25.78 -7.89 -171.8 -21.67 -0.2513 -171.8 -12.06 1.617 -168.1 -8.199 -82.7 -168.1 -18.18 -71.5 -168.1 -33.74 -48.19 -168.1 -35.14 -20.36 -168.1 -34.02 3.75 -168.1 -32.0 9.323 -169.4 -10.92 6.74 -169.7 -19.43 22.88 -159.6 -31.71 -353.9 -164.8 -6.688 -308.8 -171.0 -4.167 -313.7 -171.0 -6.518 -309.3 -173.1 -18.18 -303.4 -174.7 -25.68 -275.2 -174.7 -28.62 -245.7 -174.7 -24.8 -241.8 -174.7 -17.34 -235.9 -173.2 -2.695 -223.5 -169.1 -18.26 -240.7 -170.2 -33.52 -274.8 -168.1 -37.77 -301.8 -168.1 -35.11 -320.2 -168.1 -25.97 -351.9 -158.0 -12.56 -313.3 -171.9 -11.47 -307.3 -171.9 -11.2 -340.6 -165.7 -11.86 -343.3 -167.6 -5.887 -342.8 -167.0 8.378 -328.7 -165.7 24.39 -320.6 -167.6 -11.22 -239.3 -168.7 17.64 -190.2 -168.7 17.58 -161.8 -169.0 17.55 -132.3 -167.8 17.51 -76.18 -167.8 17.45 -84.92 -167.8 17.46 -88.25 -168.4 -4.241 17.39 -159.5 26.84 19.95 -164.4 15.71 13.02 -163.7 32.46 25.35 -164.4 2.898 23.74 -164.4 -6.436 20.42 -164.6 -9.737 16.1 -159.5 -37.05 -15.13 -165.1 -41.19 -44.98 -165.2 -42.42 -92.58 -164.1 -44.84 -76.96 -164.9 -44.13 -351.9 -159.5 -48.74 -349.6 -164.2 -27.21 -358.7 -159.5 7.922 -349.2 -162.4 18.78 -110.3 -160.9 -67.88 -338.2 -155.5 -73.88 -127.8 -158.2 -79.66 -149.8 -151.9 -89.8 -231.6 -153.2 -91.29 -275.6 -153.3 -90.92 -301.5 -150.7 -88.77 -329.4 -151.2 -82.73 18.84 -165.2 -30.05 -358.6 -159.5 -6.785 -346.9 -163.1 -12.38 -339.6 -166.8 18.75 -311.7 -167.8 16.25 15.54 -165.3 -32.16'/>
|
||||||
|
<TextureCoordinate point='0.9253 0.0175 0.9576 0.01922 0.9257 0.06855 0.9876 0.04426 0.9253 0.00337 0.9702 0.002399 1.002 0.08072 0.9207 0.09724 0.9992 0.1074 0.9109 0.1125 0.9903 0.1169 0.9053 0.1226 0.9501 0.1861 0.8825 0.1392 0.8934 0.2126 0.8428 0.1458 0.8139 0.2166 0.7842 0.1448 0.7213 0.222 0.7552 0.1383 0.5068 0.2101 0.5111 0.1466 0.5111 0.09626 0.737 0.1076 0.5056 0.01107 0.7242 0.01083 0.32 0.2101 0.2761 0.1311 0.2978 0.09639 0.3143 0.01107 0.2171 0.2208 0.214 0.142 0.152 0.2218 0.1537 0.1361 0.02865 0.2221 0.01137 0.1653 0.01241 0.06956 0.1222 0.06658 0.03386 0.04047 0.1206 0.02372 0.6588 0.2774 0.5312 0.3053 0.3235 0.303 0.2153 0.3018 0.1431 0.2988 0.06216 0.2915 0.6018 0.3195 0.5361 0.325 0.3292 0.3277 0.2145 0.3266 0.146 0.3218 0.081 0.3061 0.7108 0.1018 0.7283 0.1364 0.7564 0.1523 0.7906 0.1598 0.8539 0.159 0.9049 0.1479 0.9247 0.1219 0.9295 0.1122 0.7118 0.1391 0.7407 0.1811 0.8009 0.1849 0.8727 0.1819 0.935 0.1764 0.9494 0.1193 0.9427 0.1422 0.9844 0.1771 0.01162 0.1087 0.1281 0.1008 0.1154 0.1071 0.1267 0.1382 0.1418 0.1582 0.2147 0.1661 0.291 0.1558 0.301 0.1357 0.3162 0.09639 0.3483 0.1391 0.3038 0.1801 0.2158 0.192 0.146 0.1848 0.09846 0.1601 0.01658 0.1257 0.1164 0.1203 0.1318 0.1196 0.04584 0.1225 0.03881 0.106 0.04007 0.0676 0.07663 0.02462 0.09757 0.1204 0.3074 0.04232 0.4342 0.04247 0.5077 0.04251 0.5836 0.04281 0.7286 0.04299 0.706 0.04296 0.6974 0.1014 0.9702 0.01912 0.9768 0.04827 0.9589 0.003221 0.9908 0.08286 0.9866 0.1081 0.978 0.1169 0.9669 0.1916 0.8862 0.2018 0.8092 0.2051 0.6863 0.2118 0.7266 0.2097 0.0167 0.2231 0.02271 0.1642 -9.659E-4 0.07019 0.02373 0.04037 0.6406 0.2745 0.05193 0.2917 0.5954 0.3068 0.5386 0.3353 0.3273 0.3391 0.2138 0.3381 0.1468 0.3328 0.07478 0.3164 0.974 0.1717 -7.082E-4 0.1099 0.02966 0.1243 0.04855 0.03967 0.1206 0.04622 0.9654 0.1773'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='0.549489 0.590788 -0.590788 2.137' scale='0.7947 0.8311 0.8484' scaleOrientation='5.852E-5 0.0 1.0 0.0722696' translation='38.31 25.25 64.47'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='1.0' diffuseColor='0.5882 0.5882 0.5882' shininess='0.145'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='0 2 3 -1 0 3 1 -1 0 4 5 -1 0 5 6 -1 0 6 7 -1 0 7 2 -1 2 7 8 -1 2 8 9 -1 2 9 3 -1 3 9 10 -1 3 10 1 -1 1 4 0 -1 4 11 12 -1 4 12 5 -1 5 12 13 -1 5 13 6 -1 6 13 14 -1 6 14 7 -1 7 14 15 -1 7 15 8 -1 8 15 16 -1 8 16 9 -1 10 17 18 -1 10 18 1 -1 1 18 19 -1 1 19 11 -1 1 11 4 -1 13 20 14 -1 14 20 15 -1' creaseAngle='2.0' solid='false'>
|
||||||
|
<Coordinate point='-5.819 8.879 -7.786 1.262 12.53 -11.05 -8.114 9.076 -1.355 1.022 14.67 -0.9557 -4.43 8.357 -10.65 -6.934 6.375 -8.467 -8.242 6.0 -5.673 -9.356 5.915 -1.611 -8.47 5.914 0.6059 3.349 12.46 1.298 4.536 13.34 -0.6932 -4.691 4.076 -11.17 -7.786 2.141 -8.832 -9.067 1.267 -5.673 -10.43 0.421 -1.611 -8.515 0.2266 1.713 6.767 8.148 1.739 8.222 9.224 -0.6932 7.483 9.836 -10.84 4.182 8.951 -12.28 -10.43 0.411 -1.611'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform rotation='0.579415 0.576315 -0.576315 2.091' scale='0.7947 0.8311 0.8484' scaleOrientation='0.0 0.0 -1.0 0.00521342' translation='37.23 25.25 63.71'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material ambientIntensity='0.0' diffuseColor='0.01961 0.01961 0.01961' shininess='0.145'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='4 6 7 -1 4 7 5 -1 1 0 4 -1 4 5 1 -1 0 2 6 -1 6 4 0 -1 2 3 7 -1 7 6 2 -1 3 1 5 -1 5 7 3 -1' solid='false'>
|
||||||
|
<Coordinate point='3.71 13.89 1.372 4.542 14.5 -1.889 7.272 9.686 1.737 8.225 10.39 -0.6932 8.82 17.06 6.148 9.652 17.68 -2.293 12.37 10.95 6.513 13.34 13.57 -2.293'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
</Transform>
|
||||||
|
<Transform DEF='WheelLeftFront' translation='-1.57 0.550854 0.801999'>
|
||||||
|
<Transform DEF='Wheel' rotation='1.0 0.0 0.0 1.57079' scale='1.2 1.2 1.2'>
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<Material diffuseColor='0.0 0.0 0.0' specularColor='0.29 0.3 0.29'/>
|
||||||
|
<ImageTexture url='"textures/ChevyTahoeTires.jpg" "https://savage.nps.edu/Savage/GroundVehicles/Chevy/textures/ChevyTahoeTires.jpg"'/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet coordIndex='0 1 3 2 -1 2 3 5 4 -1 4 5 7 6 -1 6 7 9 8 -1 8 9 11 10 -1 10 11 13 12 -1 12 13 15 14 -1 14 15 17 16 -1 16 17 19 18 -1 18 19 21 20 -1 20 21 23 22 -1 22 23 25 24 -1 24 25 27 26 -1 26 27 29 28 -1 28 29 31 30 -1 30 31 1 0 -1 32 31 29 -1 32 29 27 -1 32 27 25 -1 32 25 23 -1 32 23 21 -1 32 21 19 -1 32 19 17 -1 32 17 15 -1 32 15 13 -1 32 13 11 -1 32 11 9 -1 32 9 7 -1 32 7 5 -1 32 5 3 -1 32 3 1 -1 32 1 31 -1 33 0 2 -1 33 2 4 -1 33 4 6 -1 33 6 8 -1 33 8 10 -1 33 10 12 -1 33 12 14 -1 33 14 16 -1 33 16 18 -1 33 18 20 -1 33 20 22 -1 33 22 24 -1 33 24 26 -1 33 26 28 -1 33 28 30 -1 33 30 0 -1' creaseAngle='3.0' texCoordIndex='0 1 3 2 -1 2 3 5 4 -1 4 5 7 6 -1 6 7 9 8 -1 8 9 11 10 -1 10 11 13 12 -1 12 13 15 14 -1 14 15 17 16 -1 16 17 19 18 -1 18 19 21 20 -1 20 21 23 22 -1 22 23 25 24 -1 24 25 27 26 -1 26 27 29 28 -1 28 29 31 30 -1 30 31 33 32 -1 65 35 36 -1 65 36 37 -1 65 37 63 -1 65 63 39 -1 65 39 40 -1 65 40 41 -1 65 41 42 -1 65 42 64 -1 65 64 66 -1 65 66 45 -1 65 45 46 -1 65 46 47 -1 65 47 60 -1 65 60 61 -1 65 61 62 -1 65 62 35 -1 34 16 43 -1 34 43 44 -1 34 44 50 -1 34 50 51 -1 34 51 52 -1 34 52 48 -1 34 48 49 -1 34 49 53 -1 34 53 54 -1 34 54 55 -1 34 55 56 -1 34 56 38 -1 34 38 57 -1 34 57 58 -1 34 58 59 -1 34 59 16 -1'>
|
||||||
|
<Coordinate point='0.0 -0.165 -0.42 0.0 0.165 -0.42 0.160727 -0.165 -0.38803 0.160727 0.165 -0.38803 0.296985 -0.165 -0.296985 0.296985 0.165 -0.296985 0.38803 -0.165 -0.160727 0.38803 0.165 -0.160727 0.42 -0.165 1.83588E-8 0.42 0.165 1.83588E-8 0.38803 -0.165 0.160727 0.38803 0.165 0.160727 0.296985 -0.165 0.296985 0.296985 0.165 0.296985 0.160727 -0.165 0.38803 0.160727 0.165 0.38803 6.34183E-8 -0.165 0.42 6.34183E-8 0.165 0.42 -0.160727 -0.165 0.38803 -0.160727 0.165 0.38803 -0.296985 -0.165 0.296985 -0.296985 0.165 0.296985 -0.38803 -0.165 0.160727 -0.38803 0.165 0.160727 -0.42 -0.165 -5.00846E-9 -0.42 0.165 -5.00846E-9 -0.388029 -0.165 -0.160727 -0.388029 0.165 -0.160727 -0.296985 -0.165 -0.296985 -0.296985 0.165 -0.296985 -0.160727 -0.165 -0.38803 -0.160727 0.165 -0.38803 0.0 0.165 0.0 0.0 -0.165 0.0'/>
|
||||||
|
<TextureCoordinate point='0.987903 0.685632 0.984782 0.665157 0.986394 0.625989 0.983273 0.605515 0.984885 0.566346 0.981764 0.545873 0.983376 0.506704 0.980255 0.48623 0.981867 0.447062 0.978746 0.426588 0.980357 0.387419 0.977237 0.366945 0.978848 0.327777 0.975727 0.307303 0.977339 0.268135 0.974218 0.247661 1.47025 0.0255656 0.972709 0.188018 0.974321 0.14885 0.9712 0.128376 0.972812 0.0892073 0.969691 0.0687333 0.971303 0.0295649 0.968182 0.00909095 0.969793 -0.0300775 0.966673 -0.0505514 0.968284 -0.08972 0.965164 -0.110194 0.966775 -0.149362 0.963654 -0.169836 0.965266 -0.209005 0.962145 -0.229479 0.963757 -0.268647 0.976062 -0.262564 1.4974 0.496154 0.324123 0.926009 0.175429 0.826655 0.0760747 0.677961 1.02681 0.496154 0.0760743 0.327167 0.175429 0.178473 0.324123 0.0791192 0.499519 0.0442308 1.67748 0.0613869 1.83015 0.163398 0.922964 0.327167 0.957852 0.502564 0.922964 0.67796 1.83015 0.82891 1.67748 0.930921 1.93217 0.316067 1.96799 0.496154 1.93217 0.67624 1.4974 0.966742 1.31731 0.930921 1.16464 0.828911 1.06263 0.67624 1.06263 0.316067 1.16464 0.163397 1.31731 0.0613869 0.82361 0.826655 0.674916 0.926009 0.499519 0.960897 0.041186 0.502564 0.674916 0.0791192 0.499519 0.502564 0.82361 0.178473'/>
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
</Transform>
|
||||||
|
<Transform DEF='WheelLeftRear' translation='1.65 0.55 0.801999'>
|
||||||
|
<Transform USE='Wheel'/>
|
||||||
|
</Transform>
|
||||||
|
<Transform DEF='WheelRightFront' translation='-1.57 0.550854 -0.801999'>
|
||||||
|
<Transform USE='Wheel'/>
|
||||||
|
</Transform>
|
||||||
|
<Transform DEF='WheelRightRear' translation='1.65 0.55 -0.801999'>
|
||||||
|
<Transform USE='Wheel'/>
|
||||||
|
</Transform>
|
||||||
|
</Transform>
|
||||||
|
</Scene>
|
||||||
|
</X3D>
|
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
Binary file not shown.
After Width: | Height: | Size: 69 KiB |
|
@ -0,0 +1 @@
|
||||||
|
Simple models for testing importer. No desription because models are simple and created by hands.
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<amf>
|
||||||
|
<object id="1">
|
||||||
|
<mesh>
|
||||||
|
<vertices>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>-0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>1</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
</vertices>
|
||||||
|
<volume>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>3</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
</mesh>
|
||||||
|
</object>
|
||||||
|
</amf>
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<amf>
|
||||||
|
<object id="1">
|
||||||
|
<color>
|
||||||
|
<r>0.1</r>
|
||||||
|
<g>0.6</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<mesh>
|
||||||
|
<vertices>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>-0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>1</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
</vertices>
|
||||||
|
<volume>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>3</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
</mesh>
|
||||||
|
</object>
|
||||||
|
</amf>
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<amf>
|
||||||
|
<object id="1">
|
||||||
|
<color>
|
||||||
|
<r>0.1</r>
|
||||||
|
<g>0.6</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<mesh>
|
||||||
|
<vertices>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>-0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>1</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
</vertices>
|
||||||
|
<volume>
|
||||||
|
<color>
|
||||||
|
<r>0.6</r>
|
||||||
|
<g>0.1</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>3</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
</mesh>
|
||||||
|
</object>
|
||||||
|
</amf>
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<amf>
|
||||||
|
<object id="1">
|
||||||
|
<color>
|
||||||
|
<r>0.1</r>
|
||||||
|
<g>0.6</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<mesh>
|
||||||
|
<vertices>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>-0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>1</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
</vertices>
|
||||||
|
<volume>
|
||||||
|
<color>
|
||||||
|
<r>0.6</r>
|
||||||
|
<g>0.1</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<triangle>
|
||||||
|
<color>
|
||||||
|
<r>0.0</r>
|
||||||
|
<g>0.0</g>
|
||||||
|
<b>1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>3</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
</mesh>
|
||||||
|
</object>
|
||||||
|
</amf>
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<amf>
|
||||||
|
<object id="1">
|
||||||
|
<color>
|
||||||
|
<r>0.1</r>
|
||||||
|
<g>0.6</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<mesh>
|
||||||
|
<vertices>
|
||||||
|
<vertex>
|
||||||
|
<color>
|
||||||
|
<r>0.5</r>
|
||||||
|
<g>0.5</g>
|
||||||
|
<b>0</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>-0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<color>
|
||||||
|
<r>0.5</r>
|
||||||
|
<g>0.5</g>
|
||||||
|
<b>0.2</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<color>
|
||||||
|
<r>0.5</r>
|
||||||
|
<g>0.5</g>
|
||||||
|
<b>0.4</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<coordinates>
|
||||||
|
<x>1</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<color>
|
||||||
|
<r>0.5</r>
|
||||||
|
<g>0.5</g>
|
||||||
|
<b>0.8</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
</vertices>
|
||||||
|
<volume>
|
||||||
|
<color>
|
||||||
|
<r>0.6</r>
|
||||||
|
<g>0.1</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>3</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
</mesh>
|
||||||
|
</object>
|
||||||
|
</amf>
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<amf>
|
||||||
|
<object id="1">
|
||||||
|
<color>
|
||||||
|
<r>0.1</r>
|
||||||
|
<g>0.6</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<mesh>
|
||||||
|
<vertices>
|
||||||
|
<vertex>
|
||||||
|
<color>
|
||||||
|
<r>0.5</r>
|
||||||
|
<g>0.5</g>
|
||||||
|
<b>0</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>-0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>1</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
</vertices>
|
||||||
|
<volume>
|
||||||
|
<color>
|
||||||
|
<r>0.6</r>
|
||||||
|
<g>0.1</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>3</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
</mesh>
|
||||||
|
</object>
|
||||||
|
</amf>
|
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<amf>
|
||||||
|
<object id="1">
|
||||||
|
<color>
|
||||||
|
<r>0.1</r>
|
||||||
|
<g>0.6</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<mesh>
|
||||||
|
<vertices>
|
||||||
|
<vertex>
|
||||||
|
<color>
|
||||||
|
<r>0.5</r>
|
||||||
|
<g>0.5</g>
|
||||||
|
<b>0</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>-0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>1</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
</vertices>
|
||||||
|
<volume>
|
||||||
|
<color>
|
||||||
|
<r>0.6</r>
|
||||||
|
<g>0.1</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<triangle>
|
||||||
|
<color>
|
||||||
|
<r>0.0</r>
|
||||||
|
<g>0.0</g>
|
||||||
|
<b>1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>3</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
</mesh>
|
||||||
|
</object>
|
||||||
|
</amf>
|
|
@ -0,0 +1,112 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<amf>
|
||||||
|
<object id="1">
|
||||||
|
<color>
|
||||||
|
<r>0.1</r>
|
||||||
|
<g>0.6</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<mesh>
|
||||||
|
<vertices>
|
||||||
|
<vertex>
|
||||||
|
<color>
|
||||||
|
<r>0.5</r>
|
||||||
|
<g>0.5</g>
|
||||||
|
<b>0</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>-0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>1</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>-4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
</vertices>
|
||||||
|
<volume>
|
||||||
|
<color>
|
||||||
|
<r>0.6</r>
|
||||||
|
<g>0.1</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<triangle>
|
||||||
|
<color>
|
||||||
|
<r>0.0</r>
|
||||||
|
<g>0.0</g>
|
||||||
|
<b>1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>3</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
<volume>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>4</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>4</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>4</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
</mesh>
|
||||||
|
</object>
|
||||||
|
</amf>
|
|
@ -0,0 +1,130 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<amf>
|
||||||
|
<object id="1">
|
||||||
|
<color>
|
||||||
|
<r>0.1</r>
|
||||||
|
<g>0.6</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<mesh>
|
||||||
|
<vertices>
|
||||||
|
<vertex>
|
||||||
|
<color>
|
||||||
|
<r>0.5</r>
|
||||||
|
<g>0.5</g>
|
||||||
|
<b>0</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>-0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>1</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>-4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
</vertices>
|
||||||
|
<volume>
|
||||||
|
<color>
|
||||||
|
<r>0.6</r>
|
||||||
|
<g>0.1</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<triangle>
|
||||||
|
<color>
|
||||||
|
<r>0.0</r>
|
||||||
|
<g>0.0</g>
|
||||||
|
<b>1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>3</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
<volume>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>4</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>4</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>4</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
</mesh>
|
||||||
|
</object>
|
||||||
|
<constellation id="2">
|
||||||
|
<instance objectid="1">
|
||||||
|
<deltax>-5</deltax>
|
||||||
|
<deltay>0</deltay>
|
||||||
|
<deltaz>0</deltaz>
|
||||||
|
<rx>-45</rx>
|
||||||
|
<ry>0</ry>
|
||||||
|
<rz>0</rz>
|
||||||
|
</instance>
|
||||||
|
<instance objectid="1">
|
||||||
|
<deltax>5</deltax>
|
||||||
|
<deltay>0</deltay>
|
||||||
|
<deltaz>0</deltaz>
|
||||||
|
<rx>45</rx>
|
||||||
|
<ry>0</ry>
|
||||||
|
<rz>0</rz>
|
||||||
|
</instance>
|
||||||
|
</constellation>
|
||||||
|
</amf>
|
|
@ -0,0 +1,180 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<amf>
|
||||||
|
<object id="1">
|
||||||
|
<color>
|
||||||
|
<r>0.1</r>
|
||||||
|
<g>0.6</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<mesh>
|
||||||
|
<vertices>
|
||||||
|
<vertex>
|
||||||
|
<color>
|
||||||
|
<r>0.5</r>
|
||||||
|
<g>0.5</g>
|
||||||
|
<b>0</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>-0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>-0.5</x>
|
||||||
|
<y>0.5</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>1</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>0</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
<vertex>
|
||||||
|
<coordinates>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<z>-4</z>
|
||||||
|
</coordinates>
|
||||||
|
</vertex>
|
||||||
|
</vertices>
|
||||||
|
<volume>
|
||||||
|
<color>
|
||||||
|
<r>0.6</r>
|
||||||
|
<g>0.1</g>
|
||||||
|
<b>0.1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<triangle>
|
||||||
|
<color>
|
||||||
|
<r>0.0</r>
|
||||||
|
<g>0.0</g>
|
||||||
|
<b>1</b>
|
||||||
|
<a>1</a>
|
||||||
|
</color>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>3</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>3</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
<volume>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>1</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>4</v2>
|
||||||
|
<v3>2</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>1</v1>
|
||||||
|
<v2>2</v2>
|
||||||
|
<v3>4</v3>
|
||||||
|
</triangle>
|
||||||
|
<triangle>
|
||||||
|
<v1>0</v1>
|
||||||
|
<v2>1</v2>
|
||||||
|
<v3>4</v3>
|
||||||
|
</triangle>
|
||||||
|
</volume>
|
||||||
|
</mesh>
|
||||||
|
</object>
|
||||||
|
<constellation id="2">
|
||||||
|
<instance objectid="1">
|
||||||
|
<deltax>-5</deltax>
|
||||||
|
<deltay>0</deltay>
|
||||||
|
<deltaz>0</deltaz>
|
||||||
|
<rx>-45</rx>
|
||||||
|
<ry>0</ry>
|
||||||
|
<rz>0</rz>
|
||||||
|
</instance>
|
||||||
|
<instance objectid="1">
|
||||||
|
<deltax>5</deltax>
|
||||||
|
<deltay>0</deltay>
|
||||||
|
<deltaz>0</deltaz>
|
||||||
|
<rx>45</rx>
|
||||||
|
<ry>0</ry>
|
||||||
|
<rz>0</rz>
|
||||||
|
</instance>
|
||||||
|
<instance objectid="1">
|
||||||
|
<deltax>0</deltax>
|
||||||
|
<deltay>-5</deltay>
|
||||||
|
<deltaz>0</deltaz>
|
||||||
|
<rx>0</rx>
|
||||||
|
<ry>-45</ry>
|
||||||
|
<rz>0</rz>
|
||||||
|
</instance>
|
||||||
|
<instance objectid="1">
|
||||||
|
<deltax>0</deltax>
|
||||||
|
<deltay>5</deltay>
|
||||||
|
<deltaz>0</deltaz>
|
||||||
|
<rx>0</rx>
|
||||||
|
<ry>45</ry>
|
||||||
|
<rz>0</rz>
|
||||||
|
</instance>
|
||||||
|
<instance objectid="1">
|
||||||
|
<deltax>0</deltax>
|
||||||
|
<deltay>0</deltay>
|
||||||
|
<deltaz>-5</deltaz>
|
||||||
|
<rx>0</rx>
|
||||||
|
<ry>0</ry>
|
||||||
|
<rz>-45</rz>
|
||||||
|
</instance>
|
||||||
|
<instance objectid="1">
|
||||||
|
<deltax>0</deltax>
|
||||||
|
<deltay>0</deltay>
|
||||||
|
<deltaz>5</deltaz>
|
||||||
|
<rx>0</rx>
|
||||||
|
<ry>0</ry>
|
||||||
|
<rz>45</rz>
|
||||||
|
</instance>
|
||||||
|
</constellation>
|
||||||
|
<constellation id="3">
|
||||||
|
<instance objectid="2">
|
||||||
|
<deltax>-20</deltax>
|
||||||
|
<deltay>0</deltay>
|
||||||
|
<deltaz>0</deltaz>
|
||||||
|
<rx>-20</rx>
|
||||||
|
<ry>0</ry>
|
||||||
|
<rz>0</rz>
|
||||||
|
</instance>
|
||||||
|
<instance objectid="2">
|
||||||
|
<deltax>20</deltax>
|
||||||
|
<deltay>0</deltay>
|
||||||
|
<deltaz>0</deltaz>
|
||||||
|
<rx>20</rx>
|
||||||
|
<ry>0</ry>
|
||||||
|
<rz>0</rz>
|
||||||
|
</instance>
|
||||||
|
</constellation>
|
||||||
|
</amf>
|
Loading…
Reference in New Issue