Merge branch 'master' into patch-8
|
@ -16,7 +16,7 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, ubuntu-latest-clang++, ubuntu-gcc-hunter, macos-clang-hunter, windows-msvc-hunter]
|
||||
name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, ubuntu-latest-clang++]
|
||||
# For Windows msvc, for Linux and macOS let's use the clang compiler, use gcc for Linux.
|
||||
include:
|
||||
- name: windows-latest-cl.exe
|
||||
|
@ -35,15 +35,6 @@ jobs:
|
|||
os: ubuntu-latest
|
||||
cxx: g++
|
||||
cc: gcc
|
||||
- name: ubuntu-gcc-hunter
|
||||
os: ubuntu-latest
|
||||
toolchain: ninja-gcc-cxx17-fpic
|
||||
- name: macos-clang-hunter
|
||||
os: macos-latest
|
||||
toolchain: ninja-clang-cxx17-fpic
|
||||
- name: windows-msvc-hunter
|
||||
os: windows-latest
|
||||
toolchain: ninja-vs-win64-cxx17
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
@ -55,29 +46,15 @@ jobs:
|
|||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
|
||||
- name: Set Compiler Environment
|
||||
if: "!endsWith(matrix.name, 'hunter')"
|
||||
uses: lukka/set-shell-env@v1
|
||||
with:
|
||||
CXX: ${{ matrix.cxx }}
|
||||
CC: ${{ matrix.cc }}
|
||||
|
||||
- name: Set Compiler Environment for Hunter on Windows
|
||||
if: startsWith(matrix.name, 'windows') && endsWith(matrix.name, 'hunter')
|
||||
uses: lukka/set-shell-env@v1
|
||||
with:
|
||||
VS160COMNTOOLS: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools
|
||||
|
||||
- name: Checkout Hunter toolchains
|
||||
if: endsWith(matrix.name, 'hunter')
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: cpp-pm/polly
|
||||
path: cmake/polly
|
||||
|
||||
- name: Cache DX SDK
|
||||
id: dxcache
|
||||
if: contains(matrix.name, 'windows')
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: '${{ github.workspace }}/DX_SDK'
|
||||
key: ${{ runner.os }}-DX_SDK
|
||||
|
@ -121,7 +98,7 @@ jobs:
|
|||
run: cd build/bin && ./unit ${{ steps.hunter_extra_test_args.outputs.args }}
|
||||
shell: bash
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: matrix.name == 'windows-msvc'
|
||||
with:
|
||||
name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'
|
||||
|
|
|
@ -19,7 +19,7 @@ jobs:
|
|||
dry-run: false
|
||||
language: c++
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
if: failure() && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: artifacts
|
||||
|
|
|
@ -137,7 +137,7 @@ IF (WIN32)
|
|||
ELSE()
|
||||
OPTION( ASSIMP_BUILD_ZLIB
|
||||
"Build your own zlib"
|
||||
ON
|
||||
OFF
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
|
@ -311,9 +311,9 @@ ELSEIF( MINGW )
|
|||
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
|
||||
ENDIF()
|
||||
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -g ${CMAKE_CXX_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wno-dangling-reference -Wall -Wno-long-long -Wa,-mbig-obj -g ${CMAKE_CXX_FLAGS}")
|
||||
ELSE()
|
||||
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wno-dangling-reference -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
|
||||
ENDIF()
|
||||
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
||||
ENDIF()
|
||||
|
|
|
@ -6,6 +6,7 @@ RUN apt-get update && apt-get install -y ninja-build \
|
|||
RUN add-apt-repository ppa:ubuntu-toolchain-r/test && apt-get update
|
||||
|
||||
WORKDIR /opt
|
||||
RUN apt install zlib1g-dev
|
||||
|
||||
# Build Assimp
|
||||
RUN git clone https://github.com/assimp/assimp.git /opt/assimp
|
||||
|
|
15
Readme.md
|
@ -16,26 +16,27 @@ APIs are provided for C and C++. There are various bindings to other languages (
|
|||
Additionally, assimp features various __mesh post-processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
|
||||
|
||||
### Documentation ###
|
||||
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
|
||||
Read [our latest documentation](https://assimp-docs.readthedocs.io/en/latest/).
|
||||
|
||||
### Pre-built binaries ###
|
||||
Please check our [Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib)
|
||||
Download binaries from [our Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib).
|
||||
|
||||
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
|
||||
### Test data ###
|
||||
Clone [our model database](https://github.com/assimp/assimp-mdb).
|
||||
|
||||
### Communities ###
|
||||
- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
|
||||
- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/)
|
||||
- Ask questions at [the Assimp Discussion Board](https://github.com/assimp/assimp/discussions).
|
||||
- Ask [the Assimp community on Reddit](https://www.reddit.com/r/Assimp/).
|
||||
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
|
||||
- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
|
||||
|
||||
And we also have a Gitter-channel:Gitter [](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
|
||||
|
||||
#### Supported file formats ####
|
||||
You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
|
||||
See [the complete list of supported formats](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md).
|
||||
|
||||
### Building ###
|
||||
Take a look [here](https://github.com/assimp/assimp/blob/master/Build.md) to get started. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
|
||||
Start by reading [our build instructions](https://github.com/assimp/assimp/blob/master/Build.md). We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
|
||||
|
||||
### Ports ###
|
||||
* [Android](port/AndroidJNI/README.md)
|
||||
|
|
|
@ -57,6 +57,7 @@ enum class ResourceType {
|
|||
RT_BaseMaterials,
|
||||
RT_EmbeddedTexture2D,
|
||||
RT_Texture2DGroup,
|
||||
RT_ColorGroup,
|
||||
RT_Unknown
|
||||
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
|
||||
|
||||
|
@ -117,6 +118,21 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class ColorGroup : public Resource {
|
||||
public:
|
||||
std::vector<aiColor4D> mColors;
|
||||
ColorGroup(int id) :
|
||||
Resource(id){
|
||||
// empty
|
||||
}
|
||||
|
||||
~ColorGroup() override = default;
|
||||
|
||||
ResourceType getType() const override {
|
||||
return ResourceType::RT_ColorGroup;
|
||||
}
|
||||
};
|
||||
|
||||
class BaseMaterials : public Resource {
|
||||
public:
|
||||
std::vector<unsigned int> mMaterialIndex;
|
||||
|
|
|
@ -98,6 +98,11 @@ namespace XmlTag {
|
|||
const char *const texture_cuurd_u = "u";
|
||||
const char *const texture_cuurd_v = "v";
|
||||
|
||||
// vertex color definitions
|
||||
const char *const colorgroup = "m:colorgroup";
|
||||
const char *const color_item = "m:color";
|
||||
const char *const color_vaule = "color";
|
||||
|
||||
// Meta info tags
|
||||
const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
|
||||
const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
|
||||
|
|
|
@ -81,12 +81,17 @@ static constexpr aiImporterDesc desc = {
|
|||
"3mf"
|
||||
};
|
||||
|
||||
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool ) const {
|
||||
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
|
||||
return false;
|
||||
}
|
||||
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
|
||||
return opcPackage.validate();
|
||||
static const char *const ModelRef = "3D/3dmodel.model";
|
||||
ZipArchiveIOSystem archive(pIOHandler, filename);
|
||||
if (!archive.Exists(ModelRef)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3MFImporter::SetupProperties(const Importer*) {
|
||||
|
|
|
@ -119,9 +119,9 @@ public:
|
|||
|
||||
static bool IsEmbeddedTexture( const std::string &filename ) {
|
||||
const std::string extension = BaseImporter::GetExtension(filename);
|
||||
if (extension == "jpg" || extension == "png") {
|
||||
if (extension == "jpg" || extension == "png" || extension == "jpeg") {
|
||||
std::string::size_type pos = filename.find("thumbnail");
|
||||
if (pos == std::string::npos) {
|
||||
if (pos != std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -75,7 +75,7 @@ aiFace ReadTriangle(XmlNode &node, int &texId0, int &texId1, int &texId2) {
|
|||
face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string()));
|
||||
face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string()));
|
||||
|
||||
texId0 = texId1 = texId2 = -1;
|
||||
texId0 = texId1 = texId2 = IdNotSet;
|
||||
XmlParser::getIntAttribute(node, XmlTag::p1, texId0);
|
||||
XmlParser::getIntAttribute(node, XmlTag::p2, texId1);
|
||||
XmlParser::getIntAttribute(node, XmlTag::p3, texId2);
|
||||
|
@ -236,6 +236,8 @@ void XmlSerializer::ImportXml(aiScene *scene) {
|
|||
ReadBaseMaterials(currentNode);
|
||||
} else if (currentNodeName == XmlTag::meta) {
|
||||
ReadMetadata(currentNode);
|
||||
} else if (currentNodeName == XmlTag::colorgroup) {
|
||||
ReadColorGroup(currentNode);
|
||||
}
|
||||
}
|
||||
StoreMaterialsInScene(scene);
|
||||
|
@ -331,9 +333,49 @@ void XmlSerializer::ReadObject(XmlNode &node) {
|
|||
|
||||
if (hasPid) {
|
||||
auto it = mResourcesDictionnary.find(pid);
|
||||
if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
|
||||
BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
|
||||
mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
|
||||
if (hasPindex && it != mResourcesDictionnary.end()) {
|
||||
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
|
||||
BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
|
||||
mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
|
||||
} else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
|
||||
Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second);
|
||||
if (mesh->mTextureCoords[0] == nullptr) {
|
||||
mesh->mNumUVComponents[0] = 2;
|
||||
for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||
mesh->mNumUVComponents[i] = 0;
|
||||
}
|
||||
|
||||
const std::string name = ai_to_string(group->mTexId);
|
||||
for (size_t i = 0; i < mMaterials.size(); ++i) {
|
||||
if (name == mMaterials[i]->GetName().C_Str()) {
|
||||
mesh->mMaterialIndex = static_cast<unsigned int>(i);
|
||||
}
|
||||
}
|
||||
|
||||
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
|
||||
for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
|
||||
mesh->mTextureCoords[0][vertex_idx] =
|
||||
aiVector3D(group->mTex2dCoords[pindex].x, group->mTex2dCoords[pindex].y, 0.0f);
|
||||
}
|
||||
} else {
|
||||
for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
|
||||
if (mesh->mTextureCoords[0][vertex_idx].z < 0) {
|
||||
// use default
|
||||
mesh->mTextureCoords[0][vertex_idx] =
|
||||
aiVector3D(group->mTex2dCoords[pindex].x, group->mTex2dCoords[pindex].y, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if (it->second->getType() == ResourceType::RT_ColorGroup) {
|
||||
if (mesh->mColors[0] == nullptr) {
|
||||
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
|
||||
|
||||
ColorGroup *group = static_cast<ColorGroup *>(it->second);
|
||||
for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
|
||||
mesh->mColors[0][vertex_idx] = group->mColors[pindex];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -415,27 +457,36 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
|
|||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string currentName = currentNode.name();
|
||||
if (currentName == XmlTag::triangle) {
|
||||
int pid = IdNotSet, p1 = IdNotSet;
|
||||
int pid = IdNotSet;
|
||||
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
|
||||
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
|
||||
|
||||
int texId[3];
|
||||
Texture2DGroup *group = nullptr;
|
||||
aiFace face = ReadTriangle(currentNode, texId[0], texId[1], texId[2]);
|
||||
if (hasPid && hasP1) {
|
||||
int pindex[3];
|
||||
aiFace face = ReadTriangle(currentNode, pindex[0], pindex[1], pindex[2]);
|
||||
if (hasPid && (pindex[0] != IdNotSet || pindex[1] != IdNotSet || pindex[2] != IdNotSet)) {
|
||||
auto it = mResourcesDictionnary.find(pid);
|
||||
if (it != mResourcesDictionnary.end()) {
|
||||
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
|
||||
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
|
||||
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
|
||||
|
||||
auto update_material = [&](int idx) {
|
||||
if (pindex[idx] != IdNotSet) {
|
||||
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[pindex[idx]];
|
||||
}
|
||||
};
|
||||
|
||||
update_material(0);
|
||||
update_material(1);
|
||||
update_material(2);
|
||||
|
||||
} else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
|
||||
// Load texture coordinates into mesh, when any
|
||||
Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second); // fix bug
|
||||
if (mesh->mTextureCoords[0] == nullptr) {
|
||||
mesh->mNumUVComponents[0] = 2;
|
||||
for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||
mesh->mNumUVComponents[i] = 0;
|
||||
}
|
||||
|
||||
group = static_cast<Texture2DGroup *>(it->second);
|
||||
const std::string name = ai_to_string(group->mTexId);
|
||||
for (size_t i = 0; i < mMaterials.size(); ++i) {
|
||||
if (name == mMaterials[i]->GetName().C_Str()) {
|
||||
|
@ -443,21 +494,44 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
|
|||
}
|
||||
}
|
||||
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
|
||||
for (unsigned int vertex_index = 0; vertex_index < mesh->mNumVertices; vertex_index++) {
|
||||
mesh->mTextureCoords[0][vertex_index].z = IdNotSet;//mark not set
|
||||
}
|
||||
}
|
||||
|
||||
auto update_texture = [&](int idx) {
|
||||
if (pindex[idx] != IdNotSet) {
|
||||
size_t vertex_index = face.mIndices[idx];
|
||||
mesh->mTextureCoords[0][vertex_index] =
|
||||
aiVector3D(group->mTex2dCoords[pindex[idx]].x, group->mTex2dCoords[pindex[idx]].y, 0.0f);
|
||||
}
|
||||
};
|
||||
|
||||
update_texture(0);
|
||||
update_texture(1);
|
||||
update_texture(2);
|
||||
|
||||
} else if (it->second->getType() == ResourceType::RT_ColorGroup) {
|
||||
// Load vertex color into mesh, when any
|
||||
ColorGroup *group = static_cast<ColorGroup *>(it->second);
|
||||
if (mesh->mColors[0] == nullptr) {
|
||||
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
|
||||
}
|
||||
|
||||
auto update_color = [&](int idx) {
|
||||
if (pindex[idx] != IdNotSet) {
|
||||
size_t vertex_index = face.mIndices[idx];
|
||||
mesh->mColors[0][vertex_index] = group->mColors[pindex[idx]];
|
||||
}
|
||||
};
|
||||
|
||||
update_color(0);
|
||||
update_color(1);
|
||||
update_color(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load texture coordinates into mesh, when any
|
||||
if (group != nullptr) {
|
||||
size_t i0 = face.mIndices[0];
|
||||
size_t i1 = face.mIndices[1];
|
||||
size_t i2 = face.mIndices[2];
|
||||
mesh->mTextureCoords[0][i0] = aiVector3D(group->mTex2dCoords[texId[0]].x, group->mTex2dCoords[texId[0]].y, 0.0f);
|
||||
mesh->mTextureCoords[0][i1] = aiVector3D(group->mTex2dCoords[texId[1]].x, group->mTex2dCoords[texId[1]].y, 0.0f);
|
||||
mesh->mTextureCoords[0][i2] = aiVector3D(group->mTex2dCoords[texId[2]].x, group->mTex2dCoords[texId[2]].y, 0.0f);
|
||||
}
|
||||
|
||||
faces.push_back(face);
|
||||
}
|
||||
}
|
||||
|
@ -598,6 +672,38 @@ aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basemater
|
|||
return material;
|
||||
}
|
||||
|
||||
void XmlSerializer::ReadColor(XmlNode &node, ColorGroup *colorGroup) {
|
||||
if (node.empty() || nullptr == colorGroup) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (XmlNode currentNode : node.children()) {
|
||||
const std::string currentName = currentNode.name();
|
||||
if (currentName == XmlTag::color_item) {
|
||||
const char *color = currentNode.attribute(XmlTag::color_vaule).as_string();
|
||||
aiColor4D color_value;
|
||||
if (parseColor(color, color_value)) {
|
||||
colorGroup->mColors.push_back(color_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XmlSerializer::ReadColorGroup(XmlNode &node) {
|
||||
if (node.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int id = IdNotSet;
|
||||
if (!XmlParser::getIntAttribute(node, XmlTag::id, id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ColorGroup *group = new ColorGroup(id);
|
||||
ReadColor(node, group);
|
||||
mResourcesDictionnary.insert(std::make_pair(id, group));
|
||||
}
|
||||
|
||||
void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
|
||||
if (nullptr == scene) {
|
||||
return;
|
||||
|
|
|
@ -57,6 +57,7 @@ class D3MFOpcPackage;
|
|||
class Object;
|
||||
class Texture2DGroup;
|
||||
class EmbeddedTexture;
|
||||
class ColorGroup;
|
||||
|
||||
class XmlSerializer {
|
||||
public:
|
||||
|
@ -78,6 +79,8 @@ private:
|
|||
void ReadTextureGroup(XmlNode &node);
|
||||
aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId);
|
||||
void StoreMaterialsInScene(aiScene *scene);
|
||||
void ReadColorGroup(XmlNode &node);
|
||||
void ReadColor(XmlNode &node, ColorGroup *colorGroup);
|
||||
|
||||
private:
|
||||
struct MetaEntry {
|
||||
|
|
|
@ -77,8 +77,8 @@ static constexpr aiImporterDesc desc = {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// skip to the next token
|
||||
inline const char *AcSkipToNextToken(const char *buffer) {
|
||||
if (!SkipSpaces(&buffer)) {
|
||||
inline const char *AcSkipToNextToken(const char *buffer, const char *end) {
|
||||
if (!SkipSpaces(&buffer, end)) {
|
||||
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL");
|
||||
}
|
||||
return buffer;
|
||||
|
@ -86,13 +86,13 @@ inline const char *AcSkipToNextToken(const char *buffer) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// read a string (may be enclosed in double quotation marks). buffer must point to "
|
||||
inline const char *AcGetString(const char *buffer, std::string &out) {
|
||||
inline const char *AcGetString(const char *buffer, const char *end, std::string &out) {
|
||||
if (*buffer == '\0') {
|
||||
throw DeadlyImportError("AC3D: Unexpected EOF in string");
|
||||
}
|
||||
++buffer;
|
||||
const char *sz = buffer;
|
||||
while ('\"' != *buffer) {
|
||||
while ('\"' != *buffer && buffer != end) {
|
||||
if (IsLineEnd(*buffer)) {
|
||||
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string");
|
||||
out = "ERROR";
|
||||
|
@ -112,8 +112,8 @@ inline const char *AcGetString(const char *buffer, std::string &out) {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// read 1 to n floats prefixed with an optional predefined identifier
|
||||
template <class T>
|
||||
inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name, size_t name_length, size_t num, T *out) {
|
||||
buffer = AcSkipToNextToken(buffer);
|
||||
inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *end, const char *name, size_t name_length, size_t num, T *out) {
|
||||
buffer = AcSkipToNextToken(buffer, end);
|
||||
if (0 != name_length) {
|
||||
if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) {
|
||||
ASSIMP_LOG_ERROR("AC3D: Unexpected token. ", name, " was expected.");
|
||||
|
@ -122,7 +122,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name
|
|||
buffer += name_length + 1;
|
||||
}
|
||||
for (unsigned int _i = 0; _i < num; ++_i) {
|
||||
buffer = AcSkipToNextToken(buffer);
|
||||
buffer = AcSkipToNextToken(buffer, end);
|
||||
buffer = fast_atoreal_move<float>(buffer, ((float *)out)[_i]);
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
AC3DImporter::AC3DImporter() :
|
||||
buffer(),
|
||||
mBuffer(),
|
||||
configSplitBFCull(),
|
||||
configEvalSubdivision(),
|
||||
mNumMeshes(),
|
||||
|
@ -164,17 +164,17 @@ const aiImporterDesc *AC3DImporter::GetInfo() const {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Get a pointer to the next line from the file
|
||||
bool AC3DImporter::GetNextLine() {
|
||||
SkipLine(&buffer);
|
||||
return SkipSpaces(&buffer);
|
||||
SkipLine(&mBuffer.data, mBuffer.end);
|
||||
return SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse an object section in an AC file
|
||||
void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
|
||||
if (!TokenMatch(buffer, "OBJECT", 6))
|
||||
return;
|
||||
bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
|
||||
if (!TokenMatch(mBuffer.data, "OBJECT", 6))
|
||||
return false;
|
||||
|
||||
SkipSpaces(&buffer);
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
|
||||
++mNumMeshes;
|
||||
|
||||
|
@ -182,7 +182,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
|
|||
Object &obj = objects.back();
|
||||
|
||||
aiLight *light = nullptr;
|
||||
if (!ASSIMP_strincmp(buffer, "light", 5)) {
|
||||
if (!ASSIMP_strincmp(mBuffer.data, "light", 5)) {
|
||||
// This is a light source. Add it to the list
|
||||
mLights->push_back(light = new aiLight());
|
||||
|
||||
|
@ -198,62 +198,66 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
|
|||
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("AC3D: Light source encountered");
|
||||
obj.type = Object::Light;
|
||||
} else if (!ASSIMP_strincmp(buffer, "group", 5)) {
|
||||
} else if (!ASSIMP_strincmp(mBuffer.data, "group", 5)) {
|
||||
obj.type = Object::Group;
|
||||
} else if (!ASSIMP_strincmp(buffer, "world", 5)) {
|
||||
} else if (!ASSIMP_strincmp(mBuffer.data, "world", 5)) {
|
||||
obj.type = Object::World;
|
||||
} else
|
||||
obj.type = Object::Poly;
|
||||
while (GetNextLine()) {
|
||||
if (TokenMatch(buffer, "kids", 4)) {
|
||||
SkipSpaces(&buffer);
|
||||
unsigned int num = strtoul10(buffer, &buffer);
|
||||
if (TokenMatch(mBuffer.data, "kids", 4)) {
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
unsigned int num = strtoul10(mBuffer.data, &mBuffer.data);
|
||||
GetNextLine();
|
||||
if (num) {
|
||||
// load the children of this object recursively
|
||||
obj.children.reserve(num);
|
||||
for (unsigned int i = 0; i < num; ++i)
|
||||
LoadObjectSection(obj.children);
|
||||
for (unsigned int i = 0; i < num; ++i) {
|
||||
if (!LoadObjectSection(obj.children)) {
|
||||
ASSIMP_LOG_WARN("AC3D: wrong number of kids");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else if (TokenMatch(buffer, "name", 4)) {
|
||||
SkipSpaces(&buffer);
|
||||
buffer = AcGetString(buffer, obj.name);
|
||||
return true;
|
||||
} else if (TokenMatch(mBuffer.data, "name", 4)) {
|
||||
SkipSpaces(&mBuffer.data, mBuffer.data);
|
||||
mBuffer.data = AcGetString(mBuffer.data, mBuffer.end, obj.name);
|
||||
|
||||
// If this is a light source, we'll also need to store
|
||||
// the name of the node in it.
|
||||
if (light) {
|
||||
light->mName.Set(obj.name);
|
||||
}
|
||||
} else if (TokenMatch(buffer, "texture", 7)) {
|
||||
SkipSpaces(&buffer);
|
||||
} else if (TokenMatch(mBuffer.data, "texture", 7)) {
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
std::string texture;
|
||||
buffer = AcGetString(buffer, texture);
|
||||
mBuffer.data = AcGetString(mBuffer.data, mBuffer.end, texture);
|
||||
obj.textures.push_back(texture);
|
||||
} else if (TokenMatch(buffer, "texrep", 6)) {
|
||||
SkipSpaces(&buffer);
|
||||
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texRepeat);
|
||||
} else if (TokenMatch(mBuffer.data, "texrep", 6)) {
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 2, &obj.texRepeat);
|
||||
if (!obj.texRepeat.x || !obj.texRepeat.y)
|
||||
obj.texRepeat = aiVector2D(1.f, 1.f);
|
||||
} else if (TokenMatch(buffer, "texoff", 6)) {
|
||||
SkipSpaces(&buffer);
|
||||
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texOffset);
|
||||
} else if (TokenMatch(buffer, "rot", 3)) {
|
||||
SkipSpaces(&buffer);
|
||||
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 9, &obj.rotation);
|
||||
} else if (TokenMatch(buffer, "loc", 3)) {
|
||||
SkipSpaces(&buffer);
|
||||
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &obj.translation);
|
||||
} else if (TokenMatch(buffer, "subdiv", 6)) {
|
||||
SkipSpaces(&buffer);
|
||||
obj.subDiv = strtoul10(buffer, &buffer);
|
||||
} else if (TokenMatch(buffer, "crease", 6)) {
|
||||
SkipSpaces(&buffer);
|
||||
obj.crease = fast_atof(buffer);
|
||||
} else if (TokenMatch(buffer, "numvert", 7)) {
|
||||
SkipSpaces(&buffer);
|
||||
} else if (TokenMatch(mBuffer.data, "texoff", 6)) {
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 2, &obj.texOffset);
|
||||
} else if (TokenMatch(mBuffer.data, "rot", 3)) {
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 9, &obj.rotation);
|
||||
} else if (TokenMatch(mBuffer.data, "loc", 3)) {
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 3, &obj.translation);
|
||||
} else if (TokenMatch(mBuffer.data, "subdiv", 6)) {
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
obj.subDiv = strtoul10(mBuffer.data, &mBuffer.data);
|
||||
} else if (TokenMatch(mBuffer.data, "crease", 6)) {
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
obj.crease = fast_atof(mBuffer.data);
|
||||
} else if (TokenMatch(mBuffer.data, "numvert", 7)) {
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
|
||||
unsigned int t = strtoul10(buffer, &buffer);
|
||||
unsigned int t = strtoul10(mBuffer.data, &mBuffer.data);
|
||||
if (t >= AI_MAX_ALLOC(aiVector3D)) {
|
||||
throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
|
||||
}
|
||||
|
@ -262,59 +266,59 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
|
|||
if (!GetNextLine()) {
|
||||
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: not all vertices have been parsed yet");
|
||||
break;
|
||||
} else if (!IsNumeric(*buffer)) {
|
||||
} else if (!IsNumeric(*mBuffer.data)) {
|
||||
ASSIMP_LOG_ERROR("AC3D: Unexpected token: not all vertices have been parsed yet");
|
||||
--buffer; // make sure the line is processed a second time
|
||||
--mBuffer.data; // make sure the line is processed a second time
|
||||
break;
|
||||
}
|
||||
obj.vertices.emplace_back();
|
||||
aiVector3D &v = obj.vertices.back();
|
||||
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &v.x);
|
||||
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 3, &v.x);
|
||||
}
|
||||
} else if (TokenMatch(buffer, "numsurf", 7)) {
|
||||
SkipSpaces(&buffer);
|
||||
} else if (TokenMatch(mBuffer.data, "numsurf", 7)) {
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
|
||||
bool Q3DWorkAround = false;
|
||||
|
||||
const unsigned int t = strtoul10(buffer, &buffer);
|
||||
const unsigned int t = strtoul10(mBuffer.data, &mBuffer.data);
|
||||
obj.surfaces.reserve(t);
|
||||
for (unsigned int i = 0; i < t; ++i) {
|
||||
GetNextLine();
|
||||
if (!TokenMatch(buffer, "SURF", 4)) {
|
||||
if (!TokenMatch(mBuffer.data, "SURF", 4)) {
|
||||
// FIX: this can occur for some files - Quick 3D for
|
||||
// example writes no surf chunks
|
||||
if (!Q3DWorkAround) {
|
||||
ASSIMP_LOG_WARN("AC3D: SURF token was expected");
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("Continuing with Quick3D Workaround enabled");
|
||||
}
|
||||
--buffer; // make sure the line is processed a second time
|
||||
--mBuffer.data; // make sure the line is processed a second time
|
||||
// break; --- see fix notes above
|
||||
|
||||
Q3DWorkAround = true;
|
||||
}
|
||||
SkipSpaces(&buffer);
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
obj.surfaces.emplace_back();
|
||||
Surface &surf = obj.surfaces.back();
|
||||
surf.flags = strtoul_cppstyle(buffer);
|
||||
surf.flags = strtoul_cppstyle(mBuffer.data);
|
||||
|
||||
while (true) {
|
||||
if (!GetNextLine()) {
|
||||
throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete");
|
||||
}
|
||||
if (TokenMatch(buffer, "mat", 3)) {
|
||||
SkipSpaces(&buffer);
|
||||
surf.mat = strtoul10(buffer);
|
||||
} else if (TokenMatch(buffer, "refs", 4)) {
|
||||
if (TokenMatch(mBuffer.data, "mat", 3)) {
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
surf.mat = strtoul10(mBuffer.data);
|
||||
} else if (TokenMatch(mBuffer.data, "refs", 4)) {
|
||||
// --- see fix notes above
|
||||
if (Q3DWorkAround) {
|
||||
if (!surf.entries.empty()) {
|
||||
buffer -= 6;
|
||||
mBuffer.data -= 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SkipSpaces(&buffer);
|
||||
const unsigned int m = strtoul10(buffer);
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
const unsigned int m = strtoul10(mBuffer.data);
|
||||
surf.entries.reserve(m);
|
||||
|
||||
obj.numRefs += m;
|
||||
|
@ -327,12 +331,12 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
|
|||
surf.entries.emplace_back();
|
||||
Surface::SurfaceEntry &entry = surf.entries.back();
|
||||
|
||||
entry.first = strtoul10(buffer, &buffer);
|
||||
SkipSpaces(&buffer);
|
||||
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &entry.second);
|
||||
entry.first = strtoul10(mBuffer.data, &mBuffer.data);
|
||||
SkipSpaces(&mBuffer.data, mBuffer.end);
|
||||
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 2, &entry.second);
|
||||
}
|
||||
} else {
|
||||
--buffer; // make sure the line is processed a second time
|
||||
--mBuffer.data; // make sure the line is processed a second time
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -340,6 +344,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
|
|||
}
|
||||
}
|
||||
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: \'kids\' line was expected");
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -445,7 +450,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|||
idx = 0;
|
||||
}
|
||||
if ((*it).entries.empty()) {
|
||||
ASSIMP_LOG_WARN("AC3D: surface her zero vertex references");
|
||||
ASSIMP_LOG_WARN("AC3D: surface has zero vertex references");
|
||||
}
|
||||
|
||||
// validate all vertex indices to make sure we won't crash here
|
||||
|
@ -463,16 +468,15 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|||
}
|
||||
|
||||
switch ((*it).GetType()) {
|
||||
// closed line
|
||||
case Surface::ClosedLine:
|
||||
needMat[idx].first += (unsigned int)(*it).entries.size();
|
||||
needMat[idx].second += (unsigned int)(*it).entries.size() << 1u;
|
||||
case Surface::ClosedLine: // closed line
|
||||
needMat[idx].first += static_cast<unsigned int>((*it).entries.size());
|
||||
needMat[idx].second += static_cast<unsigned int>((*it).entries.size() << 1u);
|
||||
break;
|
||||
|
||||
// unclosed line
|
||||
case Surface::OpenLine:
|
||||
needMat[idx].first += (unsigned int)(*it).entries.size() - 1;
|
||||
needMat[idx].second += ((unsigned int)(*it).entries.size() - 1) << 1u;
|
||||
needMat[idx].first += static_cast<unsigned int>((*it).entries.size() - 1);
|
||||
needMat[idx].second += static_cast<unsigned int>(((*it).entries.size() - 1) << 1u);
|
||||
break;
|
||||
|
||||
// triangle strip
|
||||
|
@ -574,15 +578,6 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|||
const Surface::SurfaceEntry &entry2 = src.entries[i + 1];
|
||||
const Surface::SurfaceEntry &entry3 = src.entries[i + 2];
|
||||
|
||||
// skip degenerate triangles
|
||||
if (object.vertices[entry1.first] == object.vertices[entry2.first] ||
|
||||
object.vertices[entry1.first] == object.vertices[entry3.first] ||
|
||||
object.vertices[entry2.first] == object.vertices[entry3.first]) {
|
||||
mesh->mNumFaces--;
|
||||
mesh->mNumVertices -= 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
aiFace &face = *faces++;
|
||||
face.mNumIndices = 3;
|
||||
face.mIndices = new unsigned int[face.mNumIndices];
|
||||
|
@ -760,17 +755,18 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
|
|||
std::vector<char> mBuffer2;
|
||||
TextFileToBuffer(file.get(), mBuffer2);
|
||||
|
||||
buffer = &mBuffer2[0];
|
||||
mBuffer.data = &mBuffer2[0];
|
||||
mBuffer.end = &mBuffer2[0] + mBuffer2.size();
|
||||
mNumMeshes = 0;
|
||||
|
||||
mLightsCounter = mPolysCounter = mWorldsCounter = mGroupsCounter = 0;
|
||||
|
||||
if (::strncmp(buffer, "AC3D", 4)) {
|
||||
if (::strncmp(mBuffer.data, "AC3D", 4)) {
|
||||
throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found");
|
||||
}
|
||||
|
||||
// print the file format version to the console
|
||||
unsigned int version = HexDigitToDecimal(buffer[4]);
|
||||
unsigned int version = HexDigitToDecimal(mBuffer.data[4]);
|
||||
char msg[3];
|
||||
ASSIMP_itoa10(msg, 3, version);
|
||||
ASSIMP_LOG_INFO("AC3D file format version: ", msg);
|
||||
|
@ -785,30 +781,31 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
|
|||
mLights = &lights;
|
||||
|
||||
while (GetNextLine()) {
|
||||
if (TokenMatch(buffer, "MATERIAL", 8)) {
|
||||
if (TokenMatch(mBuffer.data, "MATERIAL", 8)) {
|
||||
materials.emplace_back();
|
||||
Material &mat = materials.back();
|
||||
|
||||
// manually parse the material ... sscanf would use the buldin atof ...
|
||||
// Format: (name) rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f
|
||||
|
||||
buffer = AcSkipToNextToken(buffer);
|
||||
if ('\"' == *buffer) {
|
||||
buffer = AcGetString(buffer, mat.name);
|
||||
buffer = AcSkipToNextToken(buffer);
|
||||
mBuffer.data = AcSkipToNextToken(mBuffer.data, mBuffer.end);
|
||||
if ('\"' == *mBuffer.data) {
|
||||
mBuffer.data = AcGetString(mBuffer.data, mBuffer.end, mat.name);
|
||||
mBuffer.data = AcSkipToNextToken(mBuffer.data, mBuffer.end);
|
||||
}
|
||||
|
||||
buffer = TAcCheckedLoadFloatArray(buffer, "rgb", 3, 3, &mat.rgb);
|
||||
buffer = TAcCheckedLoadFloatArray(buffer, "amb", 3, 3, &mat.amb);
|
||||
buffer = TAcCheckedLoadFloatArray(buffer, "emis", 4, 3, &mat.emis);
|
||||
buffer = TAcCheckedLoadFloatArray(buffer, "spec", 4, 3, &mat.spec);
|
||||
buffer = TAcCheckedLoadFloatArray(buffer, "shi", 3, 1, &mat.shin);
|
||||
buffer = TAcCheckedLoadFloatArray(buffer, "trans", 5, 1, &mat.trans);
|
||||
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "rgb", 3, 3, &mat.rgb);
|
||||
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "amb", 3, 3, &mat.amb);
|
||||
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "emis", 4, 3, &mat.emis);
|
||||
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "spec", 4, 3, &mat.spec);
|
||||
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "shi", 3, 1, &mat.shin);
|
||||
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "trans", 5, 1, &mat.trans);
|
||||
} else {
|
||||
LoadObjectSection(rootObjects);
|
||||
}
|
||||
LoadObjectSection(rootObjects);
|
||||
}
|
||||
|
||||
if (rootObjects.empty() || !mNumMeshes) {
|
||||
if (rootObjects.empty() || mNumMeshes == 0u) {
|
||||
throw DeadlyImportError("AC3D: No meshes have been loaded");
|
||||
}
|
||||
if (materials.empty()) {
|
||||
|
@ -824,7 +821,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
|
|||
materials.reserve(mNumMeshes);
|
||||
|
||||
// generate a dummy root if there are multiple objects on the top layer
|
||||
Object *root;
|
||||
Object *root = nullptr;
|
||||
if (1 == rootObjects.size())
|
||||
root = &rootObjects[0];
|
||||
else {
|
||||
|
@ -837,7 +834,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
|
|||
delete root;
|
||||
}
|
||||
|
||||
if (!::strncmp(pScene->mRootNode->mName.data, "Node", 4)) {
|
||||
if (::strncmp(pScene->mRootNode->mName.data, "Node", 4) == 0) {
|
||||
pScene->mRootNode->mName.Set("<AC3DWorld>");
|
||||
}
|
||||
|
||||
|
@ -856,7 +853,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
|
|||
|
||||
// copy lights
|
||||
pScene->mNumLights = (unsigned int)lights.size();
|
||||
if (lights.size()) {
|
||||
if (!lights.empty()) {
|
||||
pScene->mLights = new aiLight *[lights.size()];
|
||||
::memcpy(pScene->mLights, &lights[0], lights.size() * sizeof(void *));
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -216,7 +216,7 @@ private:
|
|||
* load subobjects, the method returns after a 'kids 0' was
|
||||
* encountered.
|
||||
* @objects List of output objects*/
|
||||
void LoadObjectSection(std::vector<Object> &objects);
|
||||
bool LoadObjectSection(std::vector<Object> &objects);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Convert all objects into meshes and nodes.
|
||||
|
@ -242,7 +242,7 @@ private:
|
|||
|
||||
private:
|
||||
// points to the next data line
|
||||
const char *buffer;
|
||||
aiBuffer mBuffer;
|
||||
|
||||
// Configuration option: if enabled, up to two meshes
|
||||
// are generated per material: those faces who have
|
||||
|
|
|
@ -110,10 +110,12 @@ using namespace Assimp::ASE;
|
|||
++filePtr;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Parser::Parser(const char *szFile, unsigned int fileFormatDefault) {
|
||||
Parser::Parser(const char *szFile, unsigned int fileFormatDefault) :
|
||||
filePtr(nullptr), mEnd (nullptr) {
|
||||
ai_assert(nullptr != szFile);
|
||||
|
||||
filePtr = szFile;
|
||||
mEnd = filePtr + std::strlen(filePtr);
|
||||
iFileFormat = fileFormatDefault;
|
||||
|
||||
// make sure that the color values are invalid
|
||||
|
@ -179,14 +181,22 @@ bool Parser::SkipToNextToken() {
|
|||
while (true) {
|
||||
char me = *filePtr;
|
||||
|
||||
if (filePtr == mEnd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// increase the line number counter if necessary
|
||||
if (IsLineEnd(me) && !bLastWasEndLine) {
|
||||
++iLineNumber;
|
||||
bLastWasEndLine = true;
|
||||
} else
|
||||
bLastWasEndLine = false;
|
||||
if ('*' == me || '}' == me || '{' == me) return true;
|
||||
if ('\0' == me) return false;
|
||||
if ('*' == me || '}' == me || '{' == me) {
|
||||
return true;
|
||||
}
|
||||
if ('\0' == me) {
|
||||
return false;
|
||||
}
|
||||
|
||||
++filePtr;
|
||||
}
|
||||
|
@ -344,8 +354,9 @@ void Parser::ParseLV1SoftSkinBlock() {
|
|||
unsigned int numVerts = 0;
|
||||
|
||||
const char *sz = filePtr;
|
||||
while (!IsSpaceOrNewLine(*filePtr))
|
||||
while (!IsSpaceOrNewLine(*filePtr)) {
|
||||
++filePtr;
|
||||
}
|
||||
|
||||
const unsigned int diff = (unsigned int)(filePtr - sz);
|
||||
if (diff) {
|
||||
|
@ -363,24 +374,24 @@ void Parser::ParseLV1SoftSkinBlock() {
|
|||
// Skip the mesh data - until we find a new mesh
|
||||
// or the end of the *MESH_SOFTSKINVERTS section
|
||||
while (true) {
|
||||
SkipSpacesAndLineEnd(&filePtr);
|
||||
SkipSpacesAndLineEnd(&filePtr, mEnd);
|
||||
if (*filePtr == '}') {
|
||||
++filePtr;
|
||||
return;
|
||||
} else if (!IsNumeric(*filePtr))
|
||||
break;
|
||||
|
||||
SkipLine(&filePtr);
|
||||
SkipLine(&filePtr, mEnd);
|
||||
}
|
||||
} else {
|
||||
SkipSpacesAndLineEnd(&filePtr);
|
||||
SkipSpacesAndLineEnd(&filePtr, mEnd);
|
||||
ParseLV4MeshLong(numVerts);
|
||||
|
||||
// Reserve enough storage
|
||||
curMesh->mBoneVertices.reserve(numVerts);
|
||||
|
||||
for (unsigned int i = 0; i < numVerts; ++i) {
|
||||
SkipSpacesAndLineEnd(&filePtr);
|
||||
SkipSpacesAndLineEnd(&filePtr, mEnd);
|
||||
unsigned int numWeights;
|
||||
ParseLV4MeshLong(numWeights);
|
||||
|
||||
|
@ -422,7 +433,7 @@ void Parser::ParseLV1SoftSkinBlock() {
|
|||
if (*filePtr == '\0')
|
||||
return;
|
||||
++filePtr;
|
||||
SkipSpacesAndLineEnd(&filePtr);
|
||||
SkipSpacesAndLineEnd(&filePtr, mEnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -743,7 +754,7 @@ void Parser::ParseLV3MapBlock(Texture &map) {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
bool Parser::ParseString(std::string &out, const char *szName) {
|
||||
char szBuffer[1024];
|
||||
if (!SkipSpaces(&filePtr)) {
|
||||
if (!SkipSpaces(&filePtr, mEnd)) {
|
||||
|
||||
ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Unexpected EOL", szName);
|
||||
LogWarning(szBuffer);
|
||||
|
@ -1355,7 +1366,7 @@ void Parser::ParseLV4MeshBones(unsigned int iNumBones, ASE::Mesh &mesh) {
|
|||
// Mesh bone with name ...
|
||||
if (TokenMatch(filePtr, "MESH_BONE_NAME", 14)) {
|
||||
// parse an index ...
|
||||
if (SkipSpaces(&filePtr)) {
|
||||
if (SkipSpaces(&filePtr, mEnd)) {
|
||||
unsigned int iIndex = strtoul10(filePtr, &filePtr);
|
||||
if (iIndex >= iNumBones) {
|
||||
LogWarning("Bone index is out of bounds");
|
||||
|
@ -1395,11 +1406,11 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices, ASE::Mesh &mes
|
|||
std::pair<int, float> pairOut;
|
||||
while (true) {
|
||||
// first parse the bone index ...
|
||||
if (!SkipSpaces(&filePtr)) break;
|
||||
if (!SkipSpaces(&filePtr, mEnd)) break;
|
||||
pairOut.first = strtoul10(filePtr, &filePtr);
|
||||
|
||||
// then parse the vertex weight
|
||||
if (!SkipSpaces(&filePtr)) break;
|
||||
if (!SkipSpaces(&filePtr, mEnd)) break;
|
||||
filePtr = fast_atoreal_move<float>(filePtr, pairOut.second);
|
||||
|
||||
// -1 marks unused entries
|
||||
|
@ -1675,7 +1686,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
||||
// skip spaces and tabs
|
||||
if (!SkipSpaces(&filePtr)) {
|
||||
if (!SkipSpaces(&filePtr, mEnd)) {
|
||||
LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL [#1]");
|
||||
SkipToNextToken();
|
||||
return;
|
||||
|
@ -1685,7 +1696,7 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
|||
out.iFace = strtoul10(filePtr, &filePtr);
|
||||
|
||||
// next character should be ':'
|
||||
if (!SkipSpaces(&filePtr)) {
|
||||
if (!SkipSpaces(&filePtr, mEnd)) {
|
||||
// FIX: there are some ASE files which haven't got : here ....
|
||||
LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. \':\' expected [#2]");
|
||||
SkipToNextToken();
|
||||
|
@ -1697,7 +1708,7 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
|||
// Parse all mesh indices
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
unsigned int iIndex = 0;
|
||||
if (!SkipSpaces(&filePtr)) {
|
||||
if (!SkipSpaces(&filePtr, mEnd)) {
|
||||
LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL");
|
||||
SkipToNextToken();
|
||||
return;
|
||||
|
@ -1723,7 +1734,7 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
|||
++filePtr;
|
||||
|
||||
// next character should be ':'
|
||||
if (!SkipSpaces(&filePtr) || ':' != *filePtr) {
|
||||
if (!SkipSpaces(&filePtr, mEnd) || ':' != *filePtr) {
|
||||
LogWarning("Unable to parse *MESH_FACE Element: "
|
||||
"Unexpected EOL. \':\' expected [#2]");
|
||||
SkipToNextToken();
|
||||
|
@ -1731,9 +1742,9 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
|||
}
|
||||
|
||||
++filePtr;
|
||||
if (!SkipSpaces(&filePtr)) {
|
||||
if (!SkipSpaces(&filePtr, mEnd)) {
|
||||
LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. "
|
||||
"Vertex index ecpected [#4]");
|
||||
"Vertex index expected [#4]");
|
||||
SkipToNextToken();
|
||||
return;
|
||||
}
|
||||
|
@ -1752,7 +1763,7 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
|||
|
||||
// parse the smoothing group of the face
|
||||
if (TokenMatch(filePtr, "*MESH_SMOOTHING", 15)) {
|
||||
if (!SkipSpaces(&filePtr)) {
|
||||
if (!SkipSpaces(&filePtr, mEnd)) {
|
||||
LogWarning("Unable to parse *MESH_SMOOTHING Element: "
|
||||
"Unexpected EOL. Smoothing group(s) expected [#5]");
|
||||
SkipToNextToken();
|
||||
|
@ -1771,12 +1782,12 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
|||
LogWarning(message.c_str());
|
||||
}
|
||||
}
|
||||
SkipSpaces(&filePtr);
|
||||
SkipSpaces(&filePtr, mEnd);
|
||||
if (',' != *filePtr) {
|
||||
break;
|
||||
}
|
||||
++filePtr;
|
||||
SkipSpaces(&filePtr);
|
||||
SkipSpaces(&filePtr, mEnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1792,7 +1803,7 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
|||
}
|
||||
|
||||
if (TokenMatch(filePtr, "*MESH_MTLID", 11)) {
|
||||
if (!SkipSpaces(&filePtr)) {
|
||||
if (!SkipSpaces(&filePtr, mEnd)) {
|
||||
LogWarning("Unable to parse *MESH_MTLID Element: Unexpected EOL. "
|
||||
"Material index expected [#6]");
|
||||
SkipToNextToken();
|
||||
|
@ -1840,7 +1851,7 @@ void Parser::ParseLV4MeshFloatTriple(ai_real *apOut) {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void Parser::ParseLV4MeshFloat(ai_real &fOut) {
|
||||
// skip spaces and tabs
|
||||
if (!SkipSpaces(&filePtr)) {
|
||||
if (!SkipSpaces(&filePtr, mEnd)) {
|
||||
// LOG
|
||||
LogWarning("Unable to parse float: unexpected EOL [#1]");
|
||||
fOut = 0.0;
|
||||
|
@ -1853,7 +1864,7 @@ void Parser::ParseLV4MeshFloat(ai_real &fOut) {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void Parser::ParseLV4MeshLong(unsigned int &iOut) {
|
||||
// Skip spaces and tabs
|
||||
if (!SkipSpaces(&filePtr)) {
|
||||
if (!SkipSpaces(&filePtr, mEnd)) {
|
||||
// LOG
|
||||
LogWarning("Unable to parse long: unexpected EOL [#1]");
|
||||
iOut = 0;
|
||||
|
|
|
@ -620,6 +620,9 @@ public:
|
|||
//! Pointer to current data
|
||||
const char *filePtr;
|
||||
|
||||
/// The end pointer of the file data
|
||||
const char *mEnd;
|
||||
|
||||
//! background color to be passed to the viewer
|
||||
//! QNAN if none was found
|
||||
aiColor3D m_clrBackground;
|
||||
|
|
|
@ -473,8 +473,9 @@ void COBImporter::ReadBasicNodeInfo_Ascii(Node &msh, LineSplitter &splitter, con
|
|||
} else if (splitter.match_start("Transform")) {
|
||||
for (unsigned int y = 0; y < 4 && ++splitter; ++y) {
|
||||
const char *s = splitter->c_str();
|
||||
const char *end = s + splitter->size();
|
||||
for (unsigned int x = 0; x < 4; ++x) {
|
||||
SkipSpaces(&s);
|
||||
SkipSpaces(&s, end);
|
||||
msh.transform[y][x] = fast_atof(&s);
|
||||
}
|
||||
}
|
||||
|
@ -486,12 +487,12 @@ void COBImporter::ReadBasicNodeInfo_Ascii(Node &msh, LineSplitter &splitter, con
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void COBImporter::ReadFloat3Tuple_Ascii(T &fill, const char **in) {
|
||||
void COBImporter::ReadFloat3Tuple_Ascii(T &fill, const char **in, const char *end) {
|
||||
const char *rgb = *in;
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
SkipSpaces(&rgb);
|
||||
SkipSpaces(&rgb, end);
|
||||
if (*rgb == ',') ++rgb;
|
||||
SkipSpaces(&rgb);
|
||||
SkipSpaces(&rgb, end);
|
||||
|
||||
fill[i] = fast_atof(&rgb);
|
||||
}
|
||||
|
@ -538,7 +539,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk
|
|||
}
|
||||
|
||||
const char *rgb = splitter[1];
|
||||
ReadFloat3Tuple_Ascii(mat.rgb, &rgb);
|
||||
ReadFloat3Tuple_Ascii(mat.rgb, &rgb, splitter.getEnd());
|
||||
|
||||
++splitter;
|
||||
if (!splitter.match_start("alpha ")) {
|
||||
|
@ -617,20 +618,21 @@ void COBImporter::ReadLght_Ascii(Scene &out, LineSplitter &splitter, const Chunk
|
|||
}
|
||||
|
||||
const char *rgb = splitter[1];
|
||||
ReadFloat3Tuple_Ascii(msh.color, &rgb);
|
||||
const char *end = splitter.getEnd();
|
||||
ReadFloat3Tuple_Ascii(msh.color, &rgb, end);
|
||||
|
||||
SkipSpaces(&rgb);
|
||||
SkipSpaces(&rgb, end);
|
||||
if (strncmp(rgb, "cone angle", 10) != 0) {
|
||||
ASSIMP_LOG_WARN("Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id);
|
||||
}
|
||||
SkipSpaces(rgb + 10, &rgb);
|
||||
SkipSpaces(rgb + 10, &rgb, end);
|
||||
msh.angle = fast_atof(&rgb);
|
||||
|
||||
SkipSpaces(&rgb);
|
||||
SkipSpaces(&rgb, end);
|
||||
if (strncmp(rgb, "inner angle", 11) != 0) {
|
||||
ASSIMP_LOG_WARN("Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
|
||||
}
|
||||
SkipSpaces(rgb + 11, &rgb);
|
||||
SkipSpaces(rgb + 11, &rgb, end);
|
||||
msh.inner_angle = fast_atof(&rgb);
|
||||
|
||||
// skip the rest for we can't handle this kind of physically-based lighting information.
|
||||
|
@ -703,14 +705,14 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
|
|||
|
||||
for (unsigned int cur = 0; cur < cnt && ++splitter; ++cur) {
|
||||
const char *s = splitter->c_str();
|
||||
|
||||
const char *end = splitter.getEnd();
|
||||
aiVector3D &v = msh.vertex_positions[cur];
|
||||
|
||||
SkipSpaces(&s);
|
||||
SkipSpaces(&s, end);
|
||||
v.x = fast_atof(&s);
|
||||
SkipSpaces(&s);
|
||||
SkipSpaces(&s, end);
|
||||
v.y = fast_atof(&s);
|
||||
SkipSpaces(&s);
|
||||
SkipSpaces(&s, end);
|
||||
v.z = fast_atof(&s);
|
||||
}
|
||||
} else if (splitter.match_start("Texture Vertices")) {
|
||||
|
@ -719,12 +721,13 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
|
|||
|
||||
for (unsigned int cur = 0; cur < cnt && ++splitter; ++cur) {
|
||||
const char *s = splitter->c_str();
|
||||
const char *end = splitter.getEnd();
|
||||
|
||||
aiVector2D &v = msh.texture_coords[cur];
|
||||
|
||||
SkipSpaces(&s);
|
||||
SkipSpaces(&s, end);
|
||||
v.x = fast_atof(&s);
|
||||
SkipSpaces(&s);
|
||||
SkipSpaces(&s, end);
|
||||
v.y = fast_atof(&s);
|
||||
}
|
||||
} else if (splitter.match_start("Faces")) {
|
||||
|
@ -749,8 +752,9 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
|
|||
face.material = strtoul10(splitter[6]);
|
||||
|
||||
const char *s = (++splitter)->c_str();
|
||||
const char *end = splitter.getEnd();
|
||||
for (size_t i = 0; i < face.indices.size(); ++i) {
|
||||
if (!SkipSpaces(&s)) {
|
||||
if (!SkipSpaces(&s, end)) {
|
||||
ThrowException("Expected EOL token in Face entry");
|
||||
}
|
||||
if ('<' != *s++) {
|
||||
|
|
|
@ -120,7 +120,7 @@ private:
|
|||
void ReadChunkInfo_Ascii(COB::ChunkInfo &out, const LineSplitter &splitter);
|
||||
void ReadBasicNodeInfo_Ascii(COB::Node &msh, LineSplitter &splitter, const COB::ChunkInfo &nfo);
|
||||
template <typename T>
|
||||
void ReadFloat3Tuple_Ascii(T &fill, const char **in);
|
||||
void ReadFloat3Tuple_Ascii(T &fill, const char **in, const char *end);
|
||||
|
||||
void ReadPolH_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
|
||||
void ReadBitM_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
|
||||
|
|
|
@ -82,23 +82,20 @@ CSMImporter::CSMImporter() : noSkeletonMesh(){
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
|
||||
{
|
||||
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const {
|
||||
static const char* tokens[] = {"$Filename"};
|
||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Build a string of all file extensions supported
|
||||
const aiImporterDesc* CSMImporter::GetInfo () const
|
||||
{
|
||||
const aiImporterDesc* CSMImporter::GetInfo () const {
|
||||
return &desc;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Setup configuration properties for the loader
|
||||
void CSMImporter::SetupProperties(const Importer* pImp)
|
||||
{
|
||||
void CSMImporter::SetupProperties(const Importer* pImp) {
|
||||
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
|
||||
}
|
||||
|
||||
|
@ -118,29 +115,29 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
|||
std::vector<char> mBuffer2;
|
||||
TextFileToBuffer(file.get(),mBuffer2);
|
||||
const char* buffer = &mBuffer2[0];
|
||||
|
||||
const char *end = &mBuffer2[mBuffer2.size() - 1] + 1;
|
||||
std::unique_ptr<aiAnimation> anim(new aiAnimation());
|
||||
int first = 0, last = 0x00ffffff;
|
||||
|
||||
// now process the file and look out for '$' sections
|
||||
while (true) {
|
||||
SkipSpaces(&buffer);
|
||||
SkipSpaces(&buffer, end);
|
||||
if ('\0' == *buffer)
|
||||
break;
|
||||
|
||||
if ('$' == *buffer) {
|
||||
++buffer;
|
||||
if (TokenMatchI(buffer,"firstframe",10)) {
|
||||
SkipSpaces(&buffer);
|
||||
SkipSpaces(&buffer, end);
|
||||
first = strtol10(buffer,&buffer);
|
||||
}
|
||||
else if (TokenMatchI(buffer,"lastframe",9)) {
|
||||
SkipSpaces(&buffer);
|
||||
SkipSpaces(&buffer, end);
|
||||
last = strtol10(buffer,&buffer);
|
||||
}
|
||||
else if (TokenMatchI(buffer,"rate",4)) {
|
||||
SkipSpaces(&buffer);
|
||||
float d;
|
||||
SkipSpaces(&buffer, end);
|
||||
float d = { 0.0f };
|
||||
buffer = fast_atoreal_move<float>(buffer,d);
|
||||
anim->mTicksPerSecond = d;
|
||||
}
|
||||
|
@ -148,8 +145,8 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
|||
std::vector< aiNodeAnim* > anims_temp;
|
||||
anims_temp.reserve(30);
|
||||
while (true) {
|
||||
SkipSpaces(&buffer);
|
||||
if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
|
||||
SkipSpaces(&buffer, end);
|
||||
if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer, end) && *buffer == '$')
|
||||
break; // next section
|
||||
|
||||
// Construct a new node animation channel and setup its name
|
||||
|
@ -157,41 +154,43 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
|||
aiNodeAnim* nda = anims_temp.back();
|
||||
|
||||
char* ot = nda->mNodeName.data;
|
||||
while (!IsSpaceOrNewLine(*buffer))
|
||||
while (!IsSpaceOrNewLine(*buffer)) {
|
||||
*ot++ = *buffer++;
|
||||
}
|
||||
|
||||
*ot = '\0';
|
||||
nda->mNodeName.length = static_cast<ai_uint32>(ot-nda->mNodeName.data);
|
||||
}
|
||||
|
||||
anim->mNumChannels = static_cast<unsigned int>(anims_temp.size());
|
||||
if (!anim->mNumChannels)
|
||||
if (!anim->mNumChannels) {
|
||||
throw DeadlyImportError("CSM: Empty $order section");
|
||||
}
|
||||
|
||||
// copy over to the output animation
|
||||
anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
|
||||
::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
|
||||
}
|
||||
else if (TokenMatchI(buffer,"points",6)) {
|
||||
if (!anim->mNumChannels)
|
||||
} else if (TokenMatchI(buffer,"points",6)) {
|
||||
if (!anim->mNumChannels) {
|
||||
throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
|
||||
}
|
||||
|
||||
// If we know how many frames we'll read, we can preallocate some storage
|
||||
unsigned int alloc = 100;
|
||||
if (last != 0x00ffffff)
|
||||
{
|
||||
if (last != 0x00ffffff) {
|
||||
alloc = last-first;
|
||||
alloc += alloc>>2u; // + 25%
|
||||
for (unsigned int i = 0; i < anim->mNumChannels;++i)
|
||||
for (unsigned int i = 0; i < anim->mNumChannels; ++i) {
|
||||
anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int filled = 0;
|
||||
|
||||
// Now read all point data.
|
||||
while (true) {
|
||||
SkipSpaces(&buffer);
|
||||
if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) {
|
||||
SkipSpaces(&buffer, end);
|
||||
if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer, end) || *buffer == '$')) {
|
||||
break; // next section
|
||||
}
|
||||
|
||||
|
@ -202,8 +201,8 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
|||
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
||||
|
||||
aiNodeAnim* s = anim->mChannels[i];
|
||||
if (s->mNumPositionKeys == alloc) { /* need to reallocate? */
|
||||
|
||||
if (s->mNumPositionKeys == alloc) {
|
||||
// need to reallocate?
|
||||
aiVectorKey* old = s->mPositionKeys;
|
||||
s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
|
||||
::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
|
||||
|
@ -211,24 +210,26 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
|||
}
|
||||
|
||||
// read x,y,z
|
||||
if(!SkipSpacesAndLineEnd(&buffer))
|
||||
if (!SkipSpacesAndLineEnd(&buffer, end)) {
|
||||
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample x coord");
|
||||
}
|
||||
|
||||
if (TokenMatchI(buffer, "DROPOUT", 7)) {
|
||||
// seems this is invalid marker data; at least the doc says it's possible
|
||||
ASSIMP_LOG_WARN("CSM: Encountered invalid marker data (DROPOUT)");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
|
||||
sub->mTime = (double)frame;
|
||||
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
|
||||
|
||||
if(!SkipSpacesAndLineEnd(&buffer))
|
||||
if (!SkipSpacesAndLineEnd(&buffer, end)) {
|
||||
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample y coord");
|
||||
}
|
||||
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
|
||||
|
||||
if(!SkipSpacesAndLineEnd(&buffer))
|
||||
if (!SkipSpacesAndLineEnd(&buffer, end)) {
|
||||
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample z coord");
|
||||
}
|
||||
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
|
||||
|
||||
++s->mNumPositionKeys;
|
||||
|
@ -236,22 +237,22 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
|||
}
|
||||
|
||||
// update allocation granularity
|
||||
if (filled == alloc)
|
||||
if (filled == alloc) {
|
||||
alloc *= 2;
|
||||
}
|
||||
|
||||
++filled;
|
||||
}
|
||||
// all channels must be complete in order to continue safely.
|
||||
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
||||
|
||||
if (!anim->mChannels[i]->mNumPositionKeys)
|
||||
if (!anim->mChannels[i]->mNumPositionKeys) {
|
||||
throw DeadlyImportError("CSM: Invalid marker track");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// advance to the next line
|
||||
SkipLine(&buffer);
|
||||
SkipLine(&buffer, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,7 +266,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
|||
pScene->mRootNode->mNumChildren = anim->mNumChannels;
|
||||
pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
|
||||
|
||||
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
||||
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
||||
aiNodeAnim* na = anim->mChannels[i];
|
||||
|
||||
aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
|
||||
|
|
|
@ -654,12 +654,13 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
|
|||
std::string v;
|
||||
XmlParser::getValueAsString(currentNode, v);
|
||||
const char *content = v.c_str();
|
||||
const char *end = content + v.size();
|
||||
for (unsigned int a = 0; a < 16; a++) {
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
// read a number
|
||||
content = fast_atoreal_move<ai_real>(content, controller.mBindShapeMatrix[a]);
|
||||
// skip whitespace after it
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
}
|
||||
} else if (currentName == "source") {
|
||||
ReadSource(currentNode);
|
||||
|
@ -740,7 +741,9 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
|
|||
throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <vertex_weights> data <input> element");
|
||||
}
|
||||
} else if (currentName == "vcount" && vertexCount > 0) {
|
||||
const char *text = currentNode.text().as_string();
|
||||
const std::string stdText = currentNode.text().as_string();
|
||||
const char *text = stdText.c_str();
|
||||
const char *end = text + stdText.size();
|
||||
size_t numWeights = 0;
|
||||
for (std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) {
|
||||
if (*text == 0) {
|
||||
|
@ -749,7 +752,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
|
|||
|
||||
*it = strtoul10(text, &text);
|
||||
numWeights += *it;
|
||||
SkipSpacesAndLineEnd(&text);
|
||||
SkipSpacesAndLineEnd(&text, end);
|
||||
}
|
||||
// reserve weight count
|
||||
pController.mWeights.resize(numWeights);
|
||||
|
@ -758,18 +761,19 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
|
|||
std::string stdText;
|
||||
XmlParser::getValueAsString(currentNode, stdText);
|
||||
const char *text = stdText.c_str();
|
||||
const char *end = text + stdText.size();
|
||||
for (std::vector<std::pair<size_t, size_t>>::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) {
|
||||
if (text == nullptr) {
|
||||
throw DeadlyImportError("Out of data while reading <vertex_weights>");
|
||||
}
|
||||
SkipSpacesAndLineEnd(&text);
|
||||
SkipSpacesAndLineEnd(&text, end);
|
||||
it->first = strtoul10(text, &text);
|
||||
SkipSpacesAndLineEnd(&text);
|
||||
SkipSpacesAndLineEnd(&text, end);
|
||||
if (*text == 0) {
|
||||
throw DeadlyImportError("Out of data while reading <vertex_weights>");
|
||||
}
|
||||
it->second = strtoul10(text, &text);
|
||||
SkipSpacesAndLineEnd(&text);
|
||||
SkipSpacesAndLineEnd(&text, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -952,15 +956,16 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
|
|||
std::string v;
|
||||
XmlParser::getValueAsString(currentNode, v);
|
||||
const char *content = v.c_str();
|
||||
const char *end = content + v.size();
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.r);
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.g);
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
} else if (currentName == "constant_attenuation") {
|
||||
XmlParser::getValueAsFloat(currentNode, pLight.mAttConstant);
|
||||
} else if (currentName == "linear_attenuation") {
|
||||
|
@ -1220,18 +1225,19 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
|
|||
std::string v;
|
||||
XmlParser::getValueAsString(currentNode, v);
|
||||
const char *content = v.c_str();
|
||||
const char *end = v.c_str() + v.size() + 1;
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.r);
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.g);
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.b);
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
|
||||
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.a);
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
} else if (currentName == "texture") {
|
||||
// get name of source texture/sampler
|
||||
XmlParser::getStdStrAttribute(currentNode, "texture", pSampler.mName);
|
||||
|
@ -1345,6 +1351,7 @@ void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) {
|
|||
if (node.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (XmlNode ¤tNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "mesh") {
|
||||
|
@ -1415,6 +1422,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
|
|||
XmlParser::getValueAsString(node, v);
|
||||
v = ai_trim(v);
|
||||
const char *content = v.c_str();
|
||||
const char *end = content + v.size();
|
||||
|
||||
// read values and store inside an array in the data library
|
||||
mDataLibrary[id] = Data();
|
||||
|
@ -1433,11 +1441,13 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
|
|||
}
|
||||
|
||||
s.clear();
|
||||
while (!IsSpaceOrNewLine(*content))
|
||||
s += *content++;
|
||||
while (!IsSpaceOrNewLine(*content)) {
|
||||
s += *content;
|
||||
content++;
|
||||
}
|
||||
data.mStrings.push_back(s);
|
||||
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
}
|
||||
} else {
|
||||
data.mValues.reserve(count);
|
||||
|
@ -1452,7 +1462,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
|
|||
content = fast_atoreal_move<ai_real>(content, value);
|
||||
data.mValues.push_back(value);
|
||||
// skip whitespace after it
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1617,8 +1627,10 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
|
|||
std::string v;
|
||||
XmlParser::getValueAsString(currentNode, v);
|
||||
const char *content = v.c_str();
|
||||
const char *end = content + v.size();
|
||||
|
||||
vcount.reserve(numPrimitives);
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
for (unsigned int a = 0; a < numPrimitives; a++) {
|
||||
if (*content == 0) {
|
||||
throw DeadlyImportError("Expected more values while reading <vcount> contents.");
|
||||
|
@ -1626,7 +1638,7 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
|
|||
// read a number
|
||||
vcount.push_back((size_t)strtoul10(content, &content));
|
||||
// skip whitespace after it
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1735,14 +1747,16 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
|
|||
std::string v;
|
||||
XmlParser::getValueAsString(node, v);
|
||||
const char *content = v.c_str();
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
const char *end = content + v.size();
|
||||
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
while (*content != 0) {
|
||||
// read a value.
|
||||
// Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways.
|
||||
int value = std::max(0, strtol10(content, &content));
|
||||
indices.push_back(size_t(value));
|
||||
// skip whitespace after it
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1801,8 +1815,10 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
|
|||
|
||||
// For continued primitives, the given count does not come all in one <p>, but only one primitive per <p>
|
||||
size_t numPrimitives = pNumPrimitives;
|
||||
if (pPrimType == Prim_TriFans || pPrimType == Prim_Polygon)
|
||||
if (pPrimType == Prim_TriFans || pPrimType == Prim_Polygon) {
|
||||
numPrimitives = 1;
|
||||
}
|
||||
|
||||
// For continued primitives, the given count is actually the number of <p>'s inside the parent tag
|
||||
if (pPrimType == Prim_TriStrips) {
|
||||
size_t numberOfVertices = indices.size() / numOffsets;
|
||||
|
@ -2166,15 +2182,15 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform
|
|||
}
|
||||
|
||||
// how many parameters to read per transformation type
|
||||
static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
|
||||
static constexpr unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
|
||||
std::string value;
|
||||
XmlParser::getValueAsString(node, value);
|
||||
const char *content = value.c_str();
|
||||
|
||||
const char *end = value.c_str() + value.size();
|
||||
// read as many parameters and store in the transformation
|
||||
for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
|
||||
// skip whitespace before the number
|
||||
SkipSpacesAndLineEnd(&content);
|
||||
SkipSpacesAndLineEnd(&content, end);
|
||||
// read a number
|
||||
content = fast_atoreal_move<ai_real>(content, tf.f[a]);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
* @brief Implementation of the DXF importer class
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
|
||||
|
||||
#include "AssetLib/DXF/DXFLoader.h"
|
||||
|
@ -68,25 +67,267 @@ static constexpr size_t AI_DXF_BINARY_IDENT_LEN = sizeof AI_DXF_BINARY_IDENT;
|
|||
// default vertex color that all uncolored vertices will receive
|
||||
static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
|
||||
|
||||
// color indices for DXF - 16 are supported, the table is
|
||||
// taken directly from the DXF spec.
|
||||
static const aiColor4D g_aclrDxfIndexColors[] = {
|
||||
aiColor4D(0.6f, 0.6f, 0.6f, 1.0f),
|
||||
aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
|
||||
aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
|
||||
aiColor4D (0.0f, 0.0f, 1.0f, 1.0f), // blue
|
||||
aiColor4D (0.3f, 1.0f, 0.3f, 1.0f), // light green
|
||||
aiColor4D (0.3f, 0.3f, 1.0f, 1.0f), // light blue
|
||||
aiColor4D (1.0f, 0.3f, 0.3f, 1.0f), // light red
|
||||
aiColor4D (1.0f, 0.0f, 1.0f, 1.0f), // pink
|
||||
aiColor4D (1.0f, 0.6f, 0.0f, 1.0f), // orange
|
||||
aiColor4D (0.6f, 0.3f, 0.0f, 1.0f), // dark orange
|
||||
aiColor4D (1.0f, 1.0f, 0.0f, 1.0f), // yellow
|
||||
aiColor4D (0.3f, 0.3f, 0.3f, 1.0f), // dark gray
|
||||
aiColor4D (0.8f, 0.8f, 0.8f, 1.0f), // light gray
|
||||
aiColor4D (0.0f, 00.f, 0.0f, 1.0f), // black
|
||||
aiColor4D (1.0f, 1.0f, 1.0f, 1.0f), // white
|
||||
aiColor4D (0.6f, 0.0f, 1.0f, 1.0f) // violet
|
||||
// color indices for DXF - 256 are supported, the table is
|
||||
// taken directly from the AutoCad Index (ACI) table
|
||||
// https://gohtx.com/acadcolors.php
|
||||
//STH 2024-0126
|
||||
static const aiColor4D g_aclrDxfIndexColors[256] = {
|
||||
aiColor4D (0.0f, 0.0f ,0.0f, 1.0f), //dxf color code 0
|
||||
aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 1
|
||||
aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 2
|
||||
aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 3
|
||||
aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 4
|
||||
aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 5
|
||||
aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 6
|
||||
aiColor4D (1.0f, 1.0f ,1.0f, 1.0f), //dxf color code 7
|
||||
aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 8
|
||||
aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 9
|
||||
aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 10
|
||||
aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 11
|
||||
aiColor4D (0.7f, 0.0f ,0.0f, 1.0f), //dxf color code 12
|
||||
aiColor4D (0.7f, 0.5f ,0.5f, 1.0f), //dxf color code 13
|
||||
aiColor4D (0.5f, 0.0f ,0.0f, 1.0f), //dxf color code 14
|
||||
aiColor4D (0.5f, 0.3f ,0.3f, 1.0f), //dxf color code 15
|
||||
aiColor4D (0.4f, 0.0f ,0.0f, 1.0f), //dxf color code 16
|
||||
aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 17
|
||||
aiColor4D (0.3f, 0.0f ,0.0f, 1.0f), //dxf color code 18
|
||||
aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 19
|
||||
aiColor4D (1.0f, 0.2f ,0.0f, 1.0f), //dxf color code 20
|
||||
aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 21
|
||||
aiColor4D (0.7f, 0.2f ,0.0f, 1.0f), //dxf color code 22
|
||||
aiColor4D (0.7f, 0.6f ,0.5f, 1.0f), //dxf color code 23
|
||||
aiColor4D (0.5f, 0.1f ,0.0f, 1.0f), //dxf color code 24
|
||||
aiColor4D (0.5f, 0.4f ,0.3f, 1.0f), //dxf color code 25
|
||||
aiColor4D (0.4f, 0.1f ,0.0f, 1.0f), //dxf color code 26
|
||||
aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 27
|
||||
aiColor4D (0.3f, 0.1f ,0.0f, 1.0f), //dxf color code 28
|
||||
aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 29
|
||||
aiColor4D (1.0f, 0.5f ,0.0f, 1.0f), //dxf color code 30
|
||||
aiColor4D (1.0f, 0.8f ,0.7f, 1.0f), //dxf color code 31
|
||||
aiColor4D (0.7f, 0.4f ,0.0f, 1.0f), //dxf color code 32
|
||||
aiColor4D (0.7f, 0.6f ,0.5f, 1.0f), //dxf color code 33
|
||||
aiColor4D (0.5f, 0.3f ,0.0f, 1.0f), //dxf color code 34
|
||||
aiColor4D (0.5f, 0.4f ,0.3f, 1.0f), //dxf color code 35
|
||||
aiColor4D (0.4f, 0.2f ,0.0f, 1.0f), //dxf color code 36
|
||||
aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 37
|
||||
aiColor4D (0.3f, 0.2f ,0.0f, 1.0f), //dxf color code 38
|
||||
aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 39
|
||||
aiColor4D (1.0f, 0.7f ,0.0f, 1.0f), //dxf color code 40
|
||||
aiColor4D (1.0f, 0.9f ,0.7f, 1.0f), //dxf color code 41
|
||||
aiColor4D (0.7f, 0.6f ,0.0f, 1.0f), //dxf color code 42
|
||||
aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 43
|
||||
aiColor4D (0.5f, 0.4f ,0.0f, 1.0f), //dxf color code 44
|
||||
aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 45
|
||||
aiColor4D (0.4f, 0.3f ,0.0f, 1.0f), //dxf color code 46
|
||||
aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 47
|
||||
aiColor4D (0.3f, 0.2f ,0.0f, 1.0f), //dxf color code 48
|
||||
aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 49
|
||||
aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 50
|
||||
aiColor4D (1.0f, 1.0f ,0.7f, 1.0f), //dxf color code 51
|
||||
aiColor4D (0.7f, 0.7f ,0.0f, 1.0f), //dxf color code 52
|
||||
aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 53
|
||||
aiColor4D (0.5f, 0.5f ,0.0f, 1.0f), //dxf color code 54
|
||||
aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 55
|
||||
aiColor4D (0.4f, 0.4f ,0.0f, 1.0f), //dxf color code 56
|
||||
aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 57
|
||||
aiColor4D (0.3f, 0.3f ,0.0f, 1.0f), //dxf color code 58
|
||||
aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 59
|
||||
aiColor4D (0.7f, 1.0f ,0.0f, 1.0f), //dxf color code 60
|
||||
aiColor4D (0.9f, 1.0f ,0.7f, 1.0f), //dxf color code 61
|
||||
aiColor4D (0.6f, 0.7f ,0.0f, 1.0f), //dxf color code 62
|
||||
aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 63
|
||||
aiColor4D (0.4f, 0.5f ,0.0f, 1.0f), //dxf color code 64
|
||||
aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 65
|
||||
aiColor4D (0.3f, 0.4f ,0.0f, 1.0f), //dxf color code 66
|
||||
aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 67
|
||||
aiColor4D (0.2f, 0.3f ,0.0f, 1.0f), //dxf color code 68
|
||||
aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 69
|
||||
aiColor4D (0.5f, 1.0f ,0.0f, 1.0f), //dxf color code 70
|
||||
aiColor4D (0.8f, 1.0f ,0.7f, 1.0f), //dxf color code 71
|
||||
aiColor4D (0.4f, 0.7f ,0.0f, 1.0f), //dxf color code 72
|
||||
aiColor4D (0.6f, 0.7f ,0.5f, 1.0f), //dxf color code 73
|
||||
aiColor4D (0.3f, 0.5f ,0.0f, 1.0f), //dxf color code 74
|
||||
aiColor4D (0.4f, 0.5f ,0.3f, 1.0f), //dxf color code 75
|
||||
aiColor4D (0.2f, 0.4f ,0.0f, 1.0f), //dxf color code 76
|
||||
aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 77
|
||||
aiColor4D (0.2f, 0.3f ,0.0f, 1.0f), //dxf color code 78
|
||||
aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 79
|
||||
aiColor4D (0.2f, 1.0f ,0.0f, 1.0f), //dxf color code 80
|
||||
aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 81
|
||||
aiColor4D (0.2f, 0.7f ,0.0f, 1.0f), //dxf color code 82
|
||||
aiColor4D (0.6f, 0.7f ,0.5f, 1.0f), //dxf color code 83
|
||||
aiColor4D (0.1f, 0.5f ,0.0f, 1.0f), //dxf color code 84
|
||||
aiColor4D (0.4f, 0.5f ,0.3f, 1.0f), //dxf color code 85
|
||||
aiColor4D (0.1f, 0.4f ,0.0f, 1.0f), //dxf color code 86
|
||||
aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 87
|
||||
aiColor4D (0.1f, 0.3f ,0.0f, 1.0f), //dxf color code 88
|
||||
aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 89
|
||||
aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 90
|
||||
aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 91
|
||||
aiColor4D (0.0f, 0.7f ,0.0f, 1.0f), //dxf color code 92
|
||||
aiColor4D (0.5f, 0.7f ,0.5f, 1.0f), //dxf color code 93
|
||||
aiColor4D (0.0f, 0.5f ,0.0f, 1.0f), //dxf color code 94
|
||||
aiColor4D (0.3f, 0.5f ,0.3f, 1.0f), //dxf color code 95
|
||||
aiColor4D (0.0f, 0.4f ,0.0f, 1.0f), //dxf color code 96
|
||||
aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 97
|
||||
aiColor4D (0.0f, 0.3f ,0.0f, 1.0f), //dxf color code 98
|
||||
aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 99
|
||||
aiColor4D (0.0f, 1.0f ,0.2f, 1.0f), //dxf color code 100
|
||||
aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 101
|
||||
aiColor4D (0.0f, 0.7f ,0.2f, 1.0f), //dxf color code 102
|
||||
aiColor4D (0.5f, 0.7f ,0.6f, 1.0f), //dxf color code 103
|
||||
aiColor4D (0.0f, 0.5f ,0.1f, 1.0f), //dxf color code 104
|
||||
aiColor4D (0.3f, 0.5f ,0.4f, 1.0f), //dxf color code 105
|
||||
aiColor4D (0.0f, 0.4f ,0.1f, 1.0f), //dxf color code 106
|
||||
aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 107
|
||||
aiColor4D (0.0f, 0.3f ,0.1f, 1.0f), //dxf color code 108
|
||||
aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 109
|
||||
aiColor4D (0.0f, 1.0f ,0.5f, 1.0f), //dxf color code 110
|
||||
aiColor4D (0.7f, 1.0f ,0.8f, 1.0f), //dxf color code 111
|
||||
aiColor4D (0.0f, 0.7f ,0.4f, 1.0f), //dxf color code 112
|
||||
aiColor4D (0.5f, 0.7f ,0.6f, 1.0f), //dxf color code 113
|
||||
aiColor4D (0.0f, 0.5f ,0.3f, 1.0f), //dxf color code 114
|
||||
aiColor4D (0.3f, 0.5f ,0.4f, 1.0f), //dxf color code 115
|
||||
aiColor4D (0.0f, 0.4f ,0.2f, 1.0f), //dxf color code 116
|
||||
aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 117
|
||||
aiColor4D (0.0f, 0.3f ,0.2f, 1.0f), //dxf color code 118
|
||||
aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 119
|
||||
aiColor4D (0.0f, 1.0f ,0.7f, 1.0f), //dxf color code 120
|
||||
aiColor4D (0.7f, 1.0f ,0.9f, 1.0f), //dxf color code 121
|
||||
aiColor4D (0.0f, 0.7f ,0.6f, 1.0f), //dxf color code 122
|
||||
aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 123
|
||||
aiColor4D (0.0f, 0.5f ,0.4f, 1.0f), //dxf color code 124
|
||||
aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 125
|
||||
aiColor4D (0.0f, 0.4f ,0.3f, 1.0f), //dxf color code 126
|
||||
aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 127
|
||||
aiColor4D (0.0f, 0.3f ,0.2f, 1.0f), //dxf color code 128
|
||||
aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 129
|
||||
aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 130
|
||||
aiColor4D (0.7f, 1.0f ,1.0f, 1.0f), //dxf color code 131
|
||||
aiColor4D (0.0f, 0.7f ,0.7f, 1.0f), //dxf color code 132
|
||||
aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 133
|
||||
aiColor4D (0.0f, 0.5f ,0.5f, 1.0f), //dxf color code 134
|
||||
aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 135
|
||||
aiColor4D (0.0f, 0.4f ,0.4f, 1.0f), //dxf color code 136
|
||||
aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 137
|
||||
aiColor4D (0.0f, 0.3f ,0.3f, 1.0f), //dxf color code 138
|
||||
aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 139
|
||||
aiColor4D (0.0f, 0.7f ,1.0f, 1.0f), //dxf color code 140
|
||||
aiColor4D (0.7f, 0.9f ,1.0f, 1.0f), //dxf color code 141
|
||||
aiColor4D (0.0f, 0.6f ,0.7f, 1.0f), //dxf color code 142
|
||||
aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 143
|
||||
aiColor4D (0.0f, 0.4f ,0.5f, 1.0f), //dxf color code 144
|
||||
aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 145
|
||||
aiColor4D (0.0f, 0.3f ,0.4f, 1.0f), //dxf color code 146
|
||||
aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 147
|
||||
aiColor4D (0.0f, 0.2f ,0.3f, 1.0f), //dxf color code 148
|
||||
aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 149
|
||||
aiColor4D (0.0f, 0.5f ,1.0f, 1.0f), //dxf color code 150
|
||||
aiColor4D (0.7f, 0.8f ,1.0f, 1.0f), //dxf color code 151
|
||||
aiColor4D (0.0f, 0.4f ,0.7f, 1.0f), //dxf color code 152
|
||||
aiColor4D (0.5f, 0.6f ,0.7f, 1.0f), //dxf color code 153
|
||||
aiColor4D (0.0f, 0.3f ,0.5f, 1.0f), //dxf color code 154
|
||||
aiColor4D (0.3f, 0.4f ,0.5f, 1.0f), //dxf color code 155
|
||||
aiColor4D (0.0f, 0.2f ,0.4f, 1.0f), //dxf color code 156
|
||||
aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 157
|
||||
aiColor4D (0.0f, 0.2f ,0.3f, 1.0f), //dxf color code 158
|
||||
aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 159
|
||||
aiColor4D (0.0f, 0.2f ,1.0f, 1.0f), //dxf color code 160
|
||||
aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 161
|
||||
aiColor4D (0.0f, 0.2f ,0.7f, 1.0f), //dxf color code 162
|
||||
aiColor4D (0.5f, 0.6f ,0.7f, 1.0f), //dxf color code 163
|
||||
aiColor4D (0.0f, 0.1f ,0.5f, 1.0f), //dxf color code 164
|
||||
aiColor4D (0.3f, 0.4f ,0.5f, 1.0f), //dxf color code 165
|
||||
aiColor4D (0.0f, 0.1f ,0.4f, 1.0f), //dxf color code 166
|
||||
aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 167
|
||||
aiColor4D (0.0f, 0.1f ,0.3f, 1.0f), //dxf color code 168
|
||||
aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 169
|
||||
aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 170
|
||||
aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 171
|
||||
aiColor4D (0.0f, 0.0f ,0.7f, 1.0f), //dxf color code 172
|
||||
aiColor4D (0.5f, 0.5f ,0.7f, 1.0f), //dxf color code 173
|
||||
aiColor4D (0.0f, 0.0f ,0.5f, 1.0f), //dxf color code 174
|
||||
aiColor4D (0.3f, 0.3f ,0.5f, 1.0f), //dxf color code 175
|
||||
aiColor4D (0.0f, 0.0f ,0.4f, 1.0f), //dxf color code 176
|
||||
aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 177
|
||||
aiColor4D (0.0f, 0.0f ,0.3f, 1.0f), //dxf color code 178
|
||||
aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 179
|
||||
aiColor4D (0.2f, 0.0f ,1.0f, 1.0f), //dxf color code 180
|
||||
aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 181
|
||||
aiColor4D (0.2f, 0.0f ,0.7f, 1.0f), //dxf color code 182
|
||||
aiColor4D (0.6f, 0.5f ,0.7f, 1.0f), //dxf color code 183
|
||||
aiColor4D (0.1f, 0.0f ,0.5f, 1.0f), //dxf color code 184
|
||||
aiColor4D (0.4f, 0.3f ,0.5f, 1.0f), //dxf color code 185
|
||||
aiColor4D (0.1f, 0.0f ,0.4f, 1.0f), //dxf color code 186
|
||||
aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 187
|
||||
aiColor4D (0.1f, 0.0f ,0.3f, 1.0f), //dxf color code 188
|
||||
aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 189
|
||||
aiColor4D (0.5f, 0.0f ,1.0f, 1.0f), //dxf color code 190
|
||||
aiColor4D (0.8f, 0.7f ,1.0f, 1.0f), //dxf color code 191
|
||||
aiColor4D (0.4f, 0.0f ,0.7f, 1.0f), //dxf color code 192
|
||||
aiColor4D (0.6f, 0.5f ,0.7f, 1.0f), //dxf color code 193
|
||||
aiColor4D (0.3f, 0.0f ,0.5f, 1.0f), //dxf color code 194
|
||||
aiColor4D (0.4f, 0.3f ,0.5f, 1.0f), //dxf color code 195
|
||||
aiColor4D (0.2f, 0.0f ,0.4f, 1.0f), //dxf color code 196
|
||||
aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 197
|
||||
aiColor4D (0.2f, 0.0f ,0.3f, 1.0f), //dxf color code 198
|
||||
aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 199
|
||||
aiColor4D (0.7f, 0.0f ,1.0f, 1.0f), //dxf color code 200
|
||||
aiColor4D (0.9f, 0.7f ,1.0f, 1.0f), //dxf color code 201
|
||||
aiColor4D (0.6f, 0.0f ,0.7f, 1.0f), //dxf color code 202
|
||||
aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 203
|
||||
aiColor4D (0.4f, 0.0f ,0.5f, 1.0f), //dxf color code 204
|
||||
aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 205
|
||||
aiColor4D (0.3f, 0.0f ,0.4f, 1.0f), //dxf color code 206
|
||||
aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 207
|
||||
aiColor4D (0.2f, 0.0f ,0.3f, 1.0f), //dxf color code 208
|
||||
aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 209
|
||||
aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 210
|
||||
aiColor4D (1.0f, 0.7f ,1.0f, 1.0f), //dxf color code 211
|
||||
aiColor4D (0.7f, 0.0f ,0.7f, 1.0f), //dxf color code 212
|
||||
aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 213
|
||||
aiColor4D (0.5f, 0.0f ,0.5f, 1.0f), //dxf color code 214
|
||||
aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 215
|
||||
aiColor4D (0.4f, 0.0f ,0.4f, 1.0f), //dxf color code 216
|
||||
aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 217
|
||||
aiColor4D (0.3f, 0.0f ,0.3f, 1.0f), //dxf color code 218
|
||||
aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 219
|
||||
aiColor4D (1.0f, 0.0f ,0.7f, 1.0f), //dxf color code 220
|
||||
aiColor4D (1.0f, 0.7f ,0.9f, 1.0f), //dxf color code 221
|
||||
aiColor4D (0.7f, 0.0f ,0.6f, 1.0f), //dxf color code 222
|
||||
aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 223
|
||||
aiColor4D (0.5f, 0.0f ,0.4f, 1.0f), //dxf color code 224
|
||||
aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 225
|
||||
aiColor4D (0.4f, 0.0f ,0.3f, 1.0f), //dxf color code 226
|
||||
aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 227
|
||||
aiColor4D (0.3f, 0.0f ,0.2f, 1.0f), //dxf color code 228
|
||||
aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 229
|
||||
aiColor4D (1.0f, 0.0f ,0.5f, 1.0f), //dxf color code 230
|
||||
aiColor4D (1.0f, 0.7f ,0.8f, 1.0f), //dxf color code 231
|
||||
aiColor4D (0.7f, 0.0f ,0.4f, 1.0f), //dxf color code 232
|
||||
aiColor4D (0.7f, 0.5f ,0.6f, 1.0f), //dxf color code 233
|
||||
aiColor4D (0.5f, 0.0f ,0.3f, 1.0f), //dxf color code 234
|
||||
aiColor4D (0.5f, 0.3f ,0.4f, 1.0f), //dxf color code 235
|
||||
aiColor4D (0.4f, 0.0f ,0.2f, 1.0f), //dxf color code 236
|
||||
aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 237
|
||||
aiColor4D (0.3f, 0.0f ,0.2f, 1.0f), //dxf color code 238
|
||||
aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 239
|
||||
aiColor4D (1.0f, 0.0f ,0.2f, 1.0f), //dxf color code 240
|
||||
aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 241
|
||||
aiColor4D (0.7f, 0.0f ,0.2f, 1.0f), //dxf color code 242
|
||||
aiColor4D (0.7f, 0.5f ,0.6f, 1.0f), //dxf color code 243
|
||||
aiColor4D (0.5f, 0.0f ,0.1f, 1.0f), //dxf color code 244
|
||||
aiColor4D (0.5f, 0.3f ,0.4f, 1.0f), //dxf color code 245
|
||||
aiColor4D (0.4f, 0.0f ,0.1f, 1.0f), //dxf color code 246
|
||||
aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 247
|
||||
aiColor4D (0.3f, 0.0f ,0.1f, 1.0f), //dxf color code 248
|
||||
aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 249
|
||||
aiColor4D (0.2f, 0.2f ,0.2f, 1.0f), //dxf color code 250
|
||||
aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 251
|
||||
aiColor4D (0.4f, 0.4f ,0.4f, 1.0f), //dxf color code 252
|
||||
aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 253
|
||||
aiColor4D (0.7f, 0.7f ,0.7f, 1.0f), //dxf color code 254
|
||||
aiColor4D (1.0f, 1.0f ,1.0f, 1.0f) //dxf color code 255
|
||||
};
|
||||
|
||||
#define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0]))
|
||||
|
@ -372,8 +613,12 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
|
|||
// XXX order
|
||||
aiMatrix4x4 trafo, tmp;
|
||||
aiMatrix4x4::Translation(-bl_src.base,trafo);
|
||||
trafo *= aiMatrix4x4::Scaling(insert.scale,tmp);
|
||||
//Need to translate position before scaling the insert
|
||||
//otherwise the position ends up being the position*scaling
|
||||
//STH 2024.01.17
|
||||
trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
|
||||
trafo *= aiMatrix4x4::Scaling(insert.scale,tmp);
|
||||
//trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
|
||||
|
||||
// XXX rotation currently ignored - I didn't find an appropriate sample model.
|
||||
if (insert.angle != 0.f) {
|
||||
|
|
|
@ -1807,7 +1807,7 @@ void FBXExporter::WriteObjects ()
|
|||
p.AddP70numberA("DeformPercent", 0.0);
|
||||
sdnode.AddChild(p);
|
||||
// TODO: Normally just one weight per channel, adding stub for later development
|
||||
std::vector<float>fFullWeights;
|
||||
std::vector<double>fFullWeights;
|
||||
fFullWeights.push_back(100.);
|
||||
sdnode.AddChild("FullWeights", fFullWeights);
|
||||
sdnode.Dump(outstream, binary, indent);
|
||||
|
|
|
@ -2725,6 +2725,10 @@ template <> size_t GenericFill<IfcSpatialStructureElement>(const DB& db, const L
|
|||
do { // convert the 'CompositionType' argument
|
||||
std::shared_ptr<const DataType> arg = params[base++];
|
||||
if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcSpatialStructureElement,2>::aux_is_derived[1]=true; break; }
|
||||
if (dynamic_cast<const UNSET *>(&*arg)) {
|
||||
// Consider assigning the default value as in->CompositionType = "ELEMENT".
|
||||
break;
|
||||
}
|
||||
try { GenericConvert( in->CompositionType, arg, db ); break; }
|
||||
catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcSpatialStructureElement to be a `IfcElementCompositionEnum`")); }
|
||||
} while (false);
|
||||
|
|
|
@ -1234,7 +1234,10 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
// Parse the XML
|
||||
// Find the scene root from document root.
|
||||
const pugi::xml_node &sceneRoot = documentRoot.child("irr_scene");
|
||||
if (!sceneRoot) throw new DeadlyImportError("IRR: <irr_scene> not found in file");
|
||||
if (!sceneRoot) {
|
||||
delete root;
|
||||
throw new DeadlyImportError("IRR: <irr_scene> not found in file");
|
||||
}
|
||||
for (pugi::xml_node &child : sceneRoot.children()) {
|
||||
// XML elements are either nodes, animators, attributes, or materials
|
||||
if (!ASSIMP_stricmp(child.name(), "node")) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -69,14 +69,6 @@ static constexpr aiImporterDesc desc = {
|
|||
"xml irrmesh"
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
IRRMeshImporter::IRRMeshImporter() = default;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
IRRMeshImporter::~IRRMeshImporter() = default;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool IRRMeshImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||
|
@ -116,8 +108,9 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
|
|||
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
|
||||
|
||||
// Check whether we can read from the file
|
||||
if (file == nullptr)
|
||||
if (file == nullptr) {
|
||||
throw DeadlyImportError("Failed to open IRRMESH file ", pFile);
|
||||
}
|
||||
|
||||
// Construct the irrXML parser
|
||||
XmlParser parser;
|
||||
|
@ -148,13 +141,11 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
|
|||
// int vertexFormat = 0; // 0 = normal; 1 = 2 tcoords, 2 = tangents
|
||||
bool useColors = false;
|
||||
|
||||
/*
|
||||
** irrmesh files have a top level <mesh> owning multiple <buffer> nodes.
|
||||
** Each <buffer> contains <material>, <vertices>, and <indices>
|
||||
** <material> tags here directly owns the material data specs
|
||||
** <vertices> are a vertex per line, contains position, UV1 coords, maybe UV2, normal, tangent, bitangent
|
||||
** <boundingbox> is ignored, I think assimp recalculates those?
|
||||
*/
|
||||
// irrmesh files have a top level <mesh> owning multiple <buffer> nodes.
|
||||
// Each <buffer> contains <material>, <vertices>, and <indices>
|
||||
// <material> tags here directly owns the material data specs
|
||||
// <vertices> are a vertex per line, contains position, UV1 coords, maybe UV2, normal, tangent, bitangent
|
||||
// <boundingbox> is ignored, I think assimp recalculates those?
|
||||
|
||||
// Parse the XML file
|
||||
pugi::xml_node const &meshNode = root.child("mesh");
|
||||
|
@ -201,7 +192,6 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
|
|||
// This is possible ... remove the mesh from the list and skip further reading
|
||||
ASSIMP_LOG_WARN("IRRMESH: Found mesh with zero vertices");
|
||||
releaseMaterial(&curMat);
|
||||
// releaseMesh(&curMesh);
|
||||
continue; // Bail out early
|
||||
};
|
||||
|
||||
|
@ -250,7 +240,9 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
|
|||
};
|
||||
|
||||
// We know what format buffer is, collect numbers
|
||||
ParseBufferVertices(verticesNode.text().get(), vertexFormat,
|
||||
std::string v = verticesNode.text().get();
|
||||
const char *end = v.c_str() + v.size();
|
||||
ParseBufferVertices(v.c_str(), end, vertexFormat,
|
||||
curVertices, curNormals,
|
||||
curTangents, curBitangents,
|
||||
curUVs, curUV2s, curColors, useColors);
|
||||
|
@ -329,8 +321,10 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
|
|||
|
||||
// NOTE this might explode for UTF-16 and wchars
|
||||
const char *sz = indicesNode.text().get();
|
||||
const char *end = sz + std::strlen(sz);
|
||||
|
||||
// For each index loop over aiMesh faces
|
||||
while (SkipSpacesAndLineEnd(&sz)) {
|
||||
while (SkipSpacesAndLineEnd(&sz, end)) {
|
||||
if (curFace >= faceEnd) {
|
||||
ASSIMP_LOG_ERROR("IRRMESH: Too many indices");
|
||||
break;
|
||||
|
@ -354,12 +348,18 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
|
|||
|
||||
// Copy over data to aiMesh
|
||||
*pcV++ = curVertices[idx];
|
||||
if (pcN) *pcN++ = curNormals[idx];
|
||||
if (pcT) *pcT++ = curTangents[idx];
|
||||
if (pcB) *pcB++ = curBitangents[idx];
|
||||
if (pcC0) *pcC0++ = curColors[idx];
|
||||
if (pcT0) *pcT0++ = curUVs[idx];
|
||||
if (pcT1) *pcT1++ = curUV2s[idx];
|
||||
if (pcN)
|
||||
*pcN++ = curNormals[idx];
|
||||
if (pcT)
|
||||
*pcT++ = curTangents[idx];
|
||||
if (pcB)
|
||||
*pcB++ = curBitangents[idx];
|
||||
if (pcC0)
|
||||
*pcC0++ = curColors[idx];
|
||||
if (pcT0)
|
||||
*pcT0++ = curUVs[idx];
|
||||
if (pcT1)
|
||||
*pcT1++ = curUV2s[idx];
|
||||
|
||||
// start new face
|
||||
if (++curIdx == 3) {
|
||||
|
@ -368,8 +368,9 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
|
|||
}
|
||||
}
|
||||
// We should be at the end of mFaces
|
||||
if (curFace != faceEnd)
|
||||
if (curFace != faceEnd) {
|
||||
ASSIMP_LOG_ERROR("IRRMESH: Not enough indices");
|
||||
}
|
||||
}
|
||||
|
||||
// Finish processing the mesh - do some small material workarounds
|
||||
|
@ -379,8 +380,7 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
|
|||
aiMaterial *mat = (aiMaterial *)curMat;
|
||||
mat->AddProperty(&curColors[0].a, 1, AI_MATKEY_OPACITY);
|
||||
}
|
||||
// textMeaning = 2;
|
||||
|
||||
|
||||
// end of previous buffer. A material and a mesh should be there
|
||||
if (!curMat || !curMesh) {
|
||||
ASSIMP_LOG_ERROR("IRRMESH: A buffer must contain a mesh and a material");
|
||||
|
@ -421,37 +421,37 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
|
|||
};
|
||||
}
|
||||
|
||||
void IRRMeshImporter::ParseBufferVertices(const char *sz, VertexFormat vertexFormat,
|
||||
void IRRMeshImporter::ParseBufferVertices(const char *sz, const char *end, VertexFormat vertexFormat,
|
||||
std::vector<aiVector3D> &vertices, std::vector<aiVector3D> &normals,
|
||||
std::vector<aiVector3D> &tangents, std::vector<aiVector3D> &bitangents,
|
||||
std::vector<aiVector3D> &UVs, std::vector<aiVector3D> &UV2s,
|
||||
std::vector<aiColor4D> &colors, bool &useColors) {
|
||||
// read vertices
|
||||
do {
|
||||
SkipSpacesAndLineEnd(&sz);
|
||||
SkipSpacesAndLineEnd(&sz, end);
|
||||
aiVector3D temp;
|
||||
aiColor4D c;
|
||||
|
||||
// Read the vertex position
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
vertices.push_back(temp);
|
||||
|
||||
// Read the vertex normals
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
normals.push_back(temp);
|
||||
|
||||
// read the vertex colors
|
||||
|
@ -463,14 +463,14 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, VertexFormat vertexFor
|
|||
useColors = true;
|
||||
|
||||
colors.push_back(c);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
|
||||
// read the first UV coordinate set
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
temp.z = 0.f;
|
||||
temp.y = 1.f - temp.y; // DX to OGL
|
||||
UVs.push_back(temp);
|
||||
|
@ -480,7 +480,7 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, VertexFormat vertexFor
|
|||
// read the (optional) second UV coordinate set
|
||||
if (vertexFormat == VertexFormat::t2coord) {
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
|
||||
temp.y = 1.f - temp.y; // DX to OGL
|
||||
|
@ -490,33 +490,32 @@ void IRRMeshImporter::ParseBufferVertices(const char *sz, VertexFormat vertexFor
|
|||
else if (vertexFormat == VertexFormat::tangent) {
|
||||
// tangents
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
temp.y *= -1.0f;
|
||||
tangents.push_back(temp);
|
||||
|
||||
// bitangents
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
|
||||
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
temp.y *= -1.0f;
|
||||
bitangents.push_back(temp);
|
||||
}
|
||||
} while (SkipLine(&sz));
|
||||
/* IMPORTANT: We assume that each vertex is specified in one
|
||||
line. So we can skip the rest of the line - unknown vertex
|
||||
elements are ignored.
|
||||
*/
|
||||
} while (SkipLine(&sz, end));
|
||||
// IMPORTANT: We assume that each vertex is specified in one
|
||||
// line. So we can skip the rest of the line - unknown vertex
|
||||
// elements are ignored.
|
||||
}
|
||||
|
||||
#endif // !! ASSIMP_BUILD_NO_IRRMESH_IMPORTER
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -62,8 +62,11 @@ namespace Assimp {
|
|||
*/
|
||||
class IRRMeshImporter : public BaseImporter, public IrrlichtBase {
|
||||
public:
|
||||
IRRMeshImporter();
|
||||
~IRRMeshImporter() override;
|
||||
/// @brief The class constructor.
|
||||
IRRMeshImporter() = default;
|
||||
|
||||
/// @brief The class destructor.
|
||||
~IRRMeshImporter() override = default;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the class can handle the format of the given file.
|
||||
|
@ -93,7 +96,7 @@ private:
|
|||
tangent = 2, // "tangents" - standard + tangents and bitangents
|
||||
};
|
||||
|
||||
void ParseBufferVertices(const char *sz, VertexFormat vertexFormat,
|
||||
void ParseBufferVertices(const char *sz, const char *end, VertexFormat vertexFormat,
|
||||
std::vector<aiVector3D> &vertices, std::vector<aiVector3D> &normals,
|
||||
std::vector<aiVector3D> &tangents, std::vector<aiVector3D> &bitangents,
|
||||
std::vector<aiVector3D> &UVs, std::vector<aiVector3D> &UV2s,
|
||||
|
|
|
@ -135,21 +135,23 @@ void IrrlichtBase::ReadVectorProperty(VectorProperty &out, pugi::xml_node& vecto
|
|||
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
|
||||
// three floats, separated with commas
|
||||
const char *ptr = attrib.value();
|
||||
size_t len = std::strlen(ptr);
|
||||
const char *end = ptr + len;
|
||||
|
||||
SkipSpaces(&ptr);
|
||||
SkipSpaces(&ptr, end);
|
||||
ptr = fast_atoreal_move<float>(ptr, (float &)out.value.x);
|
||||
SkipSpaces(&ptr);
|
||||
SkipSpaces(&ptr, end);
|
||||
if (',' != *ptr) {
|
||||
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
|
||||
} else {
|
||||
SkipSpaces(ptr + 1, &ptr);
|
||||
SkipSpaces(ptr + 1, &ptr, end);
|
||||
}
|
||||
ptr = fast_atoreal_move<float>(ptr, (float &)out.value.y);
|
||||
SkipSpaces(&ptr);
|
||||
SkipSpaces(&ptr, end);
|
||||
if (',' != *ptr) {
|
||||
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
|
||||
} else {
|
||||
SkipSpaces(ptr + 1, &ptr);
|
||||
SkipSpaces(ptr + 1, &ptr, end);
|
||||
}
|
||||
ptr = fast_atoreal_move<float>(ptr, (float &)out.value.z);
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& face
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
|
||||
void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator &it,
|
||||
LE_NCONST uint16_t*& cursor,
|
||||
const uint16_t* const end,
|
||||
unsigned int max) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -78,14 +78,14 @@ static constexpr aiImporterDesc desc = {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Recursive parsing of LWS files
|
||||
void LWS::Element::Parse(const char *&buffer) {
|
||||
for (; SkipSpacesAndLineEnd(&buffer); SkipLine(&buffer)) {
|
||||
void LWS::Element::Parse(const char *&buffer, const char *end) {
|
||||
for (; SkipSpacesAndLineEnd(&buffer, end); SkipLine(&buffer, end)) {
|
||||
|
||||
// begin of a new element with children
|
||||
bool sub = false;
|
||||
if (*buffer == '{') {
|
||||
++buffer;
|
||||
SkipSpaces(&buffer);
|
||||
SkipSpaces(&buffer, end);
|
||||
sub = true;
|
||||
} else if (*buffer == '}')
|
||||
return;
|
||||
|
@ -98,16 +98,15 @@ void LWS::Element::Parse(const char *&buffer) {
|
|||
while (!IsSpaceOrNewLine(*buffer))
|
||||
++buffer;
|
||||
children.back().tokens[0] = std::string(cur, (size_t)(buffer - cur));
|
||||
SkipSpaces(&buffer);
|
||||
SkipSpaces(&buffer, end);
|
||||
|
||||
if (children.back().tokens[0] == "Plugin") {
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("LWS: Skipping over plugin-specific data");
|
||||
|
||||
// strange stuff inside Plugin/Endplugin blocks. Needn't
|
||||
// follow LWS syntax, so we skip over it
|
||||
for (; SkipSpacesAndLineEnd(&buffer); SkipLine(&buffer)) {
|
||||
for (; SkipSpacesAndLineEnd(&buffer, end); SkipLine(&buffer, end)) {
|
||||
if (!::strncmp(buffer, "EndPlugin", 9)) {
|
||||
//SkipLine(&buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +121,7 @@ void LWS::Element::Parse(const char *&buffer) {
|
|||
|
||||
// parse more elements recursively
|
||||
if (sub) {
|
||||
children.back().Parse(buffer);
|
||||
children.back().Parse(buffer, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -155,6 +154,8 @@ const aiImporterDesc *LWSImporter::GetInfo() const {
|
|||
return &desc;
|
||||
}
|
||||
|
||||
static constexpr int MagicHackNo = 150392;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Setup configuration properties
|
||||
void LWSImporter::SetupProperties(const Importer *pImp) {
|
||||
|
@ -163,11 +164,11 @@ void LWSImporter::SetupProperties(const Importer *pImp) {
|
|||
|
||||
// AI_CONFIG_IMPORT_LWS_ANIM_START
|
||||
first = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_START,
|
||||
150392 /* magic hack */);
|
||||
MagicHackNo /* magic hack */);
|
||||
|
||||
// AI_CONFIG_IMPORT_LWS_ANIM_END
|
||||
last = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_END,
|
||||
150392 /* magic hack */);
|
||||
MagicHackNo /* magic hack */);
|
||||
|
||||
if (last < first) {
|
||||
std::swap(last, first);
|
||||
|
@ -191,15 +192,16 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
|
|||
|
||||
for (++it; it != dad.children.end(); ++it) {
|
||||
const char *c = (*it).tokens[1].c_str();
|
||||
const char *end = c + (*it).tokens[1].size();
|
||||
|
||||
if ((*it).tokens[0] == "Key") {
|
||||
fill.keys.emplace_back();
|
||||
LWO::Key &key = fill.keys.back();
|
||||
|
||||
float f;
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
c = fast_atoreal_move<float>(c, key.value);
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
c = fast_atoreal_move<float>(c, f);
|
||||
|
||||
key.time = f;
|
||||
|
@ -231,13 +233,13 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
|
|||
ASSIMP_LOG_ERROR("LWS: Unknown span type");
|
||||
}
|
||||
for (unsigned int i = 0; i < num; ++i) {
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
c = fast_atoreal_move<float>(c, key.params[i]);
|
||||
}
|
||||
} else if ((*it).tokens[0] == "Behaviors") {
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
fill.pre = (LWO::PrePostBehaviour)strtoul10(c, &c);
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
fill.post = (LWO::PrePostBehaviour)strtoul10(c, &c);
|
||||
}
|
||||
}
|
||||
|
@ -245,47 +247,45 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Read animation channels in the old LightWave animation format
|
||||
void LWSImporter::ReadEnvelope_Old(
|
||||
std::list<LWS::Element>::const_iterator &it,
|
||||
const std::list<LWS::Element>::const_iterator &end,
|
||||
LWS::NodeDesc &nodes,
|
||||
unsigned int /*version*/) {
|
||||
unsigned int num, sub_num;
|
||||
if (++it == end) goto unexpected_end;
|
||||
void LWSImporter::ReadEnvelope_Old(std::list<LWS::Element>::const_iterator &it,const std::list<LWS::Element>::const_iterator &endIt,
|
||||
LWS::NodeDesc &nodes, unsigned int) {
|
||||
if (++it == endIt) {
|
||||
ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
|
||||
return;
|
||||
}
|
||||
|
||||
num = strtoul10((*it).tokens[0].c_str());
|
||||
const unsigned int num = strtoul10((*it).tokens[0].c_str());
|
||||
for (unsigned int i = 0; i < num; ++i) {
|
||||
|
||||
nodes.channels.emplace_back();
|
||||
LWO::Envelope &envl = nodes.channels.back();
|
||||
|
||||
envl.index = i;
|
||||
envl.type = (LWO::EnvelopeType)(i + 1);
|
||||
|
||||
if (++it == end) {
|
||||
goto unexpected_end;
|
||||
if (++it == endIt) {
|
||||
ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
|
||||
return;
|
||||
}
|
||||
sub_num = strtoul10((*it).tokens[0].c_str());
|
||||
|
||||
|
||||
const unsigned int sub_num = strtoul10((*it).tokens[0].c_str());
|
||||
for (unsigned int n = 0; n < sub_num; ++n) {
|
||||
|
||||
if (++it == end) goto unexpected_end;
|
||||
if (++it == endIt) {
|
||||
ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
|
||||
return;
|
||||
}
|
||||
|
||||
// parse value and time, skip the rest for the moment.
|
||||
LWO::Key key;
|
||||
const char *c = fast_atoreal_move<float>((*it).tokens[0].c_str(), key.value);
|
||||
SkipSpaces(&c);
|
||||
const char *end = c + (*it).tokens[0].size();
|
||||
SkipSpaces(&c, end);
|
||||
float f;
|
||||
fast_atoreal_move<float>((*it).tokens[0].c_str(), f);
|
||||
key.time = f;
|
||||
|
||||
envl.keys.push_back(key);
|
||||
envl.keys.emplace_back(key);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
unexpected_end:
|
||||
ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -296,7 +296,6 @@ void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
|
|||
// the name depends on the type. We break LWS's strange naming convention
|
||||
// and return human-readable, but still machine-parsable and unique, strings.
|
||||
if (src.type == LWS::NodeDesc::OBJECT) {
|
||||
|
||||
if (src.path.length()) {
|
||||
std::string::size_type s = src.path.find_last_of("\\/");
|
||||
if (s == std::string::npos) {
|
||||
|
@ -501,7 +500,8 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
// Parse the file structure
|
||||
LWS::Element root;
|
||||
const char *dummy = &mBuffer[0];
|
||||
root.Parse(dummy);
|
||||
const char *dummyEnd = dummy + mBuffer.size();
|
||||
root.Parse(dummy, dummyEnd);
|
||||
|
||||
// Construct a Batch-importer to read more files recursively
|
||||
BatchLoader batch(pIOHandler);
|
||||
|
@ -540,6 +540,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
// Now read all elements in a very straightforward manner
|
||||
for (; it != root.children.end(); ++it) {
|
||||
const char *c = (*it).tokens[1].c_str();
|
||||
const char *end = c + (*it).tokens[1].size();
|
||||
|
||||
// 'FirstFrame': begin of animation slice
|
||||
if ((*it).tokens[0] == "FirstFrame") {
|
||||
|
@ -567,14 +568,14 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
LWS::NodeDesc d;
|
||||
d.type = LWS::NodeDesc::OBJECT;
|
||||
if (version >= 4) { // handle LWSC 4 explicit ID
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
d.number = strtoul16(c, &c) & AI_LWS_MASK;
|
||||
} else {
|
||||
d.number = cur_object++;
|
||||
}
|
||||
|
||||
// and add the file to the import list
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
std::string path = FindLWOFile(c);
|
||||
d.path = path;
|
||||
d.id = batch.AddLoadRequest(path, 0, &props);
|
||||
|
@ -588,7 +589,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
|
||||
if (version >= 4) { // handle LWSC 4 explicit ID
|
||||
d.number = strtoul16(c, &c) & AI_LWS_MASK;
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
} else {
|
||||
d.number = cur_object++;
|
||||
}
|
||||
|
@ -604,7 +605,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
d.type = LWS::NodeDesc::OBJECT;
|
||||
if (version >= 4) { // handle LWSC 4 explicit ID
|
||||
d.number = strtoul16(c, &c) & AI_LWS_MASK;
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
} else {
|
||||
d.number = cur_object++;
|
||||
}
|
||||
|
@ -668,26 +669,25 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
// two ints per envelope
|
||||
LWO::Envelope &env = *envelopeIt;
|
||||
env.pre = (LWO::PrePostBehaviour)strtoul10(c, &c);
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
env.post = (LWO::PrePostBehaviour)strtoul10(c, &c);
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 'ParentItem': specifies the parent of the current element
|
||||
else if ((*it).tokens[0] == "ParentItem") {
|
||||
if (nodes.empty())
|
||||
if (nodes.empty()) {
|
||||
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentItem\'");
|
||||
|
||||
else
|
||||
} else {
|
||||
nodes.back().parent = strtoul16(c, &c);
|
||||
}
|
||||
}
|
||||
// 'ParentObject': deprecated one for older formats
|
||||
else if (version < 3 && (*it).tokens[0] == "ParentObject") {
|
||||
if (nodes.empty())
|
||||
if (nodes.empty()) {
|
||||
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentObject\'");
|
||||
|
||||
else {
|
||||
} else {
|
||||
nodes.back().parent = strtoul10(c, &c) | (1u << 28u);
|
||||
}
|
||||
}
|
||||
|
@ -700,19 +700,20 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
|
||||
if (version >= 4) { // handle LWSC 4 explicit ID
|
||||
d.number = strtoul16(c, &c) & AI_LWS_MASK;
|
||||
} else
|
||||
} else {
|
||||
d.number = cur_camera++;
|
||||
}
|
||||
nodes.push_back(d);
|
||||
|
||||
num_camera++;
|
||||
}
|
||||
// 'CameraName': set name of currently active camera
|
||||
else if ((*it).tokens[0] == "CameraName") {
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA)
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA) {
|
||||
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'CameraName\'");
|
||||
|
||||
else
|
||||
} else {
|
||||
nodes.back().name = c;
|
||||
}
|
||||
}
|
||||
// 'AddLight': add a light to the scenegraph
|
||||
else if ((*it).tokens[0] == "AddLight") {
|
||||
|
@ -723,19 +724,20 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
|
||||
if (version >= 4) { // handle LWSC 4 explicit ID
|
||||
d.number = strtoul16(c, &c) & AI_LWS_MASK;
|
||||
} else
|
||||
} else {
|
||||
d.number = cur_light++;
|
||||
}
|
||||
nodes.push_back(d);
|
||||
|
||||
num_light++;
|
||||
}
|
||||
// 'LightName': set name of currently active light
|
||||
else if ((*it).tokens[0] == "LightName") {
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
|
||||
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightName\'");
|
||||
|
||||
else
|
||||
} else {
|
||||
nodes.back().name = c;
|
||||
}
|
||||
}
|
||||
// 'LightIntensity': set intensity of currently active light
|
||||
else if ((*it).tokens[0] == "LightIntensity" || (*it).tokens[0] == "LgtIntensity") {
|
||||
|
@ -753,62 +755,58 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
}
|
||||
// 'LightType': set type of currently active light
|
||||
else if ((*it).tokens[0] == "LightType") {
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
|
||||
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightType\'");
|
||||
|
||||
else
|
||||
} else {
|
||||
nodes.back().lightType = strtoul10(c);
|
||||
|
||||
}
|
||||
}
|
||||
// 'LightFalloffType': set falloff type of currently active light
|
||||
else if ((*it).tokens[0] == "LightFalloffType") {
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
|
||||
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightFalloffType\'");
|
||||
else
|
||||
} else {
|
||||
nodes.back().lightFalloffType = strtoul10(c);
|
||||
|
||||
}
|
||||
}
|
||||
// 'LightConeAngle': set cone angle of currently active light
|
||||
else if ((*it).tokens[0] == "LightConeAngle") {
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
|
||||
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightConeAngle\'");
|
||||
|
||||
else
|
||||
} else {
|
||||
nodes.back().lightConeAngle = fast_atof(c);
|
||||
|
||||
}
|
||||
}
|
||||
// 'LightEdgeAngle': set area where we're smoothing from min to max intensity
|
||||
else if ((*it).tokens[0] == "LightEdgeAngle") {
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
|
||||
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightEdgeAngle\'");
|
||||
|
||||
else
|
||||
} else {
|
||||
nodes.back().lightEdgeAngle = fast_atof(c);
|
||||
|
||||
}
|
||||
}
|
||||
// 'LightColor': set color of currently active light
|
||||
else if ((*it).tokens[0] == "LightColor") {
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
|
||||
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
|
||||
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightColor\'");
|
||||
|
||||
else {
|
||||
} else {
|
||||
c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.r);
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.g);
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
c = fast_atoreal_move<float>(c, (float &)nodes.back().lightColor.b);
|
||||
}
|
||||
}
|
||||
|
||||
// 'PivotPosition': position of local transformation origin
|
||||
else if ((*it).tokens[0] == "PivotPosition" || (*it).tokens[0] == "PivotPoint") {
|
||||
if (nodes.empty())
|
||||
if (nodes.empty()) {
|
||||
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'PivotPosition\'");
|
||||
else {
|
||||
} else {
|
||||
c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.x);
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.y);
|
||||
SkipSpaces(&c);
|
||||
SkipSpaces(&c, end);
|
||||
c = fast_atoreal_move<float>(c, (float &)nodes.back().pivotPos.z);
|
||||
// Mark pivotPos as set
|
||||
nodes.back().isPivotSet = true;
|
||||
|
@ -818,7 +816,6 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
|
||||
// resolve parenting
|
||||
for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
|
||||
|
||||
// check whether there is another node which calls us a parent
|
||||
for (std::list<LWS::NodeDesc>::iterator dit = nodes.begin(); dit != nodes.end(); ++dit) {
|
||||
if (dit != ndIt && *ndIt == (*dit).parent) {
|
||||
|
@ -854,7 +851,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
aiNode *nd = master->mRootNode = new aiNode();
|
||||
|
||||
// allocate storage for cameras&lights
|
||||
if (num_camera) {
|
||||
if (num_camera > 0u) {
|
||||
master->mCameras = new aiCamera *[master->mNumCameras = num_camera];
|
||||
}
|
||||
aiCamera **cams = master->mCameras;
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
std::list<Element> children;
|
||||
|
||||
//! Recursive parsing function
|
||||
void Parse(const char *&buffer);
|
||||
void Parse(const char *&buffer, const char *end);
|
||||
};
|
||||
|
||||
#define AI_LWS_MASK (0xffffffff >> 4u)
|
||||
|
|
|
@ -123,12 +123,12 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
|
|||
// remove comments from it (C++ style)
|
||||
CommentRemover::RemoveLineComments("//", &_buff[0]);
|
||||
const char *buff = &_buff[0];
|
||||
|
||||
const char *end = buff + _buff.size();
|
||||
Q3Shader::ShaderDataBlock *curData = nullptr;
|
||||
Q3Shader::ShaderMapBlock *curMap = nullptr;
|
||||
|
||||
// read line per line
|
||||
for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
|
||||
for (; SkipSpacesAndLineEnd(&buff, end); SkipLine(&buff, end)) {
|
||||
|
||||
if (*buff == '{') {
|
||||
++buff;
|
||||
|
@ -140,21 +140,21 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
|
|||
}
|
||||
|
||||
// read this data section
|
||||
for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
|
||||
for (; SkipSpacesAndLineEnd(&buff, end); SkipLine(&buff, end)) {
|
||||
if (*buff == '{') {
|
||||
++buff;
|
||||
// add new map section
|
||||
curData->maps.emplace_back();
|
||||
curMap = &curData->maps.back();
|
||||
|
||||
for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
|
||||
for (; SkipSpacesAndLineEnd(&buff, end); SkipLine(&buff, end)) {
|
||||
// 'map' - Specifies texture file name
|
||||
if (TokenMatchI(buff, "map", 3) || TokenMatchI(buff, "clampmap", 8)) {
|
||||
curMap->name = GetNextToken(buff);
|
||||
curMap->name = GetNextToken(buff, end);
|
||||
}
|
||||
// 'blendfunc' - Alpha blending mode
|
||||
else if (TokenMatchI(buff, "blendfunc", 9)) {
|
||||
const std::string blend_src = GetNextToken(buff);
|
||||
const std::string blend_src = GetNextToken(buff, end);
|
||||
if (blend_src == "add") {
|
||||
curMap->blend_src = Q3Shader::BLEND_GL_ONE;
|
||||
curMap->blend_dest = Q3Shader::BLEND_GL_ONE;
|
||||
|
@ -166,12 +166,12 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
|
|||
curMap->blend_dest = Q3Shader::BLEND_GL_ONE_MINUS_SRC_ALPHA;
|
||||
} else {
|
||||
curMap->blend_src = StringToBlendFunc(blend_src);
|
||||
curMap->blend_dest = StringToBlendFunc(GetNextToken(buff));
|
||||
curMap->blend_dest = StringToBlendFunc(GetNextToken(buff, end));
|
||||
}
|
||||
}
|
||||
// 'alphafunc' - Alpha testing mode
|
||||
else if (TokenMatchI(buff, "alphafunc", 9)) {
|
||||
const std::string at = GetNextToken(buff);
|
||||
const std::string at = GetNextToken(buff, end);
|
||||
if (at == "GT0") {
|
||||
curMap->alpha_test = Q3Shader::AT_GT0;
|
||||
} else if (at == "LT128") {
|
||||
|
@ -186,7 +186,6 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (*buff == '}') {
|
||||
++buff;
|
||||
curData = nullptr;
|
||||
|
@ -195,7 +194,7 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
|
|||
|
||||
// 'cull' specifies culling behaviour for the model
|
||||
else if (TokenMatchI(buff, "cull", 4)) {
|
||||
SkipSpaces(&buff);
|
||||
SkipSpaces(&buff, end);
|
||||
if (!ASSIMP_strincmp(buff, "back", 4)) { // render face's backside, does not function in Q3 engine (bug)
|
||||
curData->cull = Q3Shader::CULL_CCW;
|
||||
} else if (!ASSIMP_strincmp(buff, "front", 5)) { // is not valid keyword in Q3, but occurs in shaders
|
||||
|
@ -213,9 +212,10 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
|
|||
curData = &fill.blocks.back();
|
||||
|
||||
// get the name of this section
|
||||
curData->name = GetNextToken(buff);
|
||||
curData->name = GetNextToken(buff, end);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -232,6 +232,7 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io)
|
|||
const size_t s = file->FileSize();
|
||||
std::vector<char> _buff(s + 1);
|
||||
const char *buff = &_buff[0];
|
||||
const char *end = buff + _buff.size();
|
||||
file->Read(&_buff[0], s, 1);
|
||||
_buff[s] = 0;
|
||||
|
||||
|
@ -240,10 +241,10 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io)
|
|||
|
||||
// read token by token and fill output table
|
||||
for (; *buff;) {
|
||||
SkipSpacesAndLineEnd(&buff);
|
||||
SkipSpacesAndLineEnd(&buff, end);
|
||||
|
||||
// get first identifier
|
||||
std::string ss = GetNextToken(buff);
|
||||
std::string ss = GetNextToken(buff, end);
|
||||
|
||||
// ignore tokens starting with tag_
|
||||
if (!::strncmp(&ss[0], "tag_", std::min((size_t)4, ss.length())))
|
||||
|
@ -253,8 +254,9 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io)
|
|||
SkinData::TextureEntry &entry = fill.textures.back();
|
||||
|
||||
entry.first = ss;
|
||||
entry.second = GetNextToken(buff);
|
||||
entry.second = GetNextToken(buff, end);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -293,7 +295,7 @@ void Q3Shader::ConvertShaderToMaterial(aiMaterial *out, const ShaderDataBlock &s
|
|||
// - in any case: set it as diffuse texture
|
||||
//
|
||||
// If the texture is using 'filter' blending
|
||||
// - take as lightmap
|
||||
// - take as light-map
|
||||
//
|
||||
// Textures with alpha funcs
|
||||
// - aiTextureFlags_UseAlpha is set (otherwise aiTextureFlags_NoAlpha is explicitly set)
|
||||
|
|
|
@ -210,7 +210,7 @@ void MD5Importer::MakeDataUnique(MD5::MeshDesc &meshSrc) {
|
|||
const unsigned int guess = (unsigned int)(fWeightsPerVert * iNewNum);
|
||||
meshSrc.mWeights.reserve(guess + (guess >> 3)); // + 12.5% as buffer
|
||||
|
||||
for (FaceList::const_iterator iter = meshSrc.mFaces.begin(), iterEnd = meshSrc.mFaces.end(); iter != iterEnd; ++iter) {
|
||||
for (FaceArray::const_iterator iter = meshSrc.mFaces.begin(), iterEnd = meshSrc.mFaces.end(); iter != iterEnd; ++iter) {
|
||||
const aiFace &face = *iter;
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
if (face.mIndices[0] >= meshSrc.mVertices.size()) {
|
||||
|
@ -231,7 +231,7 @@ void MD5Importer::MakeDataUnique(MD5::MeshDesc &meshSrc) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Recursive node graph construction from a MD5MESH
|
||||
void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones) {
|
||||
void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneArray &bones) {
|
||||
ai_assert(nullptr != piParent);
|
||||
ai_assert(!piParent->mNumChildren);
|
||||
|
||||
|
@ -282,7 +282,7 @@ void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &b
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Recursive node graph construction from a MD5ANIM
|
||||
void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneList &bones, const aiNodeAnim **node_anims) {
|
||||
void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneArray &bones, const aiNodeAnim **node_anims) {
|
||||
ai_assert(nullptr != piParent);
|
||||
ai_assert(!piParent->mNumChildren);
|
||||
|
||||
|
@ -402,7 +402,7 @@ void MD5Importer::LoadMD5MeshFile() {
|
|||
|
||||
// copy texture coordinates
|
||||
aiVector3D *pv = mesh->mTextureCoords[0];
|
||||
for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
|
||||
for (MD5::VertexArray::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
|
||||
pv->x = (*iter).mUV.x;
|
||||
pv->y = 1.0f - (*iter).mUV.y; // D3D to OpenGL
|
||||
pv->z = 0.0f;
|
||||
|
@ -412,7 +412,7 @@ void MD5Importer::LoadMD5MeshFile() {
|
|||
unsigned int *piCount = new unsigned int[meshParser.mJoints.size()];
|
||||
::memset(piCount, 0, sizeof(unsigned int) * meshParser.mJoints.size());
|
||||
|
||||
for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
|
||||
for (MD5::VertexArray::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
|
||||
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
|
||||
MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
|
||||
/* FIX for some invalid exporters */
|
||||
|
@ -447,7 +447,7 @@ void MD5Importer::LoadMD5MeshFile() {
|
|||
}
|
||||
|
||||
pv = mesh->mVertices;
|
||||
for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
|
||||
for (MD5::VertexArray::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
|
||||
// compute the final vertex position from all single weights
|
||||
*pv = aiVector3D();
|
||||
|
||||
|
@ -585,14 +585,14 @@ void MD5Importer::LoadMD5AnimFile() {
|
|||
// 1 tick == 1 frame
|
||||
anim->mTicksPerSecond = animParser.fFrameRate;
|
||||
|
||||
for (FrameList::const_iterator iter = animParser.mFrames.begin(), iterEnd = animParser.mFrames.end(); iter != iterEnd; ++iter) {
|
||||
for (FrameArray::const_iterator iter = animParser.mFrames.begin(), iterEnd = animParser.mFrames.end(); iter != iterEnd; ++iter) {
|
||||
double dTime = (double)(*iter).iIndex;
|
||||
aiNodeAnim **pcAnimNode = anim->mChannels;
|
||||
if (!(*iter).mValues.empty() || iter == animParser.mFrames.begin()) /* be sure we have at least one frame */
|
||||
{
|
||||
// now process all values in there ... read all joints
|
||||
MD5::BaseFrameDesc *pcBaseFrame = &animParser.mBaseFrames[0];
|
||||
for (AnimBoneList::const_iterator iter2 = animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end(); ++iter2,
|
||||
for (AnimBoneArray::const_iterator iter2 = animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end(); ++iter2,
|
||||
++pcAnimNode, ++pcBaseFrame) {
|
||||
if ((*iter2).iFirstKeyIndex >= (*iter).mValues.size()) {
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -118,7 +118,7 @@ protected:
|
|||
* @param node_anims Generated node animations
|
||||
*/
|
||||
void AttachChilds_Anim(int iParentID, aiNode *piParent,
|
||||
AnimBoneList &bones, const aiNodeAnim **node_anims);
|
||||
AnimBoneArray &bones, const aiNodeAnim **node_anims);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Construct node hierarchy from a given MD5MESH
|
||||
|
@ -126,7 +126,7 @@ protected:
|
|||
* @param piParent Parent node to attach to
|
||||
* @param bones Input bones
|
||||
*/
|
||||
void AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones);
|
||||
void AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneArray &bones);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Build unique vertex buffers from a given MD5ANIM
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2023, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -138,14 +138,16 @@ bool MD5Parser::ParseSection(Section &out) {
|
|||
char *sz = buffer;
|
||||
while (!IsSpaceOrNewLine(*buffer)) {
|
||||
++buffer;
|
||||
if (buffer == bufferEnd)
|
||||
if (buffer == bufferEnd) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
out.mName = std::string(sz, (uintptr_t)(buffer - sz));
|
||||
while (IsSpace(*buffer)) {
|
||||
++buffer;
|
||||
if (buffer == bufferEnd)
|
||||
if (buffer == bufferEnd) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool running = true;
|
||||
|
@ -153,14 +155,16 @@ bool MD5Parser::ParseSection(Section &out) {
|
|||
if ('{' == *buffer) {
|
||||
// it is a normal section so read all lines
|
||||
++buffer;
|
||||
if (buffer == bufferEnd)
|
||||
if (buffer == bufferEnd) {
|
||||
return false;
|
||||
}
|
||||
bool run = true;
|
||||
while (run) {
|
||||
while (IsSpaceOrNewLine(*buffer)) {
|
||||
++buffer;
|
||||
if (buffer == bufferEnd)
|
||||
if (buffer == bufferEnd) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ('\0' == *buffer) {
|
||||
return false; // seems this was the last section
|
||||
|
@ -175,18 +179,21 @@ bool MD5Parser::ParseSection(Section &out) {
|
|||
|
||||
elem.iLineNumber = lineNumber;
|
||||
elem.szStart = buffer;
|
||||
elem.end = bufferEnd;
|
||||
|
||||
// terminate the line with zero
|
||||
while (!IsLineEnd(*buffer)) {
|
||||
++buffer;
|
||||
if (buffer == bufferEnd)
|
||||
if (buffer == bufferEnd) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (*buffer) {
|
||||
++lineNumber;
|
||||
*buffer++ = '\0';
|
||||
if (buffer == bufferEnd)
|
||||
if (buffer == bufferEnd) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -194,89 +201,107 @@ bool MD5Parser::ParseSection(Section &out) {
|
|||
// it is an element at global scope. Parse its value and go on
|
||||
sz = buffer;
|
||||
while (!IsSpaceOrNewLine(*buffer++)) {
|
||||
if (buffer == bufferEnd)
|
||||
if (buffer == bufferEnd) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
out.mGlobalValue = std::string(sz, (uintptr_t)(buffer - sz));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (buffer == bufferEnd)
|
||||
if (buffer == bufferEnd) {
|
||||
return false;
|
||||
}
|
||||
while (IsSpaceOrNewLine(*buffer)) {
|
||||
if (buffer == bufferEnd) {
|
||||
break;
|
||||
}
|
||||
++buffer;
|
||||
if (buffer == bufferEnd)
|
||||
return false;
|
||||
}
|
||||
return '\0' != *buffer;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Some dirty macros just because they're so funny and easy to debug
|
||||
|
||||
// skip all spaces ... handle EOL correctly
|
||||
#define AI_MD5_SKIP_SPACES() \
|
||||
if (!SkipSpaces(&sz)) \
|
||||
MD5Parser::ReportWarning("Unexpected end of line", elem.iLineNumber);
|
||||
inline void AI_MD5_SKIP_SPACES(const char **sz, const char *bufferEnd, int linenumber) {
|
||||
if (!SkipSpaces(sz, bufferEnd)) {
|
||||
MD5Parser::ReportWarning("Unexpected end of line", linenumber);
|
||||
}
|
||||
}
|
||||
|
||||
// read a triple float in brackets: (1.0 1.0 1.0)
|
||||
#define AI_MD5_READ_TRIPLE(vec) \
|
||||
AI_MD5_SKIP_SPACES(); \
|
||||
if ('(' != *sz++) \
|
||||
MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber); \
|
||||
AI_MD5_SKIP_SPACES(); \
|
||||
sz = fast_atoreal_move<float>(sz, (float &)vec.x); \
|
||||
AI_MD5_SKIP_SPACES(); \
|
||||
sz = fast_atoreal_move<float>(sz, (float &)vec.y); \
|
||||
AI_MD5_SKIP_SPACES(); \
|
||||
sz = fast_atoreal_move<float>(sz, (float &)vec.z); \
|
||||
AI_MD5_SKIP_SPACES(); \
|
||||
if (')' != *sz++) \
|
||||
MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
|
||||
inline void AI_MD5_READ_TRIPLE(aiVector3D &vec, const char **sz, const char *bufferEnd, int linenumber) {
|
||||
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
||||
if ('(' != **sz) {
|
||||
MD5Parser::ReportWarning("Unexpected token: ( was expected", linenumber);
|
||||
++*sz;
|
||||
}
|
||||
++*sz;
|
||||
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
||||
*sz = fast_atoreal_move<float>(*sz, (float &)vec.x);
|
||||
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
||||
*sz = fast_atoreal_move<float>(*sz, (float &)vec.y);
|
||||
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
||||
*sz = fast_atoreal_move<float>(*sz, (float &)vec.z);
|
||||
AI_MD5_SKIP_SPACES(sz, bufferEnd, linenumber);
|
||||
if (')' != **sz) {
|
||||
MD5Parser::ReportWarning("Unexpected token: ) was expected", linenumber);
|
||||
}
|
||||
++*sz;
|
||||
}
|
||||
|
||||
// parse a string, enclosed in quotation marks or not
|
||||
#define AI_MD5_PARSE_STRING(out) \
|
||||
bool bQuota = (*sz == '\"'); \
|
||||
const char *szStart = sz; \
|
||||
while (!IsSpaceOrNewLine(*sz)) \
|
||||
++sz; \
|
||||
const char *szEnd = sz; \
|
||||
if (bQuota) { \
|
||||
szStart++; \
|
||||
if ('\"' != *(szEnd -= 1)) { \
|
||||
MD5Parser::ReportWarning("Expected closing quotation marks in string", \
|
||||
elem.iLineNumber); \
|
||||
continue; \
|
||||
} \
|
||||
} \
|
||||
out.length = (size_t)(szEnd - szStart); \
|
||||
::memcpy(out.data, szStart, out.length); \
|
||||
inline bool AI_MD5_PARSE_STRING(const char **sz, const char *bufferEnd, aiString &out, int linenumber) {
|
||||
bool bQuota = (**sz == '\"');
|
||||
const char *szStart = *sz;
|
||||
while (!IsSpaceOrNewLine(**sz)) {
|
||||
++*sz;
|
||||
if (*sz == bufferEnd) break;
|
||||
}
|
||||
const char *szEnd = *sz;
|
||||
if (bQuota) {
|
||||
szStart++;
|
||||
if ('\"' != *(szEnd -= 1)) {
|
||||
MD5Parser::ReportWarning("Expected closing quotation marks in string", linenumber);
|
||||
++*sz;
|
||||
}
|
||||
}
|
||||
out.length = (ai_uint32)(szEnd - szStart);
|
||||
::memcpy(out.data, szStart, out.length);
|
||||
out.data[out.length] = '\0';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// parse a string, enclosed in quotation marks
|
||||
#define AI_MD5_PARSE_STRING_IN_QUOTATION(out) \
|
||||
out.length = 0; \
|
||||
while ('\"' != *sz && '\0' != *sz) \
|
||||
++sz; \
|
||||
if ('\0' != *sz) { \
|
||||
const char *szStart = ++sz; \
|
||||
while ('\"' != *sz && '\0' != *sz) \
|
||||
++sz; \
|
||||
if ('\0' != *sz) { \
|
||||
const char *szEnd = (sz++); \
|
||||
out.length = (ai_uint32)(szEnd - szStart); \
|
||||
::memcpy(out.data, szStart, out.length); \
|
||||
} \
|
||||
} \
|
||||
inline void AI_MD5_PARSE_STRING_IN_QUOTATION(const char **sz, const char *bufferEnd, aiString &out) {
|
||||
out.length = 0u;
|
||||
while (('\"' != **sz && '\0' != **sz) && *sz != bufferEnd) {
|
||||
++*sz;
|
||||
}
|
||||
if ('\0' != **sz) {
|
||||
const char *szStart = ++(*sz);
|
||||
|
||||
while (('\"' != **sz && '\0' != **sz) && *sz != bufferEnd) {
|
||||
++*sz;
|
||||
}
|
||||
if ('\0' != **sz) {
|
||||
const char *szEnd = *sz;
|
||||
++*sz;
|
||||
out.length = (ai_uint32)(szEnd - szStart);
|
||||
::memcpy(out.data, szStart, out.length);
|
||||
}
|
||||
}
|
||||
out.data[out.length] = '\0';
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// .MD5MESH parsing function
|
||||
MD5MeshParser::MD5MeshParser(SectionList &mSections) {
|
||||
MD5MeshParser::MD5MeshParser(SectionArray &mSections) {
|
||||
ASSIMP_LOG_DEBUG("MD5MeshParser begin");
|
||||
|
||||
// now parse all sections
|
||||
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
|
||||
for (SectionArray::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
|
||||
if ((*iter).mName == "numMeshes") {
|
||||
mMeshes.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
|
||||
} else if ((*iter).mName == "numJoints") {
|
||||
|
@ -288,14 +313,15 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
|
|||
BoneDesc &desc = mJoints.back();
|
||||
|
||||
const char *sz = elem.szStart;
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(&sz, elem.end, desc.mName);
|
||||
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
|
||||
// negative values, at least -1, is allowed here
|
||||
desc.mParentIndex = (int)strtol10(sz, &sz);
|
||||
|
||||
AI_MD5_READ_TRIPLE(desc.mPositionXYZ);
|
||||
AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there
|
||||
AI_MD5_READ_TRIPLE(desc.mPositionXYZ, &sz, elem.end, elem.iLineNumber);
|
||||
AI_MD5_READ_TRIPLE(desc.mRotationQuat, &sz, elem.end, elem.iLineNumber); // normalized quaternion, so w is not there
|
||||
}
|
||||
} else if ((*iter).mName == "mesh") {
|
||||
mMeshes.emplace_back();
|
||||
|
@ -306,52 +332,52 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
|
|||
|
||||
// shader attribute
|
||||
if (TokenMatch(sz, "shader", 6)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mShader);
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(&sz, elem.end, desc.mShader);
|
||||
}
|
||||
// numverts attribute
|
||||
else if (TokenMatch(sz, "numverts", 8)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
desc.mVertices.resize(strtoul10(sz));
|
||||
}
|
||||
// numtris attribute
|
||||
else if (TokenMatch(sz, "numtris", 7)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
desc.mFaces.resize(strtoul10(sz));
|
||||
}
|
||||
// numweights attribute
|
||||
else if (TokenMatch(sz, "numweights", 10)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
desc.mWeights.resize(strtoul10(sz));
|
||||
}
|
||||
// vert attribute
|
||||
// "vert 0 ( 0.394531 0.513672 ) 0 1"
|
||||
else if (TokenMatch(sz, "vert", 4)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
const unsigned int idx = ::strtoul10(sz, &sz);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
if (idx >= desc.mVertices.size())
|
||||
desc.mVertices.resize(idx + 1);
|
||||
|
||||
VertexDesc &vert = desc.mVertices[idx];
|
||||
if ('(' != *sz++)
|
||||
MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
sz = fast_atoreal_move<float>(sz, (float &)vert.mUV.x);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
sz = fast_atoreal_move<float>(sz, (float &)vert.mUV.y);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
if (')' != *sz++)
|
||||
MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
vert.mFirstWeight = ::strtoul10(sz, &sz);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
vert.mNumWeights = ::strtoul10(sz, &sz);
|
||||
}
|
||||
// tri attribute
|
||||
// "tri 0 15 13 12"
|
||||
else if (TokenMatch(sz, "tri", 3)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
const unsigned int idx = strtoul10(sz, &sz);
|
||||
if (idx >= desc.mFaces.size())
|
||||
desc.mFaces.resize(idx + 1);
|
||||
|
@ -359,24 +385,24 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
|
|||
aiFace &face = desc.mFaces[idx];
|
||||
face.mIndices = new unsigned int[face.mNumIndices = 3];
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
face.mIndices[i] = strtoul10(sz, &sz);
|
||||
}
|
||||
}
|
||||
// weight attribute
|
||||
// "weight 362 5 0.500000 ( -3.553583 11.893474 9.719339 )"
|
||||
else if (TokenMatch(sz, "weight", 6)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
const unsigned int idx = strtoul10(sz, &sz);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
if (idx >= desc.mWeights.size())
|
||||
desc.mWeights.resize(idx + 1);
|
||||
|
||||
WeightDesc &weight = desc.mWeights[idx];
|
||||
weight.mBone = strtoul10(sz, &sz);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
sz = fast_atoreal_move<float>(sz, weight.mWeight);
|
||||
AI_MD5_READ_TRIPLE(weight.vOffsetPosition);
|
||||
AI_MD5_READ_TRIPLE(weight.vOffsetPosition, &sz, elem.end, elem.iLineNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -386,12 +412,12 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// .MD5ANIM parsing function
|
||||
MD5AnimParser::MD5AnimParser(SectionList &mSections) {
|
||||
MD5AnimParser::MD5AnimParser(SectionArray &mSections) {
|
||||
ASSIMP_LOG_DEBUG("MD5AnimParser begin");
|
||||
|
||||
fFrameRate = 24.0f;
|
||||
mNumAnimatedComponents = UINT_MAX;
|
||||
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
|
||||
for (SectionArray::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
|
||||
if ((*iter).mName == "hierarchy") {
|
||||
// "sheath" 0 63 6
|
||||
for (const auto &elem : (*iter).mElements) {
|
||||
|
@ -399,18 +425,18 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
|
|||
AnimBoneDesc &desc = mAnimatedBones.back();
|
||||
|
||||
const char *sz = elem.szStart;
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(&sz, elem.end, desc.mName);
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
|
||||
// parent index - negative values are allowed (at least -1)
|
||||
desc.mParentIndex = ::strtol10(sz, &sz);
|
||||
|
||||
// flags (highest is 2^6-1)
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
if (63 < (desc.iFlags = ::strtoul10(sz, &sz))) {
|
||||
MD5Parser::ReportWarning("Invalid flag combination in hierarchy section", elem.iLineNumber);
|
||||
}
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_SKIP_SPACES(& sz, elem.end, elem.iLineNumber);
|
||||
|
||||
// index of the first animation keyframe component for this joint
|
||||
desc.iFirstKeyIndex = ::strtoul10(sz, &sz);
|
||||
|
@ -423,8 +449,8 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
|
|||
mBaseFrames.emplace_back();
|
||||
BaseFrameDesc &desc = mBaseFrames.back();
|
||||
|
||||
AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
|
||||
AI_MD5_READ_TRIPLE(desc.vRotationQuat);
|
||||
AI_MD5_READ_TRIPLE(desc.vPositionXYZ, &sz, elem.end, elem.iLineNumber);
|
||||
AI_MD5_READ_TRIPLE(desc.vRotationQuat, &sz, elem.end, elem.iLineNumber);
|
||||
}
|
||||
} else if ((*iter).mName == "frame") {
|
||||
if (!(*iter).mGlobalValue.length()) {
|
||||
|
@ -444,7 +470,7 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
|
|||
// now read all elements (continuous list of floats)
|
||||
for (const auto &elem : (*iter).mElements) {
|
||||
const char *sz = elem.szStart;
|
||||
while (SkipSpacesAndLineEnd(&sz)) {
|
||||
while (SkipSpacesAndLineEnd(&sz, elem.end)) {
|
||||
float f;
|
||||
sz = fast_atoreal_move<float>(sz, f);
|
||||
desc.mValues.push_back(f);
|
||||
|
@ -471,11 +497,11 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// .MD5CAMERA parsing function
|
||||
MD5CameraParser::MD5CameraParser(SectionList &mSections) {
|
||||
MD5CameraParser::MD5CameraParser(SectionArray &mSections) {
|
||||
ASSIMP_LOG_DEBUG("MD5CameraParser begin");
|
||||
fFrameRate = 24.0f;
|
||||
|
||||
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
|
||||
for (SectionArray::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
|
||||
if ((*iter).mName == "numFrames") {
|
||||
frames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
|
||||
} else if ((*iter).mName == "frameRate") {
|
||||
|
@ -492,9 +518,9 @@ MD5CameraParser::MD5CameraParser(SectionList &mSections) {
|
|||
|
||||
frames.emplace_back();
|
||||
CameraAnimFrameDesc &cur = frames.back();
|
||||
AI_MD5_READ_TRIPLE(cur.vPositionXYZ);
|
||||
AI_MD5_READ_TRIPLE(cur.vRotationQuat);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_READ_TRIPLE(cur.vPositionXYZ, &sz, elem.end, elem.iLineNumber);
|
||||
AI_MD5_READ_TRIPLE(cur.vRotationQuat, &sz, elem.end, elem.iLineNumber);
|
||||
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
|
||||
cur.fFOV = fast_atof(sz);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2023, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -68,12 +68,14 @@ struct Element {
|
|||
//! Elements are terminated with \0
|
||||
char* szStart;
|
||||
|
||||
const char *end;
|
||||
|
||||
//! Original line number (can be used in error messages
|
||||
//! if a parsing error occurs)
|
||||
unsigned int iLineNumber;
|
||||
};
|
||||
|
||||
using ElementList = std::vector<Element>;
|
||||
using ElementArray = std::vector<Element>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Represents a section of a MD5 file (such as the mesh or the joints section)
|
||||
|
@ -86,7 +88,7 @@ struct Section {
|
|||
unsigned int iLineNumber;
|
||||
|
||||
//! List of all elements which have been parsed in this section.
|
||||
ElementList mElements;
|
||||
ElementArray mElements;
|
||||
|
||||
//! Name of the section
|
||||
std::string mName;
|
||||
|
@ -96,7 +98,7 @@ struct Section {
|
|||
std::string mGlobalValue;
|
||||
};
|
||||
|
||||
using SectionList = std::vector<Section>;
|
||||
using SectionArray = std::vector<Section>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Basic information about a joint
|
||||
|
@ -132,7 +134,7 @@ struct BoneDesc : BaseJointDescription {
|
|||
unsigned int mMap;
|
||||
};
|
||||
|
||||
using BoneList = std::vector<BoneDesc>;
|
||||
using BoneArray = std::vector<BoneDesc>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Represents a bone (joint) descriptor in a MD5Anim file
|
||||
|
@ -145,7 +147,7 @@ struct AnimBoneDesc : BaseJointDescription {
|
|||
unsigned int iFirstKeyIndex;
|
||||
};
|
||||
|
||||
using AnimBoneList = std::vector< AnimBoneDesc >;
|
||||
using AnimBoneArray = std::vector< AnimBoneDesc >;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Represents a base frame descriptor in a MD5Anim file
|
||||
|
@ -155,7 +157,7 @@ struct BaseFrameDesc {
|
|||
aiVector3D vRotationQuat;
|
||||
};
|
||||
|
||||
using BaseFrameList = std::vector<BaseFrameDesc>;
|
||||
using BaseFrameArray = std::vector<BaseFrameDesc>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Represents a camera animation frame in a MDCamera file
|
||||
|
@ -164,7 +166,7 @@ struct CameraAnimFrameDesc : BaseFrameDesc {
|
|||
float fFOV;
|
||||
};
|
||||
|
||||
using CameraFrameList = std::vector<CameraAnimFrameDesc>;
|
||||
using CameraFrameArray = std::vector<CameraAnimFrameDesc>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Represents a frame descriptor in a MD5Anim file
|
||||
|
@ -177,7 +179,7 @@ struct FrameDesc {
|
|||
std::vector< float > mValues;
|
||||
};
|
||||
|
||||
using FrameList = std::vector<FrameDesc>;
|
||||
using FrameArray = std::vector<FrameDesc>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Represents a vertex descriptor in a MD5 file
|
||||
|
@ -199,7 +201,7 @@ struct VertexDesc {
|
|||
unsigned int mNumWeights;
|
||||
};
|
||||
|
||||
using VertexList = std::vector<VertexDesc>;
|
||||
using VertexArray = std::vector<VertexDesc>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Represents a vertex weight descriptor in a MD5 file
|
||||
|
@ -216,27 +218,27 @@ struct WeightDesc {
|
|||
aiVector3D vOffsetPosition;
|
||||
};
|
||||
|
||||
using WeightList = std::vector<WeightDesc>;
|
||||
using FaceList = std::vector<aiFace>;
|
||||
using WeightArray = std::vector<WeightDesc>;
|
||||
using FaceArray = std::vector<aiFace>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Represents a mesh in a MD5 file
|
||||
*/
|
||||
struct MeshDesc {
|
||||
//! Weights of the mesh
|
||||
WeightList mWeights;
|
||||
WeightArray mWeights;
|
||||
|
||||
//! Vertices of the mesh
|
||||
VertexList mVertices;
|
||||
VertexArray mVertices;
|
||||
|
||||
//! Faces of the mesh
|
||||
FaceList mFaces;
|
||||
FaceArray mFaces;
|
||||
|
||||
//! Name of the shader (=texture) to be assigned to the mesh
|
||||
aiString mShader;
|
||||
};
|
||||
|
||||
using MeshList = std::vector<MeshDesc>;
|
||||
using MeshArray = std::vector<MeshDesc>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Convert a quaternion to its usual representation
|
||||
|
@ -269,13 +271,13 @@ public:
|
|||
*
|
||||
* @param mSections List of file sections (output of MD5Parser)
|
||||
*/
|
||||
explicit MD5MeshParser(SectionList& mSections);
|
||||
explicit MD5MeshParser(SectionArray& mSections);
|
||||
|
||||
//! List of all meshes
|
||||
MeshList mMeshes;
|
||||
MeshArray mMeshes;
|
||||
|
||||
//! List of all joints
|
||||
BoneList mJoints;
|
||||
BoneArray mJoints;
|
||||
};
|
||||
|
||||
// remove this flag if you need to the bounding box data
|
||||
|
@ -292,20 +294,20 @@ public:
|
|||
*
|
||||
* @param mSections List of file sections (output of MD5Parser)
|
||||
*/
|
||||
explicit MD5AnimParser(SectionList& mSections);
|
||||
explicit MD5AnimParser(SectionArray& mSections);
|
||||
|
||||
|
||||
//! Output frame rate
|
||||
float fFrameRate;
|
||||
|
||||
//! List of animation bones
|
||||
AnimBoneList mAnimatedBones;
|
||||
AnimBoneArray mAnimatedBones;
|
||||
|
||||
//! List of base frames
|
||||
BaseFrameList mBaseFrames;
|
||||
BaseFrameArray mBaseFrames;
|
||||
|
||||
//! List of animation frames
|
||||
FrameList mFrames;
|
||||
FrameArray mFrames;
|
||||
|
||||
//! Number of animated components
|
||||
unsigned int mNumAnimatedComponents;
|
||||
|
@ -322,7 +324,7 @@ public:
|
|||
*
|
||||
* @param mSections List of file sections (output of MD5Parser)
|
||||
*/
|
||||
explicit MD5CameraParser(SectionList& mSections);
|
||||
explicit MD5CameraParser(SectionArray& mSections);
|
||||
|
||||
//! Output frame rate
|
||||
float fFrameRate;
|
||||
|
@ -331,7 +333,7 @@ public:
|
|||
std::vector<unsigned int> cuts;
|
||||
|
||||
//! Frames
|
||||
CameraFrameList frames;
|
||||
CameraFrameArray frames;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -375,7 +377,7 @@ public:
|
|||
void ReportWarning (const char* warn);
|
||||
|
||||
//! List of all sections which have been read
|
||||
SectionList mSections;
|
||||
SectionArray mSections;
|
||||
|
||||
private:
|
||||
bool ParseSection(Section& out);
|
||||
|
@ -388,7 +390,7 @@ private:
|
|||
|
||||
private:
|
||||
char* buffer;
|
||||
char* bufferEnd;
|
||||
const char* bufferEnd;
|
||||
unsigned int fileSize;
|
||||
unsigned int lineNumber;
|
||||
};
|
||||
|
@ -406,7 +408,7 @@ inline void MD5Parser::ReportError(const char* error) {
|
|||
// -------------------------------------------------------------------
|
||||
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
|
||||
++lineNumber;
|
||||
return Assimp::SkipLine(in ,out);
|
||||
return Assimp::SkipLine(in, out, bufferEnd);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -450,7 +452,7 @@ inline bool MD5Parser::SkipSpacesAndLineEnd() {
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
inline bool MD5Parser::SkipSpaces() {
|
||||
return Assimp::SkipSpaces((const char**)&buffer);
|
||||
return Assimp::SkipSpaces((const char**)&buffer, bufferEnd);
|
||||
}
|
||||
|
||||
} // namespace Assimp
|
||||
|
|
|
@ -123,9 +123,8 @@ aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture *pcTexture) {
|
|||
// Read a texture from a MDL3 file
|
||||
void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char *szData) {
|
||||
const MDL::Header *pcHeader = (const MDL::Header *)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function
|
||||
|
||||
VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth *
|
||||
pcHeader->skinheight);
|
||||
const size_t len = pcHeader->skinwidth * pcHeader->skinheight;
|
||||
VALIDATE_FILE_SIZE(szData + len);
|
||||
|
||||
// allocate a new texture object
|
||||
aiTexture *pcNew = new aiTexture();
|
||||
|
|
|
@ -85,7 +85,7 @@ const aiImporterDesc *NFFImporter::GetInfo() const {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#define AI_NFF_PARSE_FLOAT(f) \
|
||||
SkipSpaces(&sz); \
|
||||
SkipSpaces(&sz, lineEnd); \
|
||||
if (!IsLineEnd(*sz)) sz = fast_atoreal_move<ai_real>(sz, (ai_real &)f);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -111,7 +111,7 @@ const aiImporterDesc *NFFImporter::GetInfo() const {
|
|||
ASSIMP_LOG_WARN("NFF2: Unexpected EOF, can't read next token"); \
|
||||
break; \
|
||||
} \
|
||||
SkipSpaces(line, &sz); \
|
||||
SkipSpaces(line, &sz, lineEnd); \
|
||||
} while (IsLineEnd(*sz))
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -148,9 +148,9 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo> &output,
|
|||
|
||||
// No read the file line per line
|
||||
char line[4096];
|
||||
const char *sz;
|
||||
const char *sz, *lineEnd = &line[2095]+1;
|
||||
while (GetNextLine(buffer, line)) {
|
||||
SkipSpaces(line, &sz);
|
||||
SkipSpaces(line, &sz, lineEnd);
|
||||
|
||||
// 'version' defines the version of the file format
|
||||
if (TokenMatch(sz, "version", 7)) {
|
||||
|
@ -198,18 +198,16 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo> &output,
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Imports the given file into the given scene structure.
|
||||
void NFFImporter::InternReadFile(const std::string &pFile,
|
||||
aiScene *pScene, IOSystem *pIOHandler) {
|
||||
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
|
||||
|
||||
// Check whether we can read from the file
|
||||
if (!file)
|
||||
throw DeadlyImportError("Failed to open NFF file ", pFile, ".");
|
||||
void NFFImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSystem *pIOHandler) {
|
||||
std::unique_ptr<IOStream> stream(pIOHandler->Open(file, "rb"));
|
||||
if (!stream) {
|
||||
throw DeadlyImportError("Failed to open NFF file ", file, ".");
|
||||
}
|
||||
|
||||
// allocate storage and copy the contents of the file to a memory buffer
|
||||
// (terminate it with zero)
|
||||
std::vector<char> mBuffer2;
|
||||
TextFileToBuffer(file.get(), mBuffer2);
|
||||
TextFileToBuffer(stream.get(), mBuffer2);
|
||||
const char *buffer = &mBuffer2[0];
|
||||
|
||||
// mesh arrays - separate here to make the handling of the pointers below easier.
|
||||
|
@ -219,8 +217,10 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
std::vector<MeshInfo> meshesLocked;
|
||||
|
||||
char line[4096];
|
||||
const char *lineEnd = &line[4096];
|
||||
const char *sz;
|
||||
|
||||
|
||||
// camera parameters
|
||||
aiVector3D camPos, camUp(0.f, 1.f, 0.f), camLookAt(0.f, 0.f, 1.f);
|
||||
ai_real angle = 45.f;
|
||||
|
@ -265,7 +265,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
CommentRemover::RemoveLineComments("//", &mBuffer2[0]);
|
||||
|
||||
while (GetNextLine(buffer, line)) {
|
||||
SkipSpaces(line, &sz);
|
||||
SkipSpaces(line, &sz, lineEnd);
|
||||
if (TokenMatch(sz, "version", 7)) {
|
||||
ASSIMP_LOG_INFO("NFF (Sense8) file format: ", sz);
|
||||
} else if (TokenMatch(sz, "viewpos", 7)) {
|
||||
|
@ -295,7 +295,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
|
||||
// material table - an external file
|
||||
if (TokenMatch(sz, "mtable", 6)) {
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
sz3 = sz;
|
||||
while (!IsSpaceOrNewLine(*sz))
|
||||
++sz;
|
||||
|
@ -316,12 +316,12 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
std::string::size_type sepPos;
|
||||
if ((std::string::npos == (sepPos = path.find_last_of('\\')) || !sepPos) &&
|
||||
(std::string::npos == (sepPos = path.find_last_of('/')) || !sepPos)) {
|
||||
sepPos = pFile.find_last_of('\\');
|
||||
sepPos = file.find_last_of('\\');
|
||||
if (std::string::npos == sepPos) {
|
||||
sepPos = pFile.find_last_of('/');
|
||||
sepPos = file.find_last_of('/');
|
||||
}
|
||||
if (std::string::npos != sepPos) {
|
||||
path = pFile.substr(0, sepPos + 1) + path;
|
||||
path = file.substr(0, sepPos + 1) + path;
|
||||
}
|
||||
}
|
||||
LoadNFF2MaterialTable(materialTable, path, pIOHandler);
|
||||
|
@ -351,7 +351,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
|
||||
// parse all other attributes in the line
|
||||
while (true) {
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
if (IsLineEnd(*sz)) break;
|
||||
|
||||
// color definition
|
||||
|
@ -403,23 +403,20 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
tempIdx.reserve(10);
|
||||
for (unsigned int i = 0; i < num; ++i) {
|
||||
AI_NFF2_GET_NEXT_TOKEN();
|
||||
SkipSpaces(line, &sz);
|
||||
SkipSpaces(line, &sz, lineEnd);
|
||||
unsigned int numIdx = strtoul10(sz, &sz);
|
||||
|
||||
// read all faces indices
|
||||
if (numIdx) {
|
||||
// mesh.faces.push_back(numIdx);
|
||||
// tempIdx.erase(tempIdx.begin(),tempIdx.end());
|
||||
tempIdx.resize(numIdx);
|
||||
|
||||
for (unsigned int a = 0; a < numIdx; ++a) {
|
||||
SkipSpaces(sz, &sz);
|
||||
SkipSpaces(sz, &sz, lineEnd);
|
||||
unsigned int m = strtoul10(sz, &sz);
|
||||
if (m >= (unsigned int)tempPositions.size()) {
|
||||
ASSIMP_LOG_ERROR("NFF2: Vertex index overflow");
|
||||
m = 0;
|
||||
}
|
||||
// mesh.vertices.push_back (tempPositions[idx]);
|
||||
tempIdx[a] = m;
|
||||
}
|
||||
}
|
||||
|
@ -432,7 +429,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
shader.color = aiColor3D(1.f, 1.f, 1.f);
|
||||
aiColor4D c = aiColor4D(1.f, 1.f, 1.f, 1.f);
|
||||
while (true) {
|
||||
SkipSpaces(sz, &sz);
|
||||
SkipSpaces(sz, &sz, lineEnd);
|
||||
if (IsLineEnd(*sz)) break;
|
||||
|
||||
// per-polygon colors
|
||||
|
@ -510,7 +507,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
|
||||
// Material ID?
|
||||
else if (!materialTable.empty() && TokenMatch(sz, "matid", 5)) {
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
matIdx = strtoul10(sz, &sz);
|
||||
if (matIdx >= materialTable.size()) {
|
||||
ASSIMP_LOG_ERROR("NFF2: Material index overflow.");
|
||||
|
@ -527,7 +524,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
shader.specular = mat.specular;
|
||||
shader.shininess = mat.shininess;
|
||||
} else
|
||||
SkipToken(sz);
|
||||
SkipToken(sz, lineEnd);
|
||||
}
|
||||
|
||||
// search the list of all shaders we have for this object whether
|
||||
|
@ -649,7 +646,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
sz = &line[1];
|
||||
out = currentMesh;
|
||||
}
|
||||
SkipSpaces(sz, &sz);
|
||||
SkipSpaces(sz, &sz, lineEnd);
|
||||
unsigned int m = strtoul10(sz);
|
||||
|
||||
// ---- flip the face order
|
||||
|
@ -677,13 +674,13 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
}
|
||||
if (out == currentMeshWithUVCoords) {
|
||||
// FIX: in one test file this wraps over multiple lines
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
if (IsLineEnd(*sz)) {
|
||||
GetNextLine(buffer, line);
|
||||
sz = line;
|
||||
}
|
||||
AI_NFF_PARSE_FLOAT(v.x);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
if (IsLineEnd(*sz)) {
|
||||
GetNextLine(buffer, line);
|
||||
sz = line;
|
||||
|
@ -717,7 +714,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
// if the next one is NOT a number we assume it is a texture file name
|
||||
// this feature is used by some NFF files on the internet and it has
|
||||
// been implemented as it can be really useful
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
if (!IsNumeric(*sz)) {
|
||||
// TODO: Support full file names with spaces and quotation marks ...
|
||||
const char *p = sz;
|
||||
|
@ -731,10 +728,8 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
} else {
|
||||
AI_NFF_PARSE_FLOAT(s.ambient); // optional
|
||||
}
|
||||
}
|
||||
// 'shader' - other way to specify a texture
|
||||
else if (TokenMatch(sz, "shader", 6)) {
|
||||
SkipSpaces(&sz);
|
||||
} else if (TokenMatch(sz, "shader", 6)) { // 'shader' - other way to specify a texture
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
const char *old = sz;
|
||||
while (!IsSpaceOrNewLine(*sz))
|
||||
++sz;
|
||||
|
@ -889,7 +884,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
}
|
||||
// 'tess' - tessellation
|
||||
else if (TokenMatch(sz, "tess", 4)) {
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
iTesselation = strtoul10(sz);
|
||||
}
|
||||
// 'from' - camera position
|
||||
|
@ -929,7 +924,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
|||
// '' - comment
|
||||
else if ('#' == line[0]) {
|
||||
const char *space;
|
||||
SkipSpaces(&line[1], &space);
|
||||
SkipSpaces(&line[1], &space, lineEnd);
|
||||
if (!IsLineEnd(*space)) {
|
||||
ASSIMP_LOG_INFO(space);
|
||||
}
|
||||
|
|
|
@ -84,10 +84,10 @@ const aiImporterDesc *OFFImporter::GetInfo() const {
|
|||
|
||||
// skip blank space, lines and comments
|
||||
static void NextToken(const char **car, const char *end) {
|
||||
SkipSpacesAndLineEnd(car);
|
||||
SkipSpacesAndLineEnd(car, end);
|
||||
while (*car < end && (**car == '#' || **car == '\n' || **car == '\r')) {
|
||||
SkipLine(car);
|
||||
SkipSpacesAndLineEnd(car);
|
||||
SkipLine(car, end);
|
||||
SkipSpacesAndLineEnd(car, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,6 +195,7 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
char line[4096];
|
||||
buffer = car;
|
||||
const char *sz = car;
|
||||
const char *lineEnd = &line[4096];
|
||||
|
||||
// now read all vertex lines
|
||||
for (unsigned int i = 0; i < numVertices; ++i) {
|
||||
|
@ -210,13 +211,13 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
|
||||
// stop at dimensions: this allows loading 1D or 2D coordinate vertices
|
||||
for (unsigned int dim = 0; dim < dimensions; ++dim) {
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, *vec[dim]);
|
||||
}
|
||||
|
||||
// if has homogeneous coordinate, divide others by this one
|
||||
if (hasHomogenous) {
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
ai_real w = 1.;
|
||||
sz = fast_atoreal_move<ai_real>(sz, w);
|
||||
for (unsigned int dim = 0; dim < dimensions; ++dim) {
|
||||
|
@ -227,11 +228,11 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
// read optional normals
|
||||
if (hasNormals) {
|
||||
aiVector3D &n = mesh->mNormals[i];
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)n.x);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)n.y);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
fast_atoreal_move<ai_real>(sz, (ai_real &)n.z);
|
||||
}
|
||||
|
||||
|
@ -241,22 +242,22 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
// in theory should be testing type !
|
||||
if (hasColors) {
|
||||
aiColor4D &c = mesh->mColors[0][i];
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.r);
|
||||
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.g);
|
||||
} else {
|
||||
c.g = 0.;
|
||||
}
|
||||
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.b);
|
||||
} else {
|
||||
c.b = 0.;
|
||||
}
|
||||
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.a);
|
||||
} else {
|
||||
c.a = 1.;
|
||||
|
@ -264,9 +265,9 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
}
|
||||
if (hasTexCoord) {
|
||||
aiVector3D &t = mesh->mTextureCoords[0][i];
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)t.x);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
fast_atoreal_move<ai_real>(sz, (ai_real &)t.y);
|
||||
}
|
||||
}
|
||||
|
@ -280,7 +281,7 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
}
|
||||
unsigned int idx;
|
||||
sz = line;
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
idx = strtoul10(sz, &sz);
|
||||
if (!idx || idx > 9) {
|
||||
ASSIMP_LOG_ERROR("OFF: Faces with zero indices aren't allowed");
|
||||
|
@ -291,7 +292,7 @@ void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
faces->mNumIndices = idx;
|
||||
faces->mIndices = new unsigned int[faces->mNumIndices];
|
||||
for (unsigned int m = 0; m < faces->mNumIndices; ++m) {
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, lineEnd);
|
||||
idx = strtoul10(sz, &sz);
|
||||
if (idx >= numVertices) {
|
||||
ASSIMP_LOG_ERROR("OFF: Vertex index is out of range");
|
||||
|
|
|
@ -64,6 +64,7 @@ ObjFileParser::ObjFileParser() :
|
|||
m_pModel(nullptr),
|
||||
m_uiLine(0),
|
||||
m_buffer(),
|
||||
mEnd(&m_buffer[Buffersize]),
|
||||
m_pIO(nullptr),
|
||||
m_progress(nullptr),
|
||||
m_originalObjFileName() {
|
||||
|
@ -97,8 +98,6 @@ ObjFileParser::ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::stri
|
|||
parseFile(streamBuffer);
|
||||
}
|
||||
|
||||
ObjFileParser::~ObjFileParser() = default;
|
||||
|
||||
void ObjFileParser::setBuffer(std::vector<char> &buffer) {
|
||||
m_DataIt = buffer.begin();
|
||||
m_DataItEnd = buffer.end();
|
||||
|
@ -121,6 +120,7 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
|
|||
while (streamBuffer.getNextDataLine(buffer, '\\')) {
|
||||
m_DataIt = buffer.begin();
|
||||
m_DataItEnd = buffer.end();
|
||||
mEnd = &buffer[buffer.size() - 1] + 1;
|
||||
|
||||
// Handle progress reporting
|
||||
const size_t filePos(streamBuffer.getFilePos());
|
||||
|
@ -130,7 +130,7 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
|
|||
m_progress->UpdateFileRead(processed, progressTotal);
|
||||
}
|
||||
|
||||
// handle cstype section end (http://paulbourke.net/dataformats/obj/)
|
||||
// handle c-stype section end (http://paulbourke.net/dataformats/obj/)
|
||||
if (insideCstype) {
|
||||
switch (*m_DataIt) {
|
||||
case 'e': {
|
||||
|
@ -301,18 +301,19 @@ size_t ObjFileParser::getNumComponentsInDataDefinition() {
|
|||
} else if (IsLineEnd(*tmp)) {
|
||||
end_of_definition = true;
|
||||
}
|
||||
if (!SkipSpaces(&tmp)) {
|
||||
if (!SkipSpaces(&tmp, mEnd)) {
|
||||
break;
|
||||
}
|
||||
const bool isNum(IsNumeric(*tmp) || isNanOrInf(tmp));
|
||||
SkipToken(tmp);
|
||||
SkipToken(tmp, mEnd);
|
||||
if (isNum) {
|
||||
++numComponents;
|
||||
}
|
||||
if (!SkipSpaces(&tmp)) {
|
||||
if (!SkipSpaces(&tmp, mEnd)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return numComponents;
|
||||
}
|
||||
|
||||
|
@ -487,8 +488,9 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
|||
++iStep;
|
||||
}
|
||||
|
||||
if (iPos == 1 && !vt && vn)
|
||||
if (iPos == 1 && !vt && vn) {
|
||||
iPos = 2; // skip texture coords for normals if there are no tex coords
|
||||
}
|
||||
|
||||
if (iVal > 0) {
|
||||
// Store parsed index
|
||||
|
@ -577,8 +579,9 @@ void ObjFileParser::getMaterialDesc() {
|
|||
// Get name
|
||||
std::string strName(pStart, &(*m_DataIt));
|
||||
strName = trim_whitespaces(strName);
|
||||
if (strName.empty())
|
||||
if (strName.empty()) {
|
||||
skip = true;
|
||||
}
|
||||
|
||||
// If the current mesh has the same material, we simply ignore that 'usemtl' command
|
||||
// There is no need to create another object or even mesh here
|
||||
|
|
|
@ -41,6 +41,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef OBJ_FILEPARSER_H_INC
|
||||
#define OBJ_FILEPARSER_H_INC
|
||||
|
||||
#include "ObjFileData.h"
|
||||
|
||||
#include <assimp/IOStreamBuffer.h>
|
||||
#include <assimp/material.h>
|
||||
#include <assimp/mesh.h>
|
||||
|
@ -53,14 +55,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace Assimp {
|
||||
|
||||
namespace ObjFile {
|
||||
struct Model;
|
||||
struct Object;
|
||||
struct Material;
|
||||
struct Point3;
|
||||
struct Point2;
|
||||
} // namespace ObjFile
|
||||
|
||||
class ObjFileImporter;
|
||||
class IOSystem;
|
||||
class ProgressHandler;
|
||||
|
@ -79,7 +73,7 @@ public:
|
|||
/// @brief Constructor with data array.
|
||||
ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::string &modelName, IOSystem *io, ProgressHandler *progress, const std::string &originalObjFileName);
|
||||
/// @brief Destructor
|
||||
~ObjFileParser();
|
||||
~ObjFileParser() = default;
|
||||
/// @brief If you want to load in-core data.
|
||||
void setBuffer(std::vector<char> &buffer);
|
||||
/// @brief Model getter.
|
||||
|
@ -149,6 +143,7 @@ private:
|
|||
unsigned int m_uiLine;
|
||||
//! Helper buffer
|
||||
char m_buffer[Buffersize];
|
||||
const char *mEnd;
|
||||
/// Pointer to IO system instance.
|
||||
IOSystem *m_pIO;
|
||||
//! Pointer to progress handler
|
||||
|
|
|
@ -159,7 +159,8 @@ void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
mBuffer = (unsigned char *)&mBuffer2[0];
|
||||
|
||||
char *szMe = (char *)&this->mBuffer[0];
|
||||
SkipSpacesAndLineEnd(szMe, (const char **)&szMe);
|
||||
const char *end = &mBuffer2[0] + mBuffer2.size();
|
||||
SkipSpacesAndLineEnd(szMe, (const char **)&szMe, end);
|
||||
|
||||
// determine the format of the file data and construct the aiMesh
|
||||
PLY::DOM sPlyDom;
|
||||
|
@ -167,7 +168,7 @@ void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
|
||||
if (TokenMatch(szMe, "format", 6)) {
|
||||
if (TokenMatch(szMe, "ascii", 5)) {
|
||||
SkipLine(szMe, (const char **)&szMe);
|
||||
SkipLine(szMe, (const char **)&szMe, end);
|
||||
if (!PLY::DOM::ParseInstance(streamedBuffer, &sPlyDom, this)) {
|
||||
if (mGeneratedMesh != nullptr) {
|
||||
delete (mGeneratedMesh);
|
||||
|
|
|
@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <utility>
|
||||
|
||||
using namespace Assimp;
|
||||
namespace Assimp {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
PLY::EDataType PLY::Property::ParseDataType(std::vector<char> &buffer) {
|
||||
|
@ -296,7 +296,7 @@ bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<
|
|||
return true;
|
||||
}
|
||||
|
||||
//parse the number of occurrences of this element
|
||||
// parse the number of occurrences of this element
|
||||
const char *pCur = (char *)&buffer[0];
|
||||
pOut->NumOccur = strtoul10(pCur, &pCur);
|
||||
|
||||
|
@ -321,13 +321,13 @@ bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<
|
|||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool PLY::DOM::SkipSpaces(std::vector<char> &buffer) {
|
||||
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
|
||||
const char *end = pCur + buffer.size();
|
||||
bool ret = false;
|
||||
if (pCur) {
|
||||
const char *szCur = pCur;
|
||||
ret = Assimp::SkipSpaces(pCur, &pCur);
|
||||
ret = Assimp::SkipSpaces(pCur, &pCur, end);
|
||||
|
||||
uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
|
||||
buffer.erase(buffer.begin(), buffer.begin() + iDiff);
|
||||
|
@ -339,10 +339,11 @@ bool PLY::DOM::SkipSpaces(std::vector<char> &buffer) {
|
|||
|
||||
bool PLY::DOM::SkipLine(std::vector<char> &buffer) {
|
||||
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
|
||||
const char *end = pCur + buffer.size();
|
||||
bool ret = false;
|
||||
if (pCur) {
|
||||
const char *szCur = pCur;
|
||||
ret = Assimp::SkipLine(pCur, &pCur);
|
||||
ret = Assimp::SkipLine(pCur, &pCur, end);
|
||||
|
||||
uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
|
||||
buffer.erase(buffer.begin(), buffer.begin() + iDiff);
|
||||
|
@ -369,10 +370,11 @@ bool PLY::DOM::TokenMatch(std::vector<char> &buffer, const char *token, unsigned
|
|||
|
||||
bool PLY::DOM::SkipSpacesAndLineEnd(std::vector<char> &buffer) {
|
||||
const char *pCur = buffer.empty() ? nullptr : (char *)&buffer[0];
|
||||
const char *end = pCur + buffer.size();
|
||||
bool ret = false;
|
||||
if (pCur) {
|
||||
const char *szCur = pCur;
|
||||
ret = Assimp::SkipSpacesAndLineEnd(pCur, &pCur);
|
||||
ret = Assimp::SkipSpacesAndLineEnd(pCur, &pCur, end);
|
||||
|
||||
uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
|
||||
buffer.erase(buffer.begin(), buffer.begin() + iDiff);
|
||||
|
@ -426,7 +428,7 @@ bool PLY::DOM::ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char>
|
|||
} else {
|
||||
// ignore unknown header elements
|
||||
if (!streamBuffer.getNextLine(buffer))
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -446,7 +448,7 @@ bool PLY::DOM::ParseElementInstanceLists(IOStreamBuffer<char> &streamBuffer, std
|
|||
std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin();
|
||||
|
||||
// parse all element instances
|
||||
//construct vertices and faces
|
||||
// construct vertices and faces
|
||||
for (; i != alElements.end(); ++i, ++a) {
|
||||
if ((*i).eSemantic == EEST_Vertex || (*i).eSemantic == EEST_Face || (*i).eSemantic == EEST_TriStrip) {
|
||||
PLY::ElementInstanceList::ParseInstanceList(streamBuffer, buffer, &(*i), nullptr, loader);
|
||||
|
@ -528,7 +530,7 @@ bool PLY::DOM::ParseInstance(IOStreamBuffer<char> &streamBuffer, DOM *p_pcOut, P
|
|||
return false;
|
||||
}
|
||||
|
||||
//get next line after header
|
||||
// get next line after header
|
||||
streamBuffer.getNextLine(buffer);
|
||||
if (!p_pcOut->ParseElementInstanceLists(streamBuffer, buffer, loader)) {
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseInstance() failure");
|
||||
|
@ -558,23 +560,24 @@ bool PLY::ElementInstanceList::ParseInstanceList(
|
|||
}
|
||||
} else {
|
||||
const char *pCur = (const char *)&buffer[0];
|
||||
const char *end = pCur + buffer.size();
|
||||
// be sure to have enough storage
|
||||
for (unsigned int i = 0; i < pcElement->NumOccur; ++i) {
|
||||
if (p_pcOut)
|
||||
PLY::ElementInstance::ParseInstance(pCur, pcElement, &p_pcOut->alInstances[i]);
|
||||
PLY::ElementInstance::ParseInstance(pCur, end, pcElement, &p_pcOut->alInstances[i]);
|
||||
else {
|
||||
ElementInstance elt;
|
||||
PLY::ElementInstance::ParseInstance(pCur, pcElement, &elt);
|
||||
PLY::ElementInstance::ParseInstance(pCur, end, pcElement, &elt);
|
||||
|
||||
// Create vertex or face
|
||||
if (pcElement->eSemantic == EEST_Vertex) {
|
||||
//call loader instance from here
|
||||
// call loader instance from here
|
||||
loader->LoadVertex(pcElement, &elt, i);
|
||||
} else if (pcElement->eSemantic == EEST_Face) {
|
||||
//call loader instance from here
|
||||
// call loader instance from here
|
||||
loader->LoadFace(pcElement, &elt, i);
|
||||
} else if (pcElement->eSemantic == EEST_TriStrip) {
|
||||
//call loader instance from here
|
||||
// call loader instance from here
|
||||
loader->LoadFace(pcElement, &elt, i);
|
||||
}
|
||||
}
|
||||
|
@ -611,13 +614,13 @@ bool PLY::ElementInstanceList::ParseInstanceListBinary(
|
|||
|
||||
// Create vertex or face
|
||||
if (pcElement->eSemantic == EEST_Vertex) {
|
||||
//call loader instance from here
|
||||
// call loader instance from here
|
||||
loader->LoadVertex(pcElement, &elt, i);
|
||||
} else if (pcElement->eSemantic == EEST_Face) {
|
||||
//call loader instance from here
|
||||
// call loader instance from here
|
||||
loader->LoadFace(pcElement, &elt, i);
|
||||
} else if (pcElement->eSemantic == EEST_TriStrip) {
|
||||
//call loader instance from here
|
||||
// call loader instance from here
|
||||
loader->LoadFace(pcElement, &elt, i);
|
||||
}
|
||||
}
|
||||
|
@ -626,7 +629,7 @@ bool PLY::ElementInstanceList::ParseInstanceListBinary(
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool PLY::ElementInstance::ParseInstance(const char *&pCur,
|
||||
bool PLY::ElementInstance::ParseInstance(const char *&pCur, const char *end,
|
||||
const PLY::Element *pcElement,
|
||||
PLY::ElementInstance *p_pcOut) {
|
||||
ai_assert(nullptr != pcElement);
|
||||
|
@ -638,7 +641,7 @@ bool PLY::ElementInstance::ParseInstance(const char *&pCur,
|
|||
std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
|
||||
std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
||||
for (; i != p_pcOut->alProperties.end(); ++i, ++a) {
|
||||
if (!(PLY::PropertyInstance::ParseInstance(pCur, &(*a), &(*i)))) {
|
||||
if (!(PLY::PropertyInstance::ParseInstance(pCur, end, &(*a), &(*i)))) {
|
||||
ASSIMP_LOG_WARN("Unable to parse property instance. "
|
||||
"Skipping this element instance");
|
||||
|
||||
|
@ -678,13 +681,13 @@ bool PLY::ElementInstance::ParseInstanceBinary(
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool PLY::PropertyInstance::ParseInstance(const char *&pCur,
|
||||
const PLY::Property *prop, PLY::PropertyInstance *p_pcOut) {
|
||||
bool PLY::PropertyInstance::ParseInstance(const char *&pCur, const char *end, const PLY::Property *prop,
|
||||
PLY::PropertyInstance *p_pcOut) {
|
||||
ai_assert(nullptr != prop);
|
||||
ai_assert(nullptr != p_pcOut);
|
||||
|
||||
// skip spaces at the beginning
|
||||
if (!SkipSpaces(&pCur)) {
|
||||
if (!SkipSpaces(&pCur, end)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -699,7 +702,7 @@ bool PLY::PropertyInstance::ParseInstance(const char *&pCur,
|
|||
// parse all list elements
|
||||
p_pcOut->avList.resize(iNum);
|
||||
for (unsigned int i = 0; i < iNum; ++i) {
|
||||
if (!SkipSpaces(&pCur))
|
||||
if (!SkipSpaces(&pCur, end))
|
||||
return false;
|
||||
|
||||
PLY::PropertyInstance::ParseValue(pCur, prop->eType, &p_pcOut->avList[i]);
|
||||
|
@ -711,7 +714,7 @@ bool PLY::PropertyInstance::ParseInstance(const char *&pCur,
|
|||
PLY::PropertyInstance::ParseValue(pCur, prop->eType, &v);
|
||||
p_pcOut->avList.push_back(v);
|
||||
}
|
||||
SkipSpacesAndLineEnd(&pCur);
|
||||
SkipSpacesAndLineEnd(&pCur, end);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -774,7 +777,7 @@ bool PLY::PropertyInstance::ParseValue(const char *&pCur,
|
|||
ai_assert(nullptr != pCur);
|
||||
ai_assert(nullptr != out);
|
||||
|
||||
//calc element size
|
||||
// calc element size
|
||||
bool ret = true;
|
||||
switch (eType) {
|
||||
case EDT_UInt:
|
||||
|
@ -824,7 +827,7 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
|
|||
bool p_bBE) {
|
||||
ai_assert(nullptr != out);
|
||||
|
||||
//calc element size
|
||||
// calc element size
|
||||
unsigned int lsize = 0;
|
||||
switch (eType) {
|
||||
case EDT_Char:
|
||||
|
@ -852,11 +855,11 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
|
|||
break;
|
||||
}
|
||||
|
||||
//read the next file block if needed
|
||||
// read the next file block if needed
|
||||
if (bufferSize < lsize) {
|
||||
std::vector<char> nbuffer;
|
||||
if (streamBuffer.getNextBlock(nbuffer)) {
|
||||
//concat buffer contents
|
||||
// concat buffer contents
|
||||
buffer = std::vector<char>(buffer.end() - bufferSize, buffer.end());
|
||||
buffer.insert(buffer.end(), nbuffer.begin(), nbuffer.end());
|
||||
nbuffer.clear();
|
||||
|
@ -958,4 +961,6 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
|
|||
return ret;
|
||||
}
|
||||
|
||||
} // namespace Assimp
|
||||
|
||||
#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER
|
||||
|
|
|
@ -324,7 +324,7 @@ public:
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse a property instance
|
||||
static bool ParseInstance(const char* &pCur,
|
||||
static bool ParseInstance(const char* &pCur, const char *end,
|
||||
const Property* prop, PropertyInstance* p_pcOut);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -364,7 +364,7 @@ public:
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
//! Parse an element instance
|
||||
static bool ParseInstance(const char* &pCur,
|
||||
static bool ParseInstance(const char *&pCur, const char *end,
|
||||
const Element* pcElement, ElementInstance* p_pcOut);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
|
|
@ -395,7 +395,10 @@ void Q3BSPFileImporter::createTriangleTopology(const Q3BSP::Q3BSPModel *pModel,
|
|||
m_pCurrentFace->mIndices = new unsigned int[3];
|
||||
m_pCurrentFace->mIndices[idx] = vertIdx;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_pCurrentFace->mIndices[idx] = vertIdx;
|
||||
}
|
||||
|
||||
|
||||
pMesh->mVertices[vertIdx].Set(pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z);
|
||||
pMesh->mNormals[vertIdx].Set(pVertex->vNormal.x, pVertex->vNormal.y, pVertex->vNormal.z);
|
||||
|
|
|
@ -104,11 +104,12 @@ void RAWImporter::InternReadFile(const std::string &pFile,
|
|||
|
||||
// now read all lines
|
||||
char line[4096];
|
||||
const char *end = &line[4096];
|
||||
while (GetNextLine(buffer, line)) {
|
||||
// if the line starts with a non-numeric identifier, it marks
|
||||
// the beginning of a new group
|
||||
const char *sz = line;
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, end);
|
||||
if (IsLineEnd(*sz)) continue;
|
||||
if (!IsNumeric(*sz)) {
|
||||
const char *sz2 = sz;
|
||||
|
@ -117,8 +118,8 @@ void RAWImporter::InternReadFile(const std::string &pFile,
|
|||
const unsigned int length = (unsigned int)(sz2 - sz);
|
||||
|
||||
// find an existing group with this name
|
||||
for (std::vector<GroupInformation>::iterator it = outGroups.begin(), end = outGroups.end();
|
||||
it != end; ++it) {
|
||||
for (std::vector<GroupInformation>::iterator it = outGroups.begin(), endIt = outGroups.end();
|
||||
it != endIt; ++it) {
|
||||
if (length == (*it).name.length() && !::strcmp(sz, (*it).name.c_str())) {
|
||||
curGroup = it;
|
||||
sz2 = nullptr;
|
||||
|
@ -134,7 +135,7 @@ void RAWImporter::InternReadFile(const std::string &pFile,
|
|||
float data[12];
|
||||
unsigned int num;
|
||||
for (num = 0; num < 12; ++num) {
|
||||
if (!SkipSpaces(&sz) || !IsNumeric(*sz)) break;
|
||||
if (!SkipSpaces(&sz, end) || !IsNumeric(*sz)) break;
|
||||
sz = fast_atoreal_move<float>(sz, data[num]);
|
||||
}
|
||||
if (num != 12 && num != 9) {
|
||||
|
|
|
@ -82,8 +82,10 @@ static constexpr aiImporterDesc desc = {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
SMDImporter::SMDImporter() :
|
||||
configFrameID(),
|
||||
pScene( nullptr ),
|
||||
configFrameID(),
|
||||
mBuffer(),
|
||||
mEnd(nullptr),
|
||||
pScene(nullptr),
|
||||
iFileSize( 0 ),
|
||||
iSmallestFrame( INT_MAX ),
|
||||
dLengthOfAnim( 0.0 ),
|
||||
|
@ -92,9 +94,6 @@ SMDImporter::SMDImporter() :
|
|||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
SMDImporter::~SMDImporter() = default;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
|
@ -632,13 +631,13 @@ void SMDImporter::ParseFile() {
|
|||
|
||||
// read line per line ...
|
||||
for ( ;; ) {
|
||||
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) {
|
||||
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent, mEnd)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// "version <n> \n", <n> should be 1 for hl and hl2 SMD files
|
||||
if (TokenMatch(szCurrent,"version",7)) {
|
||||
if(!SkipSpaces(szCurrent,&szCurrent)) break;
|
||||
if(!SkipSpaces(szCurrent,&szCurrent, mEnd)) break;
|
||||
if (1 != strtoul10(szCurrent,&szCurrent)) {
|
||||
ASSIMP_LOG_WARN("SMD.version is not 1. This "
|
||||
"file format is not known. Continuing happily ...");
|
||||
|
@ -647,26 +646,26 @@ void SMDImporter::ParseFile() {
|
|||
}
|
||||
// "nodes\n" - Starts the node section
|
||||
if (TokenMatch(szCurrent,"nodes",5)) {
|
||||
ParseNodesSection(szCurrent,&szCurrent);
|
||||
ParseNodesSection(szCurrent, &szCurrent, mEnd);
|
||||
continue;
|
||||
}
|
||||
// "triangles\n" - Starts the triangle section
|
||||
if (TokenMatch(szCurrent,"triangles",9)) {
|
||||
ParseTrianglesSection(szCurrent,&szCurrent);
|
||||
ParseTrianglesSection(szCurrent, &szCurrent, mEnd);
|
||||
continue;
|
||||
}
|
||||
// "vertexanimation\n" - Starts the vertex animation section
|
||||
if (TokenMatch(szCurrent,"vertexanimation",15)) {
|
||||
bHasUVs = false;
|
||||
ParseVASection(szCurrent,&szCurrent);
|
||||
ParseVASection(szCurrent, &szCurrent, mEnd);
|
||||
continue;
|
||||
}
|
||||
// "skeleton\n" - Starts the skeleton section
|
||||
if (TokenMatch(szCurrent,"skeleton",8)) {
|
||||
ParseSkeletonSection(szCurrent,&szCurrent);
|
||||
ParseSkeletonSection(szCurrent, &szCurrent, mEnd);
|
||||
continue;
|
||||
}
|
||||
SkipLine(szCurrent,&szCurrent);
|
||||
SkipLine(szCurrent, &szCurrent, mEnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -683,6 +682,7 @@ void SMDImporter::ReadSmd(const std::string &pFile, IOSystem* pIOHandler) {
|
|||
// Allocate storage and copy the contents of the file to a memory buffer
|
||||
mBuffer.resize(iFileSize + 1);
|
||||
TextFileToBuffer(file.get(), mBuffer);
|
||||
mEnd = &mBuffer[mBuffer.size() - 1] + 1;
|
||||
|
||||
iSmallestFrame = INT_MAX;
|
||||
bHasUVs = true;
|
||||
|
@ -723,26 +723,26 @@ unsigned int SMDImporter::GetTextureIndex(const std::string& filename) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse the nodes section of the file
|
||||
void SMDImporter::ParseNodesSection(const char* szCurrent, const char** szCurrentOut) {
|
||||
void SMDImporter::ParseNodesSection(const char* szCurrent, const char** szCurrentOut, const char *end) {
|
||||
for ( ;; ) {
|
||||
// "end\n" - Ends the nodes section
|
||||
if (0 == ASSIMP_strincmp(szCurrent,"end",3) && IsSpaceOrNewLine(*(szCurrent+3))) {
|
||||
if (0 == ASSIMP_strincmp(szCurrent, "end", 3) && IsSpaceOrNewLine(*(szCurrent+3))) {
|
||||
szCurrent += 4;
|
||||
break;
|
||||
}
|
||||
ParseNodeInfo(szCurrent,&szCurrent);
|
||||
ParseNodeInfo(szCurrent,&szCurrent, end);
|
||||
}
|
||||
SkipSpacesAndLineEnd(szCurrent,&szCurrent);
|
||||
SkipSpacesAndLineEnd(szCurrent, &szCurrent, end);
|
||||
*szCurrentOut = szCurrent;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse the triangles section of the file
|
||||
void SMDImporter::ParseTrianglesSection(const char* szCurrent, const char** szCurrentOut) {
|
||||
void SMDImporter::ParseTrianglesSection(const char *szCurrent, const char **szCurrentOut, const char *end) {
|
||||
// Parse a triangle, parse another triangle, parse the next triangle ...
|
||||
// and so on until we reach a token that looks quite similar to "end"
|
||||
for ( ;; ) {
|
||||
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) {
|
||||
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent, end)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -750,17 +750,17 @@ void SMDImporter::ParseTrianglesSection(const char* szCurrent, const char** szCu
|
|||
if (TokenMatch(szCurrent,"end",3)) {
|
||||
break;
|
||||
}
|
||||
ParseTriangle(szCurrent,&szCurrent);
|
||||
ParseTriangle(szCurrent,&szCurrent, end);
|
||||
}
|
||||
SkipSpacesAndLineEnd(szCurrent,&szCurrent);
|
||||
SkipSpacesAndLineEnd(szCurrent,&szCurrent, end);
|
||||
*szCurrentOut = szCurrent;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse the vertex animation section of the file
|
||||
void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOut) {
|
||||
void SMDImporter::ParseVASection(const char *szCurrent, const char **szCurrentOut, const char *end) {
|
||||
unsigned int iCurIndex = 0;
|
||||
for ( ;; ) {
|
||||
if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) {
|
||||
if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent, end)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -774,10 +774,10 @@ void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOu
|
|||
// NOTE: The doc says that time values COULD be negative ...
|
||||
// NOTE2: this is the shape key -> valve docs
|
||||
int iTime = 0;
|
||||
if(!ParseSignedInt(szCurrent,&szCurrent,iTime) || configFrameID != (unsigned int)iTime) {
|
||||
if (!ParseSignedInt(szCurrent, &szCurrent, end, iTime) || configFrameID != (unsigned int)iTime) {
|
||||
break;
|
||||
}
|
||||
SkipLine(szCurrent,&szCurrent);
|
||||
SkipLine(szCurrent,&szCurrent, end);
|
||||
} else {
|
||||
if(0 == iCurIndex) {
|
||||
asTriangles.emplace_back();
|
||||
|
@ -785,7 +785,7 @@ void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOu
|
|||
if (++iCurIndex == 3) {
|
||||
iCurIndex = 0;
|
||||
}
|
||||
ParseVertex(szCurrent,&szCurrent,asTriangles.back().avVertices[iCurIndex],true);
|
||||
ParseVertex(szCurrent,&szCurrent, end, asTriangles.back().avVertices[iCurIndex],true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -794,16 +794,16 @@ void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOu
|
|||
asTriangles.pop_back();
|
||||
}
|
||||
|
||||
SkipSpacesAndLineEnd(szCurrent,&szCurrent);
|
||||
SkipSpacesAndLineEnd(szCurrent,&szCurrent, end);
|
||||
*szCurrentOut = szCurrent;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse the skeleton section of the file
|
||||
void SMDImporter::ParseSkeletonSection(const char* szCurrent, const char** szCurrentOut) {
|
||||
void SMDImporter::ParseSkeletonSection(const char *szCurrent, const char **szCurrentOut, const char *end) {
|
||||
int iTime = 0;
|
||||
for ( ;; ) {
|
||||
if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) {
|
||||
if (!SkipSpacesAndLineEnd(szCurrent,&szCurrent, end)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -811,15 +811,15 @@ void SMDImporter::ParseSkeletonSection(const char* szCurrent, const char** szCur
|
|||
if (TokenMatch(szCurrent,"end",3)) {
|
||||
break;
|
||||
} else if (TokenMatch(szCurrent,"time",4)) {
|
||||
// "time <n>\n" - Specifies the current animation frame
|
||||
if(!ParseSignedInt(szCurrent,&szCurrent,iTime)) {
|
||||
// "time <n>\n" - Specifies the current animation frame
|
||||
if (!ParseSignedInt(szCurrent, &szCurrent, end, iTime)) {
|
||||
break;
|
||||
}
|
||||
|
||||
iSmallestFrame = std::min(iSmallestFrame,iTime);
|
||||
SkipLine(szCurrent,&szCurrent);
|
||||
SkipLine(szCurrent, &szCurrent, end);
|
||||
} else {
|
||||
ParseSkeletonElement(szCurrent,&szCurrent,iTime);
|
||||
ParseSkeletonElement(szCurrent, &szCurrent, end, iTime);
|
||||
}
|
||||
}
|
||||
*szCurrentOut = szCurrent;
|
||||
|
@ -827,16 +827,16 @@ void SMDImporter::ParseSkeletonSection(const char* szCurrent, const char** szCur
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#define SMDI_PARSE_RETURN { \
|
||||
SkipLine(szCurrent,&szCurrent); \
|
||||
SkipLine(szCurrent,&szCurrent, end); \
|
||||
*szCurrentOut = szCurrent; \
|
||||
return; \
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse a node line
|
||||
void SMDImporter::ParseNodeInfo(const char* szCurrent, const char** szCurrentOut) {
|
||||
void SMDImporter::ParseNodeInfo(const char *szCurrent, const char **szCurrentOut, const char *end) {
|
||||
unsigned int iBone = 0;
|
||||
SkipSpacesAndLineEnd(szCurrent,&szCurrent);
|
||||
if ( !ParseUnsignedInt(szCurrent,&szCurrent,iBone) || !SkipSpaces(szCurrent,&szCurrent)) {
|
||||
SkipSpacesAndLineEnd(szCurrent, &szCurrent, end);
|
||||
if ( !ParseUnsignedInt(szCurrent, &szCurrent, end, iBone) || !SkipSpaces(szCurrent,&szCurrent, end)) {
|
||||
throw DeadlyImportError("Unexpected EOF/EOL while parsing bone index");
|
||||
}
|
||||
if (iBone == UINT_MAX) {
|
||||
|
@ -877,7 +877,7 @@ void SMDImporter::ParseNodeInfo(const char* szCurrent, const char** szCurrentOut
|
|||
szCurrent = szEnd;
|
||||
|
||||
// the only negative bone parent index that could occur is -1 AFAIK
|
||||
if(!ParseSignedInt(szCurrent,&szCurrent,(int&)bone.iParent)) {
|
||||
if(!ParseSignedInt(szCurrent, &szCurrent, end, (int&)bone.iParent)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone parent index. Assuming -1");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
|
@ -888,12 +888,12 @@ void SMDImporter::ParseNodeInfo(const char* szCurrent, const char** szCurrentOut
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse a skeleton element
|
||||
void SMDImporter::ParseSkeletonElement(const char* szCurrent, const char** szCurrentOut,int iTime) {
|
||||
void SMDImporter::ParseSkeletonElement(const char *szCurrent, const char **szCurrentOut, const char *end, int iTime) {
|
||||
aiVector3D vPos;
|
||||
aiVector3D vRot;
|
||||
|
||||
unsigned int iBone = 0;
|
||||
if(!ParseUnsignedInt(szCurrent,&szCurrent,iBone)) {
|
||||
if (!ParseUnsignedInt(szCurrent, &szCurrent, end, iBone)) {
|
||||
ASSIMP_LOG_ERROR("Unexpected EOF/EOL while parsing bone index");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
|
@ -907,27 +907,27 @@ void SMDImporter::ParseSkeletonElement(const char* szCurrent, const char** szCur
|
|||
SMD::Bone::Animation::MatrixKey& key = bone.sAnim.asKeys.back();
|
||||
|
||||
key.dTime = (double)iTime;
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.x)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vPos.x)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.x");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.y)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vPos.y)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.y");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.z)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vPos.z)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.z");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.x)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vRot.x)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.x");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.y)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vRot.y)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.y");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.z)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vRot.z)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.z");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
|
@ -947,11 +947,11 @@ void SMDImporter::ParseSkeletonElement(const char* szCurrent, const char** szCur
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse a triangle
|
||||
void SMDImporter::ParseTriangle(const char* szCurrent, const char** szCurrentOut) {
|
||||
void SMDImporter::ParseTriangle(const char *szCurrent, const char **szCurrentOut, const char *end) {
|
||||
asTriangles.emplace_back();
|
||||
SMD::Face& face = asTriangles.back();
|
||||
|
||||
if(!SkipSpaces(szCurrent,&szCurrent)) {
|
||||
if(!SkipSpaces(szCurrent, &szCurrent, end)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing a triangle");
|
||||
return;
|
||||
}
|
||||
|
@ -963,19 +963,19 @@ void SMDImporter::ParseTriangle(const char* szCurrent, const char** szCurrentOut
|
|||
// ... and get the index that belongs to this file name
|
||||
face.iTexture = GetTextureIndex(std::string(szLast,(uintptr_t)szCurrent-(uintptr_t)szLast));
|
||||
|
||||
SkipSpacesAndLineEnd(szCurrent,&szCurrent);
|
||||
SkipSpacesAndLineEnd(szCurrent, &szCurrent, end);
|
||||
|
||||
// load three vertices
|
||||
for (auto &avVertex : face.avVertices) {
|
||||
ParseVertex(szCurrent,&szCurrent, avVertex);
|
||||
ParseVertex(szCurrent, &szCurrent, end, avVertex);
|
||||
}
|
||||
*szCurrentOut = szCurrent;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse a float
|
||||
bool SMDImporter::ParseFloat(const char* szCurrent, const char** szCurrentOut, float& out) {
|
||||
if(!SkipSpaces(&szCurrent)) {
|
||||
bool SMDImporter::ParseFloat(const char *szCurrent, const char **szCurrentOut, const char *end, float &out) {
|
||||
if (!SkipSpaces(&szCurrent, end)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -985,8 +985,8 @@ bool SMDImporter::ParseFloat(const char* szCurrent, const char** szCurrentOut, f
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse an unsigned int
|
||||
bool SMDImporter::ParseUnsignedInt(const char* szCurrent, const char** szCurrentOut, unsigned int& out) {
|
||||
if(!SkipSpaces(&szCurrent)) {
|
||||
bool SMDImporter::ParseUnsignedInt(const char *szCurrent, const char **szCurrentOut, const char *end, unsigned int &out) {
|
||||
if(!SkipSpaces(&szCurrent, end)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -996,8 +996,8 @@ bool SMDImporter::ParseUnsignedInt(const char* szCurrent, const char** szCurrent
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse a signed int
|
||||
bool SMDImporter::ParseSignedInt(const char* szCurrent, const char** szCurrentOut, int& out) {
|
||||
if(!SkipSpaces(&szCurrent)) {
|
||||
bool SMDImporter::ParseSignedInt(const char *szCurrent, const char **szCurrentOut, const char *end, int &out) {
|
||||
if(!SkipSpaces(&szCurrent, end)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1008,37 +1008,37 @@ bool SMDImporter::ParseSignedInt(const char* szCurrent, const char** szCurrentOu
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Parse a vertex
|
||||
void SMDImporter::ParseVertex(const char* szCurrent,
|
||||
const char** szCurrentOut, SMD::Vertex& vertex,
|
||||
const char **szCurrentOut, const char *end, SMD::Vertex &vertex,
|
||||
bool bVASection /*= false*/) {
|
||||
if (SkipSpaces(&szCurrent) && IsLineEnd(*szCurrent)) {
|
||||
SkipSpacesAndLineEnd(szCurrent,&szCurrent);
|
||||
return ParseVertex(szCurrent,szCurrentOut,vertex,bVASection);
|
||||
if (SkipSpaces(&szCurrent, end) && IsLineEnd(*szCurrent)) {
|
||||
SkipSpacesAndLineEnd(szCurrent,&szCurrent, end);
|
||||
return ParseVertex(szCurrent, szCurrentOut, end, vertex, bVASection);
|
||||
}
|
||||
if(!ParseSignedInt(szCurrent,&szCurrent,(int&)vertex.iParentNode)) {
|
||||
if(!ParseSignedInt(szCurrent, &szCurrent, end, (int&)vertex.iParentNode)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.parent");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.x)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.pos.x)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.x");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.y)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.pos.y)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.y");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.z)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.pos.z)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.z");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.x)) {
|
||||
if(!ParseFloat(szCurrent,&szCurrent,end, (float&)vertex.nor.x)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.x");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.y)) {
|
||||
if(!ParseFloat(szCurrent,&szCurrent, end, (float&)vertex.nor.y)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.y");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.z)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.nor.z)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.z");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
|
@ -1047,11 +1047,11 @@ void SMDImporter::ParseVertex(const char* szCurrent,
|
|||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.uv.x)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.uv.x)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.uv.x");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.uv.y)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, (float&)vertex.uv.y)) {
|
||||
LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.uv.y");
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
|
@ -1059,16 +1059,16 @@ void SMDImporter::ParseVertex(const char* szCurrent,
|
|||
// now read the number of bones affecting this vertex
|
||||
// all elements from now are fully optional, we don't need them
|
||||
unsigned int iSize = 0;
|
||||
if(!ParseUnsignedInt(szCurrent,&szCurrent,iSize)) {
|
||||
if(!ParseUnsignedInt(szCurrent, &szCurrent, end, iSize)) {
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
vertex.aiBoneLinks.resize(iSize,std::pair<unsigned int, float>(0,0.0f));
|
||||
|
||||
for (auto &aiBoneLink : vertex.aiBoneLinks) {
|
||||
if(!ParseUnsignedInt(szCurrent,&szCurrent,aiBoneLink.first)) {
|
||||
if(!ParseUnsignedInt(szCurrent, &szCurrent, end, aiBoneLink.first)) {
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
if(!ParseFloat(szCurrent,&szCurrent,aiBoneLink.second)) {
|
||||
if(!ParseFloat(szCurrent, &szCurrent, end, aiBoneLink.second)) {
|
||||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
}
|
||||
|
@ -1077,6 +1077,6 @@ void SMDImporter::ParseVertex(const char* szCurrent,
|
|||
SMDI_PARSE_RETURN;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Assimp
|
||||
|
||||
#endif // !! ASSIMP_BUILD_NO_SMD_IMPORTER
|
||||
|
|
|
@ -162,7 +162,7 @@ struct Bone {
|
|||
class ASSIMP_API SMDImporter : public BaseImporter {
|
||||
public:
|
||||
SMDImporter();
|
||||
~SMDImporter() override;
|
||||
~SMDImporter() override = default;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the class can handle the format of the given file.
|
||||
|
@ -206,7 +206,7 @@ protected:
|
|||
* the next section (or to EOF)
|
||||
*/
|
||||
void ParseTrianglesSection(const char* szCurrent,
|
||||
const char** szCurrentOut);
|
||||
const char **szCurrentOut, const char *end);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Parse the vertex animation section in VTA files
|
||||
|
@ -216,7 +216,7 @@ protected:
|
|||
* the next section (or to EOF)
|
||||
*/
|
||||
void ParseVASection(const char* szCurrent,
|
||||
const char** szCurrentOut);
|
||||
const char **szCurrentOu, const char *end);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Parse the nodes section of the SMD file
|
||||
|
@ -226,7 +226,7 @@ protected:
|
|||
* the next section (or to EOF)
|
||||
*/
|
||||
void ParseNodesSection(const char* szCurrent,
|
||||
const char** szCurrentOut);
|
||||
const char **szCurrentOut, const char *end);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Parse the skeleton section of the SMD file
|
||||
|
@ -236,7 +236,7 @@ protected:
|
|||
* the next section (or to EOF)
|
||||
*/
|
||||
void ParseSkeletonSection(const char* szCurrent,
|
||||
const char** szCurrentOut);
|
||||
const char **szCurrentOut, const char *end);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Parse a single triangle in the SMD file
|
||||
|
@ -245,8 +245,7 @@ protected:
|
|||
* \param szCurrentOut Receives the output cursor position
|
||||
*/
|
||||
void ParseTriangle(const char* szCurrent,
|
||||
const char** szCurrentOut);
|
||||
|
||||
const char **szCurrentOut, const char *end);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Parse a single vertex in the SMD file
|
||||
|
@ -256,7 +255,7 @@ protected:
|
|||
* \param vertex Vertex to be filled
|
||||
*/
|
||||
void ParseVertex(const char* szCurrent,
|
||||
const char** szCurrentOut, SMD::Vertex& vertex,
|
||||
const char **szCurrentOut, const char *end, SMD::Vertex &vertex,
|
||||
bool bVASection = false);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -271,32 +270,31 @@ protected:
|
|||
/** Parse a line in the skeleton section
|
||||
*/
|
||||
void ParseSkeletonElement(const char* szCurrent,
|
||||
const char** szCurrentOut,int iTime);
|
||||
const char **szCurrentOut, const char *end, int iTime);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Parse a line in the nodes section
|
||||
*/
|
||||
void ParseNodeInfo(const char* szCurrent,
|
||||
const char** szCurrentOut);
|
||||
|
||||
const char **szCurrentOut, const char *end);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Parse a floating-point value
|
||||
*/
|
||||
bool ParseFloat(const char* szCurrent,
|
||||
const char** szCurrentOut, float& out);
|
||||
const char **szCurrentOut, const char *end, float &out);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Parse an unsigned integer. There may be no sign!
|
||||
*/
|
||||
bool ParseUnsignedInt(const char* szCurrent,
|
||||
const char** szCurrentOut, unsigned int& out);
|
||||
const char **szCurrentOut, const char *end, unsigned int &out);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Parse a signed integer. Signs (+,-) are handled.
|
||||
*/
|
||||
bool ParseSignedInt(const char* szCurrent,
|
||||
const char** szCurrentOut, int& out);
|
||||
const char **szCurrentOut, const char *end, int &out);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Fix invalid time values in the file
|
||||
|
@ -304,7 +302,7 @@ protected:
|
|||
void FixTimeValues();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Add all children of a bone as subnodes to a node
|
||||
/** Add all children of a bone as sub-nodes to a node
|
||||
* \param pcNode Parent node
|
||||
* \param iParent Parent bone index
|
||||
*/
|
||||
|
@ -329,17 +327,15 @@ protected:
|
|||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
inline bool SkipLine( const char* in, const char** out)
|
||||
{
|
||||
Assimp::SkipLine(in,out);
|
||||
inline bool SkipLine( const char* in, const char** out, const char *end) {
|
||||
Assimp::SkipLine(in, out, end);
|
||||
++iLineNumber;
|
||||
return true;
|
||||
}
|
||||
// -------------------------------------------------------------------
|
||||
inline bool SkipSpacesAndLineEnd( const char* in, const char** out)
|
||||
{
|
||||
inline bool SkipSpacesAndLineEnd(const char *in, const char **out, const char *end) {
|
||||
++iLineNumber;
|
||||
return Assimp::SkipSpacesAndLineEnd(in,out);
|
||||
return Assimp::SkipSpacesAndLineEnd(in, out, end);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -349,6 +345,7 @@ private:
|
|||
|
||||
/** Buffer to hold the loaded file */
|
||||
std::vector<char> mBuffer;
|
||||
char *mEnd;
|
||||
|
||||
/** Output scene to be filled
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -40,9 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file STEPFileReader.cpp
|
||||
/**
|
||||
* @file STEPFileReader.cpp
|
||||
* @brief Implementation of the STEP file parser, which fills a
|
||||
* STEP::DB with data read from a file.
|
||||
* STEP::DB with data read from a file.
|
||||
*/
|
||||
|
||||
#include "STEPFileReader.h"
|
||||
|
@ -58,34 +58,28 @@ using namespace Assimp;
|
|||
namespace EXPRESS = STEP::EXPRESS;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = std::string())
|
||||
{
|
||||
std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = std::string()) {
|
||||
return line == STEP::SyntaxError::LINE_NOT_SPECIFIED ? prefix+s : static_cast<std::string>( (Formatter::format(),prefix,"(line ",line,") ",s) );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::string AddEntityID(const std::string& s,uint64_t entity /*= ENTITY_NOT_SPECIFIED*/, const std::string& prefix = std::string())
|
||||
{
|
||||
std::string AddEntityID(const std::string& s,uint64_t entity /*= ENTITY_NOT_SPECIFIED*/, const std::string& prefix = std::string()) {
|
||||
return entity == STEP::TypeError::ENTITY_NOT_SPECIFIED ? prefix+s : static_cast<std::string>( (Formatter::format(),prefix,"(entity #",entity,") ",s));
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
STEP::SyntaxError::SyntaxError (const std::string& s,uint64_t line /* = LINE_NOT_SPECIFIED */)
|
||||
: DeadlyImportError(AddLineNumber(s,line))
|
||||
{
|
||||
|
||||
STEP::SyntaxError::SyntaxError (const std::string& s,uint64_t line) : DeadlyImportError(AddLineNumber(s,line)) {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
STEP::TypeError::TypeError (const std::string& s,uint64_t entity /* = ENTITY_NOT_SPECIFIED */,uint64_t line /*= LINE_NOT_SPECIFIED*/)
|
||||
: DeadlyImportError(AddLineNumber(AddEntityID(s,entity),line))
|
||||
{
|
||||
|
||||
STEP::TypeError::TypeError (const std::string& s,uint64_t entity, uint64_t line) : DeadlyImportError(AddLineNumber(AddEntityID(s,entity),line)) {
|
||||
// empty
|
||||
}
|
||||
|
||||
static const char *ISO_Token = "ISO-10303-21;";
|
||||
static const char *FILE_SCHEMA_Token = "FILE_SCHEMA";
|
||||
static constexpr char ISO_Token[] = "ISO-10303-21;";
|
||||
static constexpr char FILE_SCHEMA_Token[] = "FILE_SCHEMA";
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream) {
|
||||
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(std::move(stream)));
|
||||
|
@ -110,8 +104,9 @@ STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream) {
|
|||
|
||||
if (s.substr(0,11) == FILE_SCHEMA_Token) {
|
||||
const char* sz = s.c_str()+11;
|
||||
SkipSpaces(sz,&sz);
|
||||
std::shared_ptr< const EXPRESS::DataType > schema = EXPRESS::DataType::Parse(sz);
|
||||
const char *end = s.c_str() + s.size();
|
||||
SkipSpaces(sz,&sz, end);
|
||||
std::shared_ptr< const EXPRESS::DataType > schema = EXPRESS::DataType::Parse(sz, end);
|
||||
|
||||
// the file schema should be a regular list entity, although it usually contains exactly one entry
|
||||
// since the list itself is contained in a regular parameter list, we actually have
|
||||
|
@ -304,10 +299,10 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/)
|
||||
std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& inout, const char *end, uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/)
|
||||
{
|
||||
const char* cur = inout;
|
||||
SkipSpaces(&cur);
|
||||
SkipSpaces(&cur, end);
|
||||
if (*cur == ',' || IsSpaceOrNewLine(*cur)) {
|
||||
throw STEP::SyntaxError("unexpected token, expected parameter",line);
|
||||
}
|
||||
|
@ -325,7 +320,7 @@ std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& i
|
|||
std::transform(s.begin(),s.end(),s.begin(),&ai_tolower<char> );
|
||||
if (schema->IsKnownToken(s)) {
|
||||
for(cur = t+1;*cur++ != '(';);
|
||||
std::shared_ptr<const EXPRESS::DataType> dt = Parse(cur);
|
||||
std::shared_ptr<const EXPRESS::DataType> dt = Parse(cur, end);
|
||||
inout = *cur ? cur+1 : cur;
|
||||
return dt;
|
||||
}
|
||||
|
@ -348,7 +343,7 @@ std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& i
|
|||
else if (*cur == '(' ) {
|
||||
// start of an aggregate, further parsing is done by the LIST factory constructor
|
||||
inout = cur;
|
||||
return EXPRESS::LIST::Parse(inout,line,schema);
|
||||
return EXPRESS::LIST::Parse(inout, end, line, schema);
|
||||
}
|
||||
else if (*cur == '.' ) {
|
||||
// enum (includes boolean)
|
||||
|
@ -427,9 +422,10 @@ std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& i
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/) {
|
||||
std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout, const char *end,
|
||||
uint64_t line, const EXPRESS::ConversionSchema* schema) {
|
||||
const std::shared_ptr<EXPRESS::LIST> list = std::make_shared<EXPRESS::LIST>();
|
||||
EXPRESS::LIST::MemberList& members = list->members;
|
||||
EXPRESS::LIST::MemberList& cur_members = list->members;
|
||||
|
||||
const char* cur = inout;
|
||||
if (*cur++ != '(') {
|
||||
|
@ -442,19 +438,19 @@ std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout,uin
|
|||
count += (*c == ',' ? 1 : 0);
|
||||
}
|
||||
|
||||
members.reserve(count);
|
||||
cur_members.reserve(count);
|
||||
|
||||
for(;;++cur) {
|
||||
if (!*cur) {
|
||||
throw STEP::SyntaxError("unexpected end of line while reading list");
|
||||
}
|
||||
SkipSpaces(cur,&cur);
|
||||
SkipSpaces(cur,&cur, end);
|
||||
if (*cur == ')') {
|
||||
break;
|
||||
}
|
||||
|
||||
members.push_back( EXPRESS::DataType::Parse(cur,line,schema));
|
||||
SkipSpaces(cur,&cur);
|
||||
cur_members.push_back(EXPRESS::DataType::Parse(cur, end, line, schema));
|
||||
SkipSpaces(cur, &cur, end);
|
||||
|
||||
if (*cur != ',') {
|
||||
if (*cur == ')') {
|
||||
|
@ -464,7 +460,7 @@ std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout,uin
|
|||
}
|
||||
}
|
||||
|
||||
inout = cur+1;
|
||||
inout = cur + 1;
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -543,7 +539,8 @@ void STEP::LazyObject::LazyInit() const {
|
|||
}
|
||||
|
||||
const char* acopy = args;
|
||||
std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy,(uint64_t)STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
|
||||
const char *end = acopy + std::strlen(args);
|
||||
std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy, end, (uint64_t)STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
|
||||
delete[] args;
|
||||
args = nullptr;
|
||||
|
||||
|
|
|
@ -60,8 +60,7 @@ void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const*
|
|||
|
||||
/// @brief Helper to read a file.
|
||||
template <size_t N, size_t N2>
|
||||
inline
|
||||
void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) {
|
||||
inline void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) {
|
||||
return ReadFile(db,scheme,arr,N,arr2,N2);
|
||||
}
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ static bool IsAsciiSTL(const char *buffer, size_t fileSize) {
|
|||
|
||||
const char *bufferEnd = buffer + fileSize;
|
||||
|
||||
if (!SkipSpaces(&buffer)) {
|
||||
if (!SkipSpaces(&buffer, bufferEnd)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -244,11 +244,11 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
|
|||
aiNode *node = new aiNode;
|
||||
node->mParent = root;
|
||||
nodes.push_back(node);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, bufferEnd);
|
||||
ai_assert(!IsLineEnd(sz));
|
||||
|
||||
sz += 5; // skip the "solid"
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, bufferEnd);
|
||||
const char *szMe = sz;
|
||||
while (!IsSpaceOrNewLine(*sz)) {
|
||||
sz++;
|
||||
|
@ -270,7 +270,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
|
|||
unsigned int faceVertexCounter = 3;
|
||||
for (;;) {
|
||||
// go to the next token
|
||||
if (!SkipSpacesAndLineEnd(&sz)) {
|
||||
if (!SkipSpacesAndLineEnd(&sz, bufferEnd)) {
|
||||
// seems we're finished although there was no end marker
|
||||
ASSIMP_LOG_WARN("STL: unexpected EOF. \'endsolid\' keyword was expected");
|
||||
break;
|
||||
|
@ -284,7 +284,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
|
|||
faceVertexCounter = 0;
|
||||
|
||||
sz += 6;
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, bufferEnd);
|
||||
if (strncmp(sz, "normal", 6)) {
|
||||
ASSIMP_LOG_WARN("STL: a facet normal vector was expected but not found");
|
||||
} else {
|
||||
|
@ -293,11 +293,11 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
|
|||
}
|
||||
aiVector3D vn;
|
||||
sz += 7;
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, bufferEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.x);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, bufferEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.y);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, bufferEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.z);
|
||||
normalBuffer.emplace_back(vn);
|
||||
normalBuffer.emplace_back(vn);
|
||||
|
@ -312,13 +312,13 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
|
|||
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
|
||||
}
|
||||
sz += 7;
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, bufferEnd);
|
||||
positionBuffer.emplace_back();
|
||||
aiVector3D *vn = &positionBuffer.back();
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->x);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, bufferEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->y);
|
||||
SkipSpaces(&sz);
|
||||
SkipSpaces(&sz, bufferEnd);
|
||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->z);
|
||||
faceVertexCounter++;
|
||||
}
|
||||
|
@ -326,7 +326,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
|
|||
do {
|
||||
++sz;
|
||||
} while (!IsLineEnd(*sz));
|
||||
SkipSpacesAndLineEnd(&sz);
|
||||
SkipSpacesAndLineEnd(&sz, bufferEnd);
|
||||
// finished!
|
||||
break;
|
||||
} else { // else skip the whole identifier
|
||||
|
|
|
@ -199,35 +199,27 @@ public:
|
|||
}
|
||||
|
||||
public:
|
||||
/** parse a variable from a string and set 'inout' to the character
|
||||
* behind the last consumed character. An optional schema enables,
|
||||
* if specified, automatic conversion of custom data types.
|
||||
*
|
||||
* @throw SyntaxError
|
||||
*/
|
||||
static std::shared_ptr<const EXPRESS::DataType> Parse(const char *&inout,
|
||||
uint64_t line = SyntaxError::LINE_NOT_SPECIFIED,
|
||||
const EXPRESS::ConversionSchema *schema = nullptr);
|
||||
/// @brief Parse a variable from a string and set 'inout' to the character behind the last consumed character.
|
||||
///
|
||||
/// An optional schema enables, if specified, automatic conversion of custom data types.
|
||||
///
|
||||
/// @throw SyntaxError
|
||||
static std::shared_ptr<const EXPRESS::DataType> Parse(const char *&inout, const char *end,
|
||||
uint64_t line = SyntaxError::LINE_NOT_SPECIFIED, const EXPRESS::ConversionSchema *schema = nullptr);
|
||||
};
|
||||
|
||||
typedef DataType SELECT;
|
||||
typedef DataType LOGICAL;
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** Sentinel class to represent explicitly unset (optional) fields ($) */
|
||||
/// Sentinel class to represent explicitly unset (optional) fields ($)
|
||||
// -------------------------------------------------------------------------------
|
||||
class UNSET : public DataType {
|
||||
public:
|
||||
private:
|
||||
};
|
||||
class UNSET : public DataType {};
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** Sentinel class to represent explicitly derived fields (*) */
|
||||
/// Sentinel class to represent explicitly derived fields (*)
|
||||
// -------------------------------------------------------------------------------
|
||||
class ISDERIVED : public DataType {
|
||||
public:
|
||||
private:
|
||||
};
|
||||
class ISDERIVED : public DataType {};
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** Shared implementation for some of the primitive data type, i.e. int, float
|
||||
|
@ -304,7 +296,7 @@ public:
|
|||
public:
|
||||
/** @see DaraType::Parse
|
||||
*/
|
||||
static std::shared_ptr<const EXPRESS::LIST> Parse(const char *&inout,
|
||||
static std::shared_ptr<const EXPRESS::LIST> Parse(const char *&inout, const char *end,
|
||||
uint64_t line = SyntaxError::LINE_NOT_SPECIFIED,
|
||||
const EXPRESS::ConversionSchema *schema = nullptr);
|
||||
|
||||
|
|
|
@ -320,17 +320,18 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
|
|||
std::vector<char> _data;
|
||||
TextFileToBuffer(pb.get(), _data);
|
||||
const char *data = &_data[0];
|
||||
const char *end = &_data[_data.size() - 1] + 1;
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> tempTextures;
|
||||
|
||||
// do a quick search in the UC file for some known, usually texture-related, tags
|
||||
for (; *data; ++data) {
|
||||
if (TokenMatchI(data, "#exec", 5)) {
|
||||
SkipSpacesAndLineEnd(&data);
|
||||
SkipSpacesAndLineEnd(&data, end);
|
||||
|
||||
// #exec TEXTURE IMPORT [...] NAME=jjjjj [...] FILE=jjjj.pcx [...]
|
||||
if (TokenMatchI(data, "TEXTURE", 7)) {
|
||||
SkipSpacesAndLineEnd(&data);
|
||||
SkipSpacesAndLineEnd(&data, end);
|
||||
|
||||
if (TokenMatchI(data, "IMPORT", 6)) {
|
||||
tempTextures.emplace_back();
|
||||
|
@ -348,14 +349,15 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
|
|||
me.second = std::string(d, (size_t)(data - d));
|
||||
}
|
||||
}
|
||||
if (!me.first.length() || !me.second.length())
|
||||
if (!me.first.length() || !me.second.length()) {
|
||||
tempTextures.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
// #exec MESHMAP SETTEXTURE MESHMAP=box NUM=1 TEXTURE=Jtex1
|
||||
// #exec MESHMAP SCALE MESHMAP=box X=0.1 Y=0.1 Z=0.2
|
||||
else if (TokenMatchI(data, "MESHMAP", 7)) {
|
||||
SkipSpacesAndLineEnd(&data);
|
||||
SkipSpacesAndLineEnd(&data, end);
|
||||
|
||||
if (TokenMatchI(data, "SETTEXTURE", 10)) {
|
||||
|
||||
|
@ -369,8 +371,7 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
|
|||
} else if (!ASSIMP_strincmp(data, "TEXTURE=", 8)) {
|
||||
data += 8;
|
||||
const char *d = data;
|
||||
for (; !IsSpaceOrNewLine(*data); ++data)
|
||||
;
|
||||
for (; !IsSpaceOrNewLine(*data); ++data);
|
||||
me.second = std::string(d, (size_t)(data - d));
|
||||
|
||||
// try to find matching path names, doesn't care if we don't find them
|
||||
|
@ -408,7 +409,7 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
|
|||
// find out how many output meshes and materials we'll have and build material indices
|
||||
for (Unreal::Triangle &tri : triangles) {
|
||||
Unreal::TempMat mat(tri);
|
||||
std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(), materials.end(), mat);
|
||||
auto nt = std::find(materials.begin(), materials.end(), mat);
|
||||
if (nt == materials.end()) {
|
||||
// add material
|
||||
tri.matIndex = static_cast<unsigned int>(materials.size());
|
||||
|
|
|
@ -359,10 +359,18 @@ void XFileImporter::CreateMeshes(aiScene *pScene, aiNode *pNode, const std::vect
|
|||
// set up a vertex-linear array of the weights for quick searching if a bone influences a vertex
|
||||
std::vector<ai_real> oldWeights(sourceMesh->mPositions.size(), 0.0);
|
||||
for (unsigned int d = 0; d < obone.mWeights.size(); ++d) {
|
||||
const unsigned int boneIdx = obone.mWeights[d].mVertex;
|
||||
if (boneIdx < obone.mWeights.size()) {
|
||||
// TODO The conditional against boneIdx which was added in commit f844c33
|
||||
// TODO (https://github.com/assimp/assimp/commit/f844c3397d7726477ab0fdca8efd3df56c18366b)
|
||||
// TODO causes massive breakage as detailed in:
|
||||
// TODO https://github.com/assimp/assimp/issues/5332
|
||||
// TODO In cases like this unit tests are less useful, since the model still has
|
||||
// TODO meshes, textures, animations etc. and asserts against these values may pass;
|
||||
// TODO when touching importer code, it is crucial that developers also run manual, visual
|
||||
// TODO checks to ensure there's no obvious breakage _before_ commiting to main branch
|
||||
//const unsigned int boneIdx = obone.mWeights[d].mVertex;
|
||||
//if (boneIdx < obone.mWeights.size()) {
|
||||
oldWeights[obone.mWeights[d].mVertex] = obone.mWeights[d].mWeight;
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
// collect all vertex weights that influence a vertex in the new mesh
|
||||
|
|
|
@ -188,6 +188,51 @@ mg_m_err:
|
|||
pFaces.clear();
|
||||
}
|
||||
|
||||
void X3DGeoHelper::coordIdx_str2lines_arr(const std::vector<int32_t> &pCoordIdx, std::vector<aiFace> &pFaces) {
|
||||
std::vector<int32_t> f_data(pCoordIdx);
|
||||
|
||||
if (f_data.back() != (-1)) {
|
||||
f_data.push_back(-1);
|
||||
}
|
||||
|
||||
// reserve average size.
|
||||
pFaces.reserve(f_data.size() / 2);
|
||||
for (std::vector<int32_t>::const_iterator startIt = f_data.cbegin(), endIt = f_data.cbegin(); endIt != f_data.cend(); ++endIt) {
|
||||
// check for end of current polyline
|
||||
if (*endIt != -1)
|
||||
continue;
|
||||
|
||||
// found end of polyline, check if this is a valid polyline
|
||||
std::size_t numIndices = std::distance(startIt, endIt);
|
||||
if (numIndices <= 1)
|
||||
goto mg_m_err;
|
||||
|
||||
// create line faces out of polyline indices
|
||||
for (int32_t idx0 = *startIt++; startIt != endIt; ++startIt) {
|
||||
int32_t idx1 = *startIt;
|
||||
|
||||
aiFace tface;
|
||||
tface.mNumIndices = 2;
|
||||
tface.mIndices = new unsigned int[2];
|
||||
tface.mIndices[0] = idx0;
|
||||
tface.mIndices[1] = idx1;
|
||||
pFaces.push_back(tface);
|
||||
|
||||
idx0 = idx1;
|
||||
}
|
||||
|
||||
++startIt;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
mg_m_err:
|
||||
for (size_t i = 0, i_e = pFaces.size(); i < i_e; i++)
|
||||
delete[] pFaces[i].mIndices;
|
||||
|
||||
pFaces.clear();
|
||||
}
|
||||
|
||||
void X3DGeoHelper::add_color(aiMesh &pMesh, const std::list<aiColor3D> &pColors, const bool pColorPerVertex) {
|
||||
std::list<aiColor4D> tcol;
|
||||
|
||||
|
@ -528,4 +573,40 @@ aiMesh *X3DGeoHelper::make_mesh(const std::vector<int32_t> &pCoordIdx, const std
|
|||
return tmesh;
|
||||
}
|
||||
|
||||
aiMesh *X3DGeoHelper::make_line_mesh(const std::vector<int32_t> &pCoordIdx, const std::list<aiVector3D> &pVertices) {
|
||||
std::vector<aiFace> faces;
|
||||
|
||||
// create faces array from input string with vertices indices.
|
||||
X3DGeoHelper::coordIdx_str2lines_arr(pCoordIdx, faces);
|
||||
if (!faces.size()) {
|
||||
throw DeadlyImportError("Failed to create mesh, faces list is empty.");
|
||||
}
|
||||
|
||||
//
|
||||
// Create new mesh and copy geometry data.
|
||||
//
|
||||
aiMesh *tmesh = new aiMesh;
|
||||
size_t ts = faces.size();
|
||||
// faces
|
||||
tmesh->mFaces = new aiFace[ts];
|
||||
tmesh->mNumFaces = static_cast<unsigned int>(ts);
|
||||
for (size_t i = 0; i < ts; i++)
|
||||
tmesh->mFaces[i] = faces[i];
|
||||
|
||||
// vertices
|
||||
std::list<aiVector3D>::const_iterator vit = pVertices.begin();
|
||||
|
||||
ts = pVertices.size();
|
||||
tmesh->mVertices = new aiVector3D[ts];
|
||||
tmesh->mNumVertices = static_cast<unsigned int>(ts);
|
||||
for (size_t i = 0; i < ts; i++) {
|
||||
tmesh->mVertices[i] = *vit++;
|
||||
}
|
||||
|
||||
// set primitive type and return result.
|
||||
tmesh->mPrimitiveTypes = aiPrimitiveType_LINE;
|
||||
|
||||
return tmesh;
|
||||
}
|
||||
|
||||
} // namespace Assimp
|
||||
|
|
|
@ -21,6 +21,7 @@ public:
|
|||
static void polylineIdx_to_lineIdx(const std::list<int32_t> &pPolylineCoordIdx, std::list<int32_t> &pLineCoordIdx);
|
||||
static void rect_parallel_epiped(const aiVector3D &pSize, std::list<aiVector3D> &pVertices);
|
||||
static void coordIdx_str2faces_arr(const std::vector<int32_t> &pCoordIdx, std::vector<aiFace> &pFaces, unsigned int &pPrimitiveTypes);
|
||||
static void coordIdx_str2lines_arr(const std::vector<int32_t> &pCoordIdx, std::vector<aiFace> &pFaces);
|
||||
static void add_color(aiMesh &pMesh, const std::list<aiColor3D> &pColors, const bool pColorPerVertex);
|
||||
static void add_color(aiMesh &pMesh, const std::list<aiColor4D> &pColors, const bool pColorPerVertex);
|
||||
static void add_color(aiMesh &pMesh, const std::vector<int32_t> &pCoordIdx, const std::vector<int32_t> &pColorIdx,
|
||||
|
@ -34,6 +35,7 @@ public:
|
|||
const std::list<aiVector2D> &pTexCoords);
|
||||
static void add_tex_coord(aiMesh &pMesh, const std::list<aiVector2D> &pTexCoords);
|
||||
static aiMesh *make_mesh(const std::vector<int32_t> &pCoordIdx, const std::list<aiVector3D> &pVertices);
|
||||
static aiMesh *make_line_mesh(const std::vector<int32_t> &pCoordIdx, const std::list<aiVector3D> &pVertices);
|
||||
};
|
||||
|
||||
} // namespace Assimp
|
||||
|
|
|
@ -320,7 +320,7 @@ void X3DImporter::Postprocess_BuildMesh(const X3DNodeElementBase &pNodeElement,
|
|||
// at first search for <Coordinate> node and create mesh.
|
||||
for (std::list<X3DNodeElementBase *>::iterator ch_it = tnemesh.Children.begin(); ch_it != tnemesh.Children.end(); ++ch_it) {
|
||||
if ((*ch_it)->Type == X3DElemType::ENET_Coordinate) {
|
||||
*pMesh = X3DGeoHelper::make_mesh(tnemesh.CoordIndex, ((X3DNodeElementCoordinate *)*ch_it)->Value);
|
||||
*pMesh = X3DGeoHelper::make_line_mesh(tnemesh.CoordIndex, ((X3DNodeElementCoordinate *)*ch_it)->Value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -700,13 +700,14 @@ unsigned int XGLImporter::ReadIDAttr(XmlNode &node) {
|
|||
float XGLImporter::ReadFloat(XmlNode &node) {
|
||||
std::string v;
|
||||
XmlParser::getValueAsString(node, v);
|
||||
const char *s = v.c_str(), *se;
|
||||
if (!SkipSpaces(&s)) {
|
||||
const char *s = v.c_str();
|
||||
const char *end = v.c_str() + v.size();
|
||||
if (!SkipSpaces(&s, end)) {
|
||||
LogError("unexpected EOL, failed to parse index element");
|
||||
return 0.f;
|
||||
}
|
||||
float t;
|
||||
se = fast_atoreal_move(s, t);
|
||||
float t{ 0.0f };
|
||||
const char *se = fast_atoreal_move(s, t);
|
||||
if (se == s) {
|
||||
LogError("failed to read float text");
|
||||
return 0.f;
|
||||
|
@ -720,7 +721,8 @@ unsigned int XGLImporter::ReadIndexFromText(XmlNode &node) {
|
|||
std::string v;
|
||||
XmlParser::getValueAsString(node, v);
|
||||
const char *s = v.c_str();
|
||||
if (!SkipSpaces(&s)) {
|
||||
const char *end = v.c_str() + v.size();
|
||||
if (!SkipSpaces(&s, end)) {
|
||||
LogError("unexpected EOL, failed to parse index element");
|
||||
return ErrorId;
|
||||
}
|
||||
|
@ -741,16 +743,17 @@ aiVector2D XGLImporter::ReadVec2(XmlNode &node) {
|
|||
std::string val;
|
||||
XmlParser::getValueAsString(node, val);
|
||||
const char *s = val.c_str();
|
||||
const char *end = val.c_str() + val.size();
|
||||
ai_real v[2] = {};
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!SkipSpaces(&s)) {
|
||||
if (!SkipSpaces(&s, end)) {
|
||||
LogError("unexpected EOL, failed to parse vec2");
|
||||
return vec;
|
||||
}
|
||||
|
||||
v[i] = fast_atof(&s);
|
||||
|
||||
SkipSpaces(&s);
|
||||
SkipSpaces(&s, end);
|
||||
if (i != 1 && *s != ',') {
|
||||
LogError("expected comma, failed to parse vec2");
|
||||
return vec;
|
||||
|
@ -769,14 +772,15 @@ aiVector3D XGLImporter::ReadVec3(XmlNode &node) {
|
|||
std::string v;
|
||||
XmlParser::getValueAsString(node, v);
|
||||
const char *s = v.c_str();
|
||||
const char *end = v.c_str() + v.size();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (!SkipSpaces(&s)) {
|
||||
if (!SkipSpaces(&s, end)) {
|
||||
LogError("unexpected EOL, failed to parse vec3");
|
||||
return vec;
|
||||
}
|
||||
vec[i] = fast_atof(&s);
|
||||
|
||||
SkipSpaces(&s);
|
||||
SkipSpaces(&s, end);
|
||||
if (i != 2 && *s != ',') {
|
||||
LogError("expected comma, failed to parse vec3");
|
||||
return vec;
|
||||
|
|
|
@ -547,7 +547,7 @@ struct BufferView : public Object {
|
|||
BufferViewTarget target; //! The target that the WebGL buffer should be bound to.
|
||||
|
||||
void Read(Value &obj, Asset &r);
|
||||
uint8_t *GetPointer(size_t accOffset);
|
||||
uint8_t *GetPointerAndTailSize(size_t accOffset, size_t& outTailSize);
|
||||
};
|
||||
|
||||
//! A typed view into a BufferView. A BufferView contains raw binary data.
|
||||
|
@ -629,7 +629,7 @@ struct Accessor : public Object {
|
|||
|
||||
std::vector<uint8_t> data; //!< Actual data, which may be defaulted to an array of zeros or the original data, with the sparse buffer view applied on top of it.
|
||||
|
||||
void PopulateData(size_t numBytes, uint8_t *bytes);
|
||||
void PopulateData(size_t numBytes, const uint8_t *bytes);
|
||||
void PatchData(unsigned int elementSize);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -785,12 +785,14 @@ inline void BufferView::Read(Value &obj, Asset &r) {
|
|||
}
|
||||
}
|
||||
|
||||
inline uint8_t *BufferView::GetPointer(size_t accOffset) {
|
||||
inline uint8_t *BufferView::GetPointerAndTailSize(size_t accOffset, size_t& outTailSize) {
|
||||
if (!buffer) {
|
||||
outTailSize = 0;
|
||||
return nullptr;
|
||||
}
|
||||
uint8_t *basePtr = buffer->GetPointer();
|
||||
uint8_t * const basePtr = buffer->GetPointer();
|
||||
if (!basePtr) {
|
||||
outTailSize = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -799,17 +801,25 @@ inline uint8_t *BufferView::GetPointer(size_t accOffset) {
|
|||
const size_t begin = buffer->EncodedRegion_Current->Offset;
|
||||
const size_t end = begin + buffer->EncodedRegion_Current->DecodedData_Length;
|
||||
if ((offset >= begin) && (offset < end)) {
|
||||
outTailSize = end - offset;
|
||||
return &buffer->EncodedRegion_Current->DecodedData[offset - begin];
|
||||
}
|
||||
}
|
||||
|
||||
if (offset >= buffer->byteLength)
|
||||
{
|
||||
outTailSize = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
outTailSize = buffer->byteLength - offset;
|
||||
return basePtr + offset;
|
||||
}
|
||||
|
||||
//
|
||||
// struct Accessor
|
||||
//
|
||||
inline void Accessor::Sparse::PopulateData(size_t numBytes, uint8_t *bytes) {
|
||||
inline void Accessor::Sparse::PopulateData(size_t numBytes, const uint8_t *bytes) {
|
||||
if (bytes) {
|
||||
data.assign(bytes, bytes + numBytes);
|
||||
} else {
|
||||
|
@ -818,11 +828,21 @@ inline void Accessor::Sparse::PopulateData(size_t numBytes, uint8_t *bytes) {
|
|||
}
|
||||
|
||||
inline void Accessor::Sparse::PatchData(unsigned int elementSize) {
|
||||
uint8_t *pIndices = indices->GetPointer(indicesByteOffset);
|
||||
size_t indicesTailDataSize;
|
||||
uint8_t *pIndices = indices->GetPointerAndTailSize(indicesByteOffset, indicesTailDataSize);
|
||||
const unsigned int indexSize = int(ComponentTypeSize(indicesType));
|
||||
uint8_t *indicesEnd = pIndices + count * indexSize;
|
||||
|
||||
uint8_t *pValues = values->GetPointer(valuesByteOffset);
|
||||
if ((uint64_t)indicesEnd > (uint64_t)pIndices + indicesTailDataSize) {
|
||||
throw DeadlyImportError("Invalid sparse accessor. Indices outside allocated memory.");
|
||||
}
|
||||
|
||||
size_t valuesTailDataSize;
|
||||
uint8_t* pValues = values->GetPointerAndTailSize(valuesByteOffset, valuesTailDataSize);
|
||||
|
||||
if (elementSize * count > valuesTailDataSize) {
|
||||
throw DeadlyImportError("Invalid sparse accessor. Indices outside allocated memory.");
|
||||
}
|
||||
while (pIndices != indicesEnd) {
|
||||
size_t offset;
|
||||
switch (indicesType) {
|
||||
|
@ -894,6 +914,9 @@ inline void Accessor::Read(Value &obj, Asset &r) {
|
|||
if (Value *indicesValue = FindObject(*sparseValue, "indices")) {
|
||||
//indices bufferView
|
||||
Value *indiceViewID = FindUInt(*indicesValue, "bufferView");
|
||||
if (!indiceViewID) {
|
||||
throw DeadlyImportError("A bufferView value is required, when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
|
||||
}
|
||||
sparse->indices = r.bufferViews.Retrieve(indiceViewID->GetUint());
|
||||
//indices byteOffset
|
||||
sparse->indicesByteOffset = MemberOrDefault(*indicesValue, "byteOffset", size_t(0));
|
||||
|
@ -909,6 +932,9 @@ inline void Accessor::Read(Value &obj, Asset &r) {
|
|||
if (Value *valuesValue = FindObject(*sparseValue, "values")) {
|
||||
//value bufferView
|
||||
Value *valueViewID = FindUInt(*valuesValue, "bufferView");
|
||||
if (!valueViewID) {
|
||||
throw DeadlyImportError("A bufferView value is required, when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
|
||||
}
|
||||
sparse->values = r.bufferViews.Retrieve(valueViewID->GetUint());
|
||||
//value byteOffset
|
||||
sparse->valuesByteOffset = MemberOrDefault(*valuesValue, "byteOffset", size_t(0));
|
||||
|
@ -918,8 +944,18 @@ inline void Accessor::Read(Value &obj, Asset &r) {
|
|||
|
||||
const unsigned int elementSize = GetElementSize();
|
||||
const size_t dataSize = count * elementSize;
|
||||
sparse->PopulateData(dataSize, bufferView ? bufferView->GetPointer(byteOffset) : nullptr);
|
||||
sparse->PatchData(elementSize);
|
||||
if (bufferView) {
|
||||
size_t bufferViewTailSize;
|
||||
const uint8_t* bufferViewPointer = bufferView->GetPointerAndTailSize(byteOffset, bufferViewTailSize);
|
||||
if (dataSize > bufferViewTailSize) {
|
||||
throw DeadlyImportError("Invalid buffer when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
|
||||
}
|
||||
sparse->PopulateData(dataSize, bufferViewPointer);
|
||||
}
|
||||
else {
|
||||
sparse->PopulateData(dataSize, nullptr);
|
||||
}
|
||||
sparse->PatchData(elementSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -912,6 +912,7 @@ void glTF2Exporter::ExportMaterials() {
|
|||
if (GetMatSpecular(mat, specular)) {
|
||||
mAsset->extensionsUsed.KHR_materials_specular = true;
|
||||
m->materialSpecular = Nullable<MaterialSpecular>(specular);
|
||||
GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE);
|
||||
}
|
||||
|
||||
MaterialSheen sheen;
|
||||
|
|
|
@ -1193,6 +1193,10 @@ ENDIF ()
|
|||
|
||||
TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp)
|
||||
|
||||
add_compile_options(
|
||||
"$<$<CONFIG:DEBUG>:-O0;-g3;-ggdb>"
|
||||
)
|
||||
|
||||
IF (ASSIMP_WARNINGS_AS_ERRORS)
|
||||
MESSAGE(STATUS "Treating all warnings as errors (for assimp library only)")
|
||||
IF (MSVC)
|
||||
|
|
|
@ -99,12 +99,12 @@ bool DefaultIOSystem::Exists(const char *pFile) const {
|
|||
return false;
|
||||
}
|
||||
#else
|
||||
FILE *file = ::fopen(pFile, "rb");
|
||||
if (!file) {
|
||||
struct stat statbuf;
|
||||
stat(pFile, &statbuf);
|
||||
// test for a regular file
|
||||
if (!S_ISREG(statbuf.st_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::fclose(file);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -116,6 +116,7 @@ IOStream *DefaultIOSystem::Open(const char *strFile, const char *strMode) {
|
|||
ai_assert(strFile != nullptr);
|
||||
ai_assert(strMode != nullptr);
|
||||
FILE *file;
|
||||
|
||||
#ifdef _WIN32
|
||||
std::wstring name = Utf8ToWide(strFile);
|
||||
if (name.empty()) {
|
||||
|
@ -126,6 +127,7 @@ IOStream *DefaultIOSystem::Open(const char *strFile, const char *strMode) {
|
|||
#else
|
||||
file = ::fopen(strFile, strMode);
|
||||
#endif
|
||||
|
||||
if (!file) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -64,10 +64,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
The list can be regenerated using the following:
|
||||
|
||||
cat <path/to/stb/stb_image.h> | fgrep STBIDEF | fgrep '(' | sed -E 's/\*|\(.+//g' | \
|
||||
awk '{print "#define " $(NF) " assimp_" $(NF) }' | sort | uniq"
|
||||
cat "path/to/stb/stb_image.h" | fgrep STBIDEF | fgrep '(' | sed -E 's/\*|\(.+//g' | \
|
||||
awk '{print "#define " $(NF) " assimp_" $(NF) }' | sort | uniq
|
||||
*/
|
||||
#define stbi_convert_iphone_png_to_rgb assimp_stbi_convert_iphone_png_to_rgb
|
||||
#define stbi_convert_iphone_png_to_rgb_thread assimp_stbi_convert_iphone_png_to_rgb_thread
|
||||
#define stbi_convert_wchar_to_utf8 assimp_stbi_convert_wchar_to_utf8
|
||||
#define stbi_failure_reason assimp_stbi_failure_reason
|
||||
#define stbi_hdr_to_ldr_gamma assimp_stbi_hdr_to_ldr_gamma
|
||||
|
@ -87,22 +88,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define stbi_is_hdr_from_memory assimp_stbi_is_hdr_from_memory
|
||||
#define stbi_ldr_to_hdr_gamma assimp_stbi_ldr_to_hdr_gamma
|
||||
#define stbi_ldr_to_hdr_scale assimp_stbi_ldr_to_hdr_scale
|
||||
#define stbi_load assimp_stbi_load
|
||||
#define stbi_load_16 assimp_stbi_load_16
|
||||
#define stbi_load_16_from_callbacks assimp_stbi_load_16_from_callbacks
|
||||
#define stbi_load_16_from_memory assimp_stbi_load_16_from_memory
|
||||
#define stbi_load assimp_stbi_load
|
||||
#define stbi_load_from_callbacks assimp_stbi_load_from_callbacks
|
||||
#define stbi_load_from_file assimp_stbi_load_from_file
|
||||
#define stbi_load_from_file_16 assimp_stbi_load_from_file_16
|
||||
#define stbi_load_from_memory assimp_stbi_load_from_memory
|
||||
#define stbi_load_gif_from_memory assimp_stbi_load_gif_from_memory
|
||||
#define stbi_loadf assimp_stbi_loadf
|
||||
#define stbi_loadf_from_callbacks assimp_stbi_loadf_from_callbacks
|
||||
#define stbi_loadf_from_file assimp_stbi_loadf_from_file
|
||||
#define stbi_loadf_from_memory assimp_stbi_loadf_from_memory
|
||||
#define stbi_load_from_callbacks assimp_stbi_load_from_callbacks
|
||||
#define stbi_load_from_file_16 assimp_stbi_load_from_file_16
|
||||
#define stbi_load_from_file assimp_stbi_load_from_file
|
||||
#define stbi_load_from_memory assimp_stbi_load_from_memory
|
||||
#define stbi_load_gif_from_memory assimp_stbi_load_gif_from_memory
|
||||
#define stbi_set_flip_vertically_on_load assimp_stbi_set_flip_vertically_on_load
|
||||
#define stbi_set_flip_vertically_on_load_thread assimp_stbi_set_flip_vertically_on_load_thread
|
||||
#define stbi_set_unpremultiply_on_load assimp_stbi_set_unpremultiply_on_load
|
||||
#define stbi_set_unpremultiply_on_load_thread assimp_stbi_set_unpremultiply_on_load_thread
|
||||
#define stbi_zlib_decode_buffer assimp_stbi_zlib_decode_buffer
|
||||
#define stbi_zlib_decode_malloc assimp_stbi_zlib_decode_malloc
|
||||
#define stbi_zlib_decode_malloc_guesssize assimp_stbi_zlib_decode_malloc_guesssize
|
||||
|
|
|
@ -89,22 +89,27 @@ using namespace Assimp;
|
|||
|
||||
namespace Assimp {
|
||||
|
||||
void ExportScenePbrt (
|
||||
const char* pFile,
|
||||
IOSystem* pIOSystem,
|
||||
const aiScene* pScene,
|
||||
const ExportProperties* /*pProperties*/
|
||||
){
|
||||
void ExportScenePbrt(const char *pFile, IOSystem *pIOSystem, const aiScene *pScene,
|
||||
const ExportProperties *) {
|
||||
std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
|
||||
std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
|
||||
|
||||
path = path + file + ".pbrt";
|
||||
// initialize the exporter
|
||||
PbrtExporter exporter(pScene, pIOSystem, path, file);
|
||||
}
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
// Constructor
|
||||
static void create_embedded_textures_folder(const aiScene *scene, IOSystem *pIOSystem) {
|
||||
if (scene->mNumTextures > 0) {
|
||||
if (!pIOSystem->Exists("textures")) {
|
||||
if (!pIOSystem->CreateDirectory("textures")) {
|
||||
throw DeadlyExportError("Could not create textures/ directory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PbrtExporter::PbrtExporter(
|
||||
const aiScene *pScene, IOSystem *pIOSystem,
|
||||
const std::string &path, const std::string &file) :
|
||||
|
@ -127,10 +132,10 @@ PbrtExporter::PbrtExporter(
|
|||
0.f, 0.f, 1.f, 0.f, //
|
||||
0.f, 0.f, 0.f, 1.f //
|
||||
) * mRootTransform;
|
||||
|
||||
// Export embedded textures.
|
||||
if (mScene->mNumTextures > 0)
|
||||
if (!mIOSystem->CreateDirectory("textures"))
|
||||
throw DeadlyExportError("Could not create textures/ directory.");
|
||||
create_embedded_textures_folder(mScene, mIOSystem);
|
||||
|
||||
for (unsigned int i = 0; i < mScene->mNumTextures; ++i) {
|
||||
aiTexture* tex = mScene->mTextures[i];
|
||||
std::string fn = CleanTextureFilename(tex->mFilename, false);
|
||||
|
@ -176,9 +181,6 @@ PbrtExporter::PbrtExporter(
|
|||
outfile->Write(mOutput.str().c_str(), mOutput.str().length(), 1);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
PbrtExporter::~PbrtExporter() = default;
|
||||
|
||||
void PbrtExporter::WriteMetaData() {
|
||||
mOutput << "#############################\n";
|
||||
mOutput << "# Scene metadata:\n";
|
||||
|
|
|
@ -70,15 +70,33 @@ class ExportProperties;
|
|||
// ---------------------------------------------------------------------
|
||||
/** Helper class to export a given scene to a Pbrt file. */
|
||||
// ---------------------------------------------------------------------
|
||||
class PbrtExporter
|
||||
{
|
||||
class PbrtExporter {
|
||||
public:
|
||||
/// Constructor for a specific scene to export
|
||||
PbrtExporter(const aiScene *pScene, IOSystem *pIOSystem,
|
||||
const std::string &path, const std::string &file);
|
||||
|
||||
/// Destructor
|
||||
virtual ~PbrtExporter();
|
||||
virtual ~PbrtExporter() = default;
|
||||
|
||||
private:
|
||||
aiMatrix4x4 GetNodeTransform(const aiString &name) const;
|
||||
static std::string TransformAsString(const aiMatrix4x4 &m);
|
||||
static std::string RemoveSuffix(std::string filename);
|
||||
std::string CleanTextureFilename(const aiString &f, bool rewriteExtension = true) const;
|
||||
void WriteMetaData();
|
||||
void WriteWorldDefinition();
|
||||
void WriteCameras();
|
||||
void WriteCamera(int i);
|
||||
void WriteLights();
|
||||
void WriteTextures();
|
||||
static bool TextureHasAlphaMask(const std::string &filename);
|
||||
void WriteMaterials();
|
||||
void WriteMaterial(int i);
|
||||
void WriteMesh(aiMesh *mesh);
|
||||
void WriteInstanceDefinition(int i);
|
||||
void WriteGeometricObjects(aiNode *node, aiMatrix4x4 parentTransform,
|
||||
std::map<int, int> &meshUses);
|
||||
|
||||
private:
|
||||
// the scene to export
|
||||
|
@ -96,39 +114,11 @@ private:
|
|||
/// Name of the file (without extension) where the scene will be exported
|
||||
const std::string mFile;
|
||||
|
||||
private:
|
||||
// A private set to keep track of which textures have been declared
|
||||
std::set<std::string> mTextureSet;
|
||||
|
||||
// Transform to apply to the root node and all root objects such as cameras, lights, etc.
|
||||
aiMatrix4x4 mRootTransform;
|
||||
|
||||
aiMatrix4x4 GetNodeTransform(const aiString& name) const;
|
||||
static std::string TransformAsString(const aiMatrix4x4& m);
|
||||
|
||||
static std::string RemoveSuffix(std::string filename);
|
||||
std::string CleanTextureFilename(const aiString &f, bool rewriteExtension = true) const;
|
||||
|
||||
void WriteMetaData();
|
||||
|
||||
void WriteWorldDefinition();
|
||||
|
||||
void WriteCameras();
|
||||
void WriteCamera(int i);
|
||||
|
||||
void WriteLights();
|
||||
|
||||
void WriteTextures();
|
||||
static bool TextureHasAlphaMask(const std::string &filename);
|
||||
|
||||
void WriteMaterials();
|
||||
void WriteMaterial(int i);
|
||||
|
||||
void WriteMesh(aiMesh* mesh);
|
||||
|
||||
void WriteInstanceDefinition(int i);
|
||||
void WriteGeometricObjects(aiNode* node, aiMatrix4x4 parentTransform,
|
||||
std::map<int, int> &meshUses);
|
||||
};
|
||||
|
||||
} // namespace Assimp
|
||||
|
|
|
@ -52,8 +52,9 @@ namespace Assimp {
|
|||
// -------------------------------------------------------------------------------
|
||||
void ConvertListToStrings(const std::string &in, std::list<std::string> &out) {
|
||||
const char *s = in.c_str();
|
||||
const char *end = in.c_str() + in.size();
|
||||
while (*s) {
|
||||
SkipSpacesAndLineEnd(&s);
|
||||
SkipSpacesAndLineEnd(&s, end);
|
||||
if (*s == '\'') {
|
||||
const char *base = ++s;
|
||||
while (*s != '\'') {
|
||||
|
@ -66,7 +67,7 @@ void ConvertListToStrings(const std::string &in, std::list<std::string> &out) {
|
|||
out.emplace_back(base, (size_t)(s - base));
|
||||
++s;
|
||||
} else {
|
||||
out.push_back(GetNextToken(s));
|
||||
out.push_back(GetNextToken(s, end));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,124 +75,129 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) {
|
|||
ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess begin");
|
||||
|
||||
unsigned int redundantRemoved = 0, unreferencedRemoved = 0;
|
||||
if (pScene->mNumMaterials) {
|
||||
// Find out which materials are referenced by meshes
|
||||
std::vector<bool> abReferenced(pScene->mNumMaterials,false);
|
||||
for (unsigned int i = 0;i < pScene->mNumMeshes;++i)
|
||||
abReferenced[pScene->mMeshes[i]->mMaterialIndex] = true;
|
||||
if (pScene->mNumMaterials == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find out which materials are referenced by meshes
|
||||
std::vector<bool> abReferenced(pScene->mNumMaterials,false);
|
||||
for (unsigned int i = 0;i < pScene->mNumMeshes;++i)
|
||||
abReferenced[pScene->mMeshes[i]->mMaterialIndex] = true;
|
||||
|
||||
// If a list of materials to be excluded was given, match the list with
|
||||
// our imported materials and 'salt' all positive matches to ensure that
|
||||
// we get unique hashes later.
|
||||
if (mConfigFixedMaterials.length()) {
|
||||
// If a list of materials to be excluded was given, match the list with
|
||||
// our imported materials and 'salt' all positive matches to ensure that
|
||||
// we get unique hashes later.
|
||||
if (mConfigFixedMaterials.length()) {
|
||||
|
||||
std::list<std::string> strings;
|
||||
ConvertListToStrings(mConfigFixedMaterials,strings);
|
||||
std::list<std::string> strings;
|
||||
ConvertListToStrings(mConfigFixedMaterials,strings);
|
||||
|
||||
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
|
||||
aiMaterial* mat = pScene->mMaterials[i];
|
||||
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
|
||||
aiMaterial* mat = pScene->mMaterials[i];
|
||||
|
||||
aiString name;
|
||||
mat->Get(AI_MATKEY_NAME,name);
|
||||
aiString name;
|
||||
mat->Get(AI_MATKEY_NAME,name);
|
||||
|
||||
if (name.length) {
|
||||
std::list<std::string>::const_iterator it = std::find(strings.begin(), strings.end(), name.data);
|
||||
if (it != strings.end()) {
|
||||
if (name.length) {
|
||||
std::list<std::string>::const_iterator it = std::find(strings.begin(), strings.end(), name.data);
|
||||
if (it != strings.end()) {
|
||||
|
||||
// Our brilliant 'salt': A single material property with ~ as first
|
||||
// character to mark it as internal and temporary.
|
||||
const int dummy = 1;
|
||||
((aiMaterial*)mat)->AddProperty(&dummy,1,"~RRM.UniqueMaterial",0,0);
|
||||
// Our brilliant 'salt': A single material property with ~ as first
|
||||
// character to mark it as internal and temporary.
|
||||
const int dummy = 1;
|
||||
((aiMaterial*)mat)->AddProperty(&dummy,1,"~RRM.UniqueMaterial",0,0);
|
||||
|
||||
// Keep this material even if no mesh references it
|
||||
abReferenced[i] = true;
|
||||
ASSIMP_LOG_VERBOSE_DEBUG( "Found positive match in exclusion list: \'", name.data, "\'");
|
||||
}
|
||||
// Keep this material even if no mesh references it
|
||||
abReferenced[i] = true;
|
||||
ASSIMP_LOG_VERBOSE_DEBUG( "Found positive match in exclusion list: \'", name.data, "\'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: re-implement this algorithm to work in-place
|
||||
unsigned int *aiMappingTable = new unsigned int[pScene->mNumMaterials];
|
||||
for ( unsigned int i=0; i<pScene->mNumMaterials; i++ ) {
|
||||
aiMappingTable[ i ] = 0;
|
||||
// TODO: re-implement this algorithm to work in-place
|
||||
unsigned int *aiMappingTable = new unsigned int[pScene->mNumMaterials];
|
||||
for ( unsigned int i=0; i<pScene->mNumMaterials; i++ ) {
|
||||
aiMappingTable[ i ] = 0;
|
||||
}
|
||||
unsigned int iNewNum = 0;
|
||||
|
||||
// Iterate through all materials and calculate a hash for them
|
||||
// store all hashes in a list and so a quick search whether
|
||||
// we do already have a specific hash. This allows us to
|
||||
// determine which materials are identical.
|
||||
uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];;
|
||||
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
|
||||
// No mesh is referencing this material, remove it.
|
||||
if (!abReferenced[i]) {
|
||||
++unreferencedRemoved;
|
||||
delete pScene->mMaterials[i];
|
||||
pScene->mMaterials[i] = nullptr;
|
||||
continue;
|
||||
}
|
||||
unsigned int iNewNum = 0;
|
||||
|
||||
// Iterate through all materials and calculate a hash for them
|
||||
// store all hashes in a list and so a quick search whether
|
||||
// we do already have a specific hash. This allows us to
|
||||
// determine which materials are identical.
|
||||
uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];;
|
||||
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
|
||||
// No mesh is referencing this material, remove it.
|
||||
if (!abReferenced[i]) {
|
||||
++unreferencedRemoved;
|
||||
// Check all previously mapped materials for a matching hash.
|
||||
// On a match we can delete this material and just make it ref to the same index.
|
||||
uint32_t me = aiHashes[i] = ComputeMaterialHash(pScene->mMaterials[i]);
|
||||
for (unsigned int a = 0; a < i;++a) {
|
||||
if (abReferenced[a] && me == aiHashes[a]) {
|
||||
++redundantRemoved;
|
||||
me = 0;
|
||||
aiMappingTable[i] = aiMappingTable[a];
|
||||
delete pScene->mMaterials[i];
|
||||
pScene->mMaterials[i] = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// This is a new material that is referenced, add to the map.
|
||||
if (me) {
|
||||
aiMappingTable[i] = iNewNum++;
|
||||
}
|
||||
}
|
||||
// If the new material count differs from the original,
|
||||
// we need to rebuild the material list and remap mesh material indexes.
|
||||
if (iNewNum < 1) {
|
||||
//throw DeadlyImportError("No materials remaining");
|
||||
return;
|
||||
}
|
||||
if (iNewNum != pScene->mNumMaterials) {
|
||||
ai_assert(iNewNum > 0);
|
||||
aiMaterial** ppcMaterials = new aiMaterial*[iNewNum];
|
||||
::memset(ppcMaterials,0,sizeof(void*)*iNewNum);
|
||||
for (unsigned int p = 0; p < pScene->mNumMaterials;++p)
|
||||
{
|
||||
// if the material is not referenced ... remove it
|
||||
if (!abReferenced[p]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check all previously mapped materials for a matching hash.
|
||||
// On a match we can delete this material and just make it ref to the same index.
|
||||
uint32_t me = aiHashes[i] = ComputeMaterialHash(pScene->mMaterials[i]);
|
||||
for (unsigned int a = 0; a < i;++a) {
|
||||
if (abReferenced[a] && me == aiHashes[a]) {
|
||||
++redundantRemoved;
|
||||
me = 0;
|
||||
aiMappingTable[i] = aiMappingTable[a];
|
||||
delete pScene->mMaterials[i];
|
||||
pScene->mMaterials[i] = nullptr;
|
||||
break;
|
||||
// generate new names for modified materials that had no names
|
||||
const unsigned int idx = aiMappingTable[p];
|
||||
if (ppcMaterials[idx]) {
|
||||
aiString sz;
|
||||
if( ppcMaterials[idx]->Get(AI_MATKEY_NAME, sz) != AI_SUCCESS ) {
|
||||
sz.length = ::ai_snprintf(sz.data,MAXLEN,"JoinedMaterial_#%u",p);
|
||||
((aiMaterial*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME);
|
||||
}
|
||||
}
|
||||
// This is a new material that is referenced, add to the map.
|
||||
if (me) {
|
||||
aiMappingTable[i] = iNewNum++;
|
||||
} else {
|
||||
ppcMaterials[idx] = pScene->mMaterials[p];
|
||||
}
|
||||
}
|
||||
// If the new material count differs from the original,
|
||||
// we need to rebuild the material list and remap mesh material indexes.
|
||||
if(iNewNum < 1)
|
||||
throw DeadlyImportError("No materials remaining");
|
||||
if (iNewNum != pScene->mNumMaterials) {
|
||||
ai_assert(iNewNum > 0);
|
||||
aiMaterial** ppcMaterials = new aiMaterial*[iNewNum];
|
||||
::memset(ppcMaterials,0,sizeof(void*)*iNewNum);
|
||||
for (unsigned int p = 0; p < pScene->mNumMaterials;++p)
|
||||
{
|
||||
// if the material is not referenced ... remove it
|
||||
if (!abReferenced[p]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// generate new names for modified materials that had no names
|
||||
const unsigned int idx = aiMappingTable[p];
|
||||
if (ppcMaterials[idx]) {
|
||||
aiString sz;
|
||||
if( ppcMaterials[idx]->Get(AI_MATKEY_NAME, sz) != AI_SUCCESS ) {
|
||||
sz.length = ::ai_snprintf(sz.data,MAXLEN,"JoinedMaterial_#%u",p);
|
||||
((aiMaterial*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME);
|
||||
}
|
||||
} else {
|
||||
ppcMaterials[idx] = pScene->mMaterials[p];
|
||||
}
|
||||
}
|
||||
// update all material indices
|
||||
for (unsigned int p = 0; p < pScene->mNumMeshes;++p) {
|
||||
aiMesh* mesh = pScene->mMeshes[p];
|
||||
ai_assert(nullptr != mesh);
|
||||
mesh->mMaterialIndex = aiMappingTable[mesh->mMaterialIndex];
|
||||
}
|
||||
// delete the old material list
|
||||
delete[] pScene->mMaterials;
|
||||
pScene->mMaterials = ppcMaterials;
|
||||
pScene->mNumMaterials = iNewNum;
|
||||
// update all material indices
|
||||
for (unsigned int p = 0; p < pScene->mNumMeshes;++p) {
|
||||
aiMesh* mesh = pScene->mMeshes[p];
|
||||
ai_assert(nullptr != mesh);
|
||||
mesh->mMaterialIndex = aiMappingTable[mesh->mMaterialIndex];
|
||||
}
|
||||
// delete temporary storage
|
||||
delete[] aiHashes;
|
||||
delete[] aiMappingTable;
|
||||
// delete the old material list
|
||||
delete[] pScene->mMaterials;
|
||||
pScene->mMaterials = ppcMaterials;
|
||||
pScene->mNumMaterials = iNewNum;
|
||||
}
|
||||
// delete temporary storage
|
||||
delete[] aiHashes;
|
||||
delete[] aiMappingTable;
|
||||
|
||||
if (redundantRemoved == 0 && unreferencedRemoved == 0) {
|
||||
ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess finished ");
|
||||
} else {
|
||||
|
|
|
@ -111,6 +111,9 @@ void Sweep::EdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
|
|||
|
||||
void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point)
|
||||
{
|
||||
if (triangle == nullptr)
|
||||
return;
|
||||
|
||||
if (IsEdgeSideOfTriangle(*triangle, ep, eq)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ __Importers__:
|
|||
- ASE
|
||||
- ASK
|
||||
- B3D
|
||||
- [BLEND](https://en.wikipedia.org/wiki/.blend_(file_format))
|
||||
- [BVH](https://en.wikipedia.org/wiki/Biovision_Hierarchy)
|
||||
- CSM
|
||||
- COB
|
||||
|
@ -66,6 +65,9 @@ __Importers__:
|
|||
- XGL
|
||||
- ZGL
|
||||
|
||||
Note: support for [BLEND](https://en.wikipedia.org/wiki/.blend_(file_format)) is deprecated.
|
||||
It is too time-consuming to maintain an undocumented format which contains so much more than we need.
|
||||
|
||||
Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
|
||||
|
||||
- [C4D](https://en.wikipedia.org/wiki/Cinema_4D) (https://github.com/assimp/assimp/wiki/Cinema4D-&-Melange) IMporting geometry + node hierarchy are currently supported
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
* Create an instance of your derived class and assign it to an
|
||||
* #Assimp::Importer instance by calling Importer::SetIOHandler().
|
||||
*/
|
||||
IOSystem() AI_NO_EXCEPT;
|
||||
IOSystem() AI_NO_EXCEPT = default;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Virtual destructor.
|
||||
|
@ -105,7 +105,7 @@ public:
|
|||
* It is safe to be called from within DLL Assimp, we're constructed
|
||||
* on Assimp's heap.
|
||||
*/
|
||||
virtual ~IOSystem();
|
||||
virtual ~IOSystem() = default;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief For backward compatibility
|
||||
|
@ -236,12 +236,6 @@ private:
|
|||
std::vector<std::string> m_pathStack;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE IOSystem::IOSystem() AI_NO_EXCEPT = default;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE IOSystem::~IOSystem() = default;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// For compatibility, the interface of some functions taking a std::string was
|
||||
// changed to const char* to avoid crashes between binary incompatible STL
|
||||
|
|
|
@ -110,6 +110,8 @@ public:
|
|||
|
||||
std::string operator* () const;
|
||||
|
||||
const char *getEnd() const;
|
||||
|
||||
// -----------------------------------------
|
||||
/** boolean context */
|
||||
operator bool() const;
|
||||
|
@ -139,17 +141,21 @@ public:
|
|||
private:
|
||||
line_idx mIdx;
|
||||
std::string mCur;
|
||||
const char *mEnd;
|
||||
StreamReaderLE& mStream;
|
||||
bool mSwallow, mSkip_empty_lines, mTrim;
|
||||
};
|
||||
|
||||
AI_FORCE_INLINE LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim ) :
|
||||
mIdx(0),
|
||||
mCur(),
|
||||
mEnd(nullptr),
|
||||
mStream(stream),
|
||||
mSwallow(),
|
||||
mSkip_empty_lines(skip_empty_lines),
|
||||
mTrim(trim) {
|
||||
mCur.reserve(1024);
|
||||
mEnd = mCur.c_str() + 1024;
|
||||
operator++();
|
||||
mIdx = 0;
|
||||
}
|
||||
|
@ -203,14 +209,14 @@ AI_FORCE_INLINE LineSplitter &LineSplitter::operator++(int) {
|
|||
AI_FORCE_INLINE const char *LineSplitter::operator[] (size_t idx) const {
|
||||
const char* s = operator->()->c_str();
|
||||
|
||||
SkipSpaces(&s);
|
||||
SkipSpaces(&s, mEnd);
|
||||
for (size_t i = 0; i < idx; ++i) {
|
||||
for (; !IsSpace(*s); ++s) {
|
||||
if (IsLineEnd(*s)) {
|
||||
throw std::range_error("Token index out of range, EOL reached");
|
||||
}
|
||||
}
|
||||
SkipSpaces(&s);
|
||||
SkipSpaces(&s, mEnd);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
@ -219,7 +225,7 @@ template <size_t N>
|
|||
AI_FORCE_INLINE void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
|
||||
const char* s = operator->()->c_str();
|
||||
|
||||
SkipSpaces(&s);
|
||||
SkipSpaces(&s, mEnd);
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
if (IsLineEnd(*s)) {
|
||||
throw std::range_error("Token count out of range, EOL reached");
|
||||
|
@ -227,7 +233,7 @@ AI_FORCE_INLINE void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
|
|||
tokens[i] = s;
|
||||
|
||||
for (; *s && !IsSpace(*s); ++s);
|
||||
SkipSpaces(&s);
|
||||
SkipSpaces(&s, mEnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,6 +245,10 @@ AI_FORCE_INLINE std::string LineSplitter::operator* () const {
|
|||
return mCur;
|
||||
}
|
||||
|
||||
AI_FORCE_INLINE const char* LineSplitter::getEnd() const {
|
||||
return mEnd;
|
||||
}
|
||||
|
||||
AI_FORCE_INLINE LineSplitter::operator bool() const {
|
||||
return mStream.GetRemainingSize() > 0;
|
||||
}
|
||||
|
|
|
@ -102,8 +102,8 @@ AI_FORCE_INLINE bool IsSpaceOrNewLine(char_t in) {
|
|||
|
||||
// ---------------------------------------------------------------------------------
|
||||
template <class char_t>
|
||||
AI_FORCE_INLINE bool SkipSpaces(const char_t *in, const char_t **out) {
|
||||
while (*in == (char_t)' ' || *in == (char_t)'\t') {
|
||||
AI_FORCE_INLINE bool SkipSpaces(const char_t *in, const char_t **out, const char_t *end) {
|
||||
while ((*in == (char_t)' ' || *in == (char_t)'\t') && in != end) {
|
||||
++in;
|
||||
}
|
||||
*out = in;
|
||||
|
@ -112,19 +112,19 @@ AI_FORCE_INLINE bool SkipSpaces(const char_t *in, const char_t **out) {
|
|||
|
||||
// ---------------------------------------------------------------------------------
|
||||
template <class char_t>
|
||||
AI_FORCE_INLINE bool SkipSpaces(const char_t **inout) {
|
||||
return SkipSpaces<char_t>(*inout, inout);
|
||||
AI_FORCE_INLINE bool SkipSpaces(const char_t **inout, const char_t *end) {
|
||||
return SkipSpaces<char_t>(*inout, inout, end);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
template <class char_t>
|
||||
AI_FORCE_INLINE bool SkipLine(const char_t *in, const char_t **out) {
|
||||
while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0') {
|
||||
AI_FORCE_INLINE bool SkipLine(const char_t *in, const char_t **out, const char_t *end) {
|
||||
while ((*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0') && in != end) {
|
||||
++in;
|
||||
}
|
||||
|
||||
// files are opened in binary mode. Ergo there are both NL and CR
|
||||
while (*in == (char_t)'\r' || *in == (char_t)'\n') {
|
||||
while ((*in == (char_t)'\r' || *in == (char_t)'\n') && in != end) {
|
||||
++in;
|
||||
}
|
||||
*out = in;
|
||||
|
@ -133,14 +133,14 @@ AI_FORCE_INLINE bool SkipLine(const char_t *in, const char_t **out) {
|
|||
|
||||
// ---------------------------------------------------------------------------------
|
||||
template <class char_t>
|
||||
AI_FORCE_INLINE bool SkipLine(const char_t **inout) {
|
||||
return SkipLine<char_t>(*inout, inout);
|
||||
AI_FORCE_INLINE bool SkipLine(const char_t **inout, const char_t *end) {
|
||||
return SkipLine<char_t>(*inout, inout, end);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
template <class char_t>
|
||||
AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t *in, const char_t **out) {
|
||||
while (*in == (char_t)' ' || *in == (char_t)'\t' || *in == (char_t)'\r' || *in == (char_t)'\n') {
|
||||
AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t *in, const char_t **out, const char_t *end) {
|
||||
while ((*in == (char_t)' ' || *in == (char_t)'\t' || *in == (char_t)'\r' || *in == (char_t)'\n') && in != end) {
|
||||
++in;
|
||||
}
|
||||
*out = in;
|
||||
|
@ -149,8 +149,8 @@ AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t *in, const char_t **out)
|
|||
|
||||
// ---------------------------------------------------------------------------------
|
||||
template <class char_t>
|
||||
AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t **inout) {
|
||||
return SkipSpacesAndLineEnd<char_t>(*inout, inout);
|
||||
AI_FORCE_INLINE bool SkipSpacesAndLineEnd(const char_t **inout, const char_t *end) {
|
||||
return SkipSpacesAndLineEnd<char_t>(*inout, inout, end);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
@ -210,16 +210,16 @@ AI_FORCE_INLINE bool TokenMatchI(const char *&in, const char *token, unsigned in
|
|||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE void SkipToken(const char *&in) {
|
||||
SkipSpaces(&in);
|
||||
AI_FORCE_INLINE void SkipToken(const char *&in, const char *end) {
|
||||
SkipSpaces(&in, end);
|
||||
while (!IsSpaceOrNewLine(*in)) {
|
||||
++in;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE std::string GetNextToken(const char *&in) {
|
||||
SkipSpacesAndLineEnd(&in);
|
||||
AI_FORCE_INLINE std::string GetNextToken(const char *&in, const char *end) {
|
||||
SkipSpacesAndLineEnd(&in, end);
|
||||
const char *cur = in;
|
||||
while (!IsSpaceOrNewLine(*in)) {
|
||||
++in;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -523,6 +523,23 @@ struct aiMemoryInfo {
|
|||
unsigned int total;
|
||||
}; // !struct aiMemoryInfo
|
||||
|
||||
/**
|
||||
* @brief Type to store a in-memory data buffer.
|
||||
*/
|
||||
struct aiBuffer {
|
||||
const char *data; ///< Begin poiner
|
||||
const char *end; ///< End pointer
|
||||
|
||||
#ifdef __cplusplus
|
||||
/// @brief The class constructor.
|
||||
aiBuffer() :
|
||||
data(nullptr), end(nullptr) {}
|
||||
|
||||
/// @brief The class destructor.
|
||||
~aiBuffer() = default;
|
||||
#endif //! __cplusplus
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //! __cplusplus
|
||||
|
|
|
@ -165,6 +165,7 @@ SET( IMPORTERS
|
|||
unit/ImportExport/MDL/utMDLImporter_HL1_Nodes.cpp
|
||||
unit/ImportExport/RAW/utRAWImportExport.cpp
|
||||
unit/ImportExport/Terragen/utTerragenImportExport.cpp
|
||||
unit/ImportExport/Pbrt/utPbrtImportExport.cpp
|
||||
)
|
||||
|
||||
SET( MATERIAL
|
||||
|
|
|
@ -0,0 +1,535 @@
|
|||
AC3Db
|
||||
MATERIAL "ac3dmat1" rgb 1.00 1.00 1.00 amb 0.20 0.20 0.20 emis 0.00 0.00 0.00 spec 0.20 0.20 0.20 shi 128 trans 0
|
||||
OBJECT world
|
||||
kids 2
|
||||
OBJECT light
|
||||
name "light"
|
||||
loc 0.000424567 -0.0127304 0
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "sphere"
|
||||
texture "earthSpherical.jpg" base
|
||||
texture empty_texture_no_mapping tiled
|
||||
texture empty_texture_no_mapping skids
|
||||
texture empty_texture_no_mapping shad
|
||||
numvert 167
|
||||
-0.051576 -0.062833 0.063067 0.224114 -0.961969 0.156168
|
||||
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
|
||||
-0.049587 -0.062833 0.055841 0.270337 -0.962554 0.020215
|
||||
-0.057009 -0.062833 0.068357 0.117917 -0.961035 0.250013
|
||||
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
|
||||
-0.064432 -0.062833 0.070294 -0.019618 -0.960685 0.276946
|
||||
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
|
||||
-0.071854 -0.062833 0.068357 -0.151973 -0.961267 0.229935
|
||||
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
|
||||
-0.077288 -0.062833 0.063067 -0.243865 -0.962202 0.121235
|
||||
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
|
||||
-0.079277 -0.062833 0.055841 -0.270337 -0.962554 -0.020215
|
||||
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
|
||||
-0.077288 -0.062833 0.048614 -0.224114 -0.961969 -0.156168
|
||||
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
|
||||
-0.071854 -0.062833 0.043324 -0.117917 -0.961035 -0.250013
|
||||
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
|
||||
-0.064432 -0.062833 0.041388 0.019618 -0.960685 -0.276946
|
||||
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
|
||||
-0.057009 -0.062833 0.043324 0.151973 -0.961267 -0.229935
|
||||
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
|
||||
-0.049587 0.042114 0.055841 0.270334 0.962554 -0.020215
|
||||
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
|
||||
-0.051576 0.042114 0.063067 0.243863 0.962202 0.121233
|
||||
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
|
||||
-0.057009 0.042114 0.068357 0.151972 0.961268 0.229933
|
||||
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
|
||||
-0.064432 0.042114 0.070294 0.019618 0.960686 0.276944
|
||||
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
|
||||
-0.071854 0.042114 0.068357 -0.117915 0.961036 0.250011
|
||||
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
|
||||
-0.077288 0.042114 0.063067 -0.224112 0.961970 0.156167
|
||||
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
|
||||
-0.079277 0.042114 0.055841 -0.270334 0.962554 0.020215
|
||||
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
|
||||
-0.077288 0.042114 0.048614 -0.243863 0.962202 -0.121233
|
||||
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
|
||||
-0.071854 0.042114 0.043324 -0.151972 0.961268 -0.229933
|
||||
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
|
||||
-0.064432 0.042114 0.041388 -0.019618 0.960686 -0.276944
|
||||
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
|
||||
-0.057009 0.042114 0.043324 0.117916 0.961036 -0.250011
|
||||
-0.035753 -0.057406 0.055841 0.479979 -0.877222 0.010123
|
||||
-0.049587 -0.062833 0.055841 0.270337 -0.962554 0.020215
|
||||
-0.051576 -0.062833 0.048614 0.243865 -0.962202 -0.121234
|
||||
-0.039596 -0.057406 0.041881 0.420061 -0.875943 -0.237219
|
||||
-0.023874 -0.048773 0.055841 0.687850 -0.725803 0.008451
|
||||
-0.029308 -0.048773 0.036098 0.598218 -0.723534 -0.344433
|
||||
-0.014759 -0.037522 0.055841 0.853991 -0.520251 0.006112
|
||||
-0.021414 -0.037522 0.031661 0.739473 -0.517639 -0.430382
|
||||
-0.009029 -0.024420 0.055841 0.962274 -0.272063 0.003217
|
||||
-0.016452 -0.024420 0.028872 0.830450 -0.270187 -0.487187
|
||||
-0.007075 -0.010360 0.055841 1.000000 -0.000000 0.000000
|
||||
-0.014759 -0.010360 0.027920 0.860926 0.000265 -0.508731
|
||||
-0.009029 0.003701 0.055841 0.962274 0.272063 -0.003217
|
||||
-0.016452 0.003701 0.028872 0.827147 0.270625 -0.492534
|
||||
-0.014759 0.016803 0.055841 0.853991 0.520251 -0.006112
|
||||
-0.021414 0.016803 0.031661 0.733264 0.517855 -0.440625
|
||||
-0.023874 0.028054 0.055841 0.687850 0.725803 -0.008451
|
||||
-0.029308 0.028054 0.036098 0.589753 0.723523 -0.358756
|
||||
-0.035753 0.036687 0.055841 0.479979 0.877222 -0.010123
|
||||
-0.039596 0.036687 0.041881 0.410061 0.875812 -0.254565
|
||||
-0.049587 0.042114 0.055841 0.270334 0.962554 -0.020215
|
||||
-0.051576 0.042114 0.048614 0.224112 0.961970 -0.156167
|
||||
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
|
||||
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
|
||||
-0.039596 -0.057406 0.069801 0.410061 -0.875812 0.254565
|
||||
-0.035753 -0.057406 0.055841 0.479979 -0.877222 0.010123
|
||||
-0.050092 -0.057406 0.080021 0.230454 -0.873143 0.429549
|
||||
-0.064432 -0.057406 0.083761 -0.009683 -0.871880 0.489625
|
||||
-0.078771 -0.057406 0.080021 -0.247407 -0.873270 0.419748
|
||||
-0.089268 -0.057406 0.069801 -0.420061 -0.875942 0.237220
|
||||
-0.093110 -0.057406 0.055841 -0.479980 -0.877221 -0.010124
|
||||
-0.089268 -0.057406 0.041881 -0.410062 -0.875812 -0.254565
|
||||
-0.078771 -0.057406 0.031661 -0.230453 -0.873143 -0.429549
|
||||
-0.064432 -0.057406 0.027920 0.009684 -0.871880 -0.489625
|
||||
-0.050092 -0.057406 0.031661 0.247407 -0.873271 -0.419748
|
||||
-0.029308 -0.048773 0.075583 0.589753 -0.723523 0.358757
|
||||
-0.023874 -0.048773 0.055841 0.687850 -0.725803 0.008451
|
||||
-0.044153 -0.048773 0.090036 0.333957 -0.719029 0.609483
|
||||
-0.064432 -0.048773 0.095326 -0.007940 -0.716811 0.697222
|
||||
-0.084710 -0.048773 0.090036 -0.348006 -0.719035 0.601564
|
||||
-0.099555 -0.048773 0.075583 -0.598218 -0.723534 0.344434
|
||||
-0.104989 -0.048773 0.055841 -0.687850 -0.725804 -0.008451
|
||||
-0.099555 -0.048773 0.036098 -0.589753 -0.723523 -0.358757
|
||||
-0.084710 -0.048773 0.021645 -0.333958 -0.719029 -0.609483
|
||||
-0.064432 -0.048773 0.016355 0.007940 -0.716811 -0.697222
|
||||
-0.044153 -0.048773 0.021645 0.348006 -0.719035 -0.601565
|
||||
-0.021414 -0.037522 0.080021 0.733263 -0.517855 0.440625
|
||||
-0.014759 -0.037522 0.055841 0.853991 -0.520251 0.006112
|
||||
-0.039596 -0.037522 0.097721 0.416448 -0.512938 0.750643
|
||||
-0.064432 -0.037522 0.104200 -0.005639 -0.510417 0.859908
|
||||
-0.089268 -0.037522 0.097721 -0.426533 -0.512723 0.745107
|
||||
-0.107449 -0.037522 0.080021 -0.739473 -0.517640 0.430382
|
||||
-0.114104 -0.037522 0.055841 -0.853991 -0.520252 -0.006112
|
||||
-0.107449 -0.037522 0.031661 -0.733262 -0.517857 -0.440626
|
||||
-0.089268 -0.037522 0.013960 -0.416448 -0.512938 -0.750643
|
||||
-0.064432 -0.037522 0.007481 0.005639 -0.510417 -0.859908
|
||||
-0.039595 -0.037522 0.013960 0.426534 -0.512723 -0.745107
|
||||
-0.016452 -0.024420 0.082810 0.827147 -0.270625 0.492534
|
||||
-0.009029 -0.024420 0.055841 0.962274 -0.272063 0.003217
|
||||
-0.036730 -0.024420 0.102553 0.470709 -0.267377 0.840799
|
||||
-0.064432 -0.024420 0.109779 -0.002929 -0.265584 0.964083
|
||||
-0.092133 -0.024420 0.102553 -0.475987 -0.266955 0.837957
|
||||
-0.112412 -0.024420 0.082810 -0.830450 -0.270188 0.487187
|
||||
-0.119834 -0.024420 0.055841 -0.962274 -0.272062 -0.003217
|
||||
-0.112412 -0.024420 0.028872 -0.827148 -0.270623 -0.492534
|
||||
-0.092133 -0.024420 0.009129 -0.470709 -0.267377 -0.840799
|
||||
-0.064432 -0.024420 0.001903 0.002929 -0.265584 -0.964083
|
||||
-0.036730 -0.024420 0.009129 0.475987 -0.266954 -0.837957
|
||||
-0.014759 -0.010360 0.083761 0.860926 -0.000266 0.508731
|
||||
-0.007075 -0.010360 0.055841 1.000000 -0.000000 0.000000
|
||||
-0.035753 -0.010360 0.104200 0.491288 -0.000257 0.870997
|
||||
-0.064432 -0.010360 0.111682 0.000000 -0.000000 1.000000
|
||||
-0.093110 -0.010360 0.104200 -0.491288 0.000257 0.870997
|
||||
-0.114104 -0.010360 0.083761 -0.860926 0.000265 0.508731
|
||||
-0.121788 -0.010360 0.055841 -1.000000 -0.000001 -0.000001
|
||||
-0.114104 -0.010360 0.027920 -0.860925 -0.000266 -0.508731
|
||||
-0.093110 -0.010360 0.007481 -0.491288 -0.000256 -0.870997
|
||||
-0.064432 -0.010360 0.000000 0.000000 -0.000000 -1.000000
|
||||
-0.035753 -0.010360 0.007481 0.491288 0.000257 -0.870997
|
||||
-0.016452 0.003701 0.082810 0.830450 0.270188 0.487187
|
||||
-0.009029 0.003701 0.055841 0.962274 0.272063 -0.003217
|
||||
-0.036730 0.003701 0.102553 0.475987 0.266955 0.837957
|
||||
-0.064432 0.003701 0.109779 0.002929 0.265584 0.964083
|
||||
-0.092133 0.003701 0.102553 -0.470709 0.267377 0.840799
|
||||
-0.112412 0.003701 0.082810 -0.827147 0.270625 0.492534
|
||||
-0.119834 0.003701 0.055841 -0.962274 0.272063 0.003217
|
||||
-0.112412 0.003701 0.028872 -0.830450 0.270186 -0.487188
|
||||
-0.092133 0.003701 0.009129 -0.475987 0.266954 -0.837957
|
||||
-0.064432 0.003701 0.001903 -0.002929 0.265583 -0.964083
|
||||
-0.036730 0.003701 0.009129 0.470710 0.267376 -0.840799
|
||||
-0.021414 0.016803 0.080021 0.739473 0.517639 0.430383
|
||||
-0.014759 0.016803 0.055841 0.853991 0.520251 -0.006112
|
||||
-0.039596 0.016803 0.097721 0.426533 0.512723 0.745107
|
||||
-0.064432 0.016803 0.104200 0.005639 0.510417 0.859908
|
||||
-0.089268 0.016803 0.097721 -0.416448 0.512938 0.750643
|
||||
-0.107449 0.016803 0.080021 -0.733262 0.517857 0.440626
|
||||
-0.114104 0.016803 0.055841 -0.853991 0.520252 0.006112
|
||||
-0.107449 0.016803 0.031661 -0.739473 0.517640 -0.430382
|
||||
-0.089268 0.016803 0.013960 -0.426533 0.512723 -0.745107
|
||||
-0.064432 0.016803 0.007481 -0.005640 0.510418 -0.859908
|
||||
-0.039595 0.016803 0.013960 0.416449 0.512938 -0.750643
|
||||
-0.029308 0.028054 0.075583 0.598218 0.723534 0.344433
|
||||
-0.023874 0.028054 0.055841 0.687850 0.725803 -0.008451
|
||||
-0.044153 0.028054 0.090036 0.348006 0.719035 0.601565
|
||||
-0.064432 0.028054 0.095326 0.007940 0.716811 0.697222
|
||||
-0.084710 0.028054 0.090036 -0.333958 0.719029 0.609483
|
||||
-0.099555 0.028054 0.075583 -0.589753 0.723523 0.358757
|
||||
-0.104989 0.028054 0.055841 -0.687850 0.725804 0.008451
|
||||
-0.099555 0.028054 0.036098 -0.598218 0.723534 -0.344434
|
||||
-0.084710 0.028054 0.021645 -0.348006 0.719035 -0.601564
|
||||
-0.064432 0.028054 0.016355 -0.007940 0.716811 -0.697222
|
||||
-0.044153 0.028054 0.021645 0.333956 0.719030 -0.609483
|
||||
-0.039596 0.036687 0.069801 0.420061 0.875943 0.237219
|
||||
-0.035753 0.036687 0.055841 0.479979 0.877222 -0.010123
|
||||
-0.050092 0.036687 0.080021 0.247407 0.873271 0.419748
|
||||
-0.064432 0.036687 0.083761 0.009684 0.871880 0.489625
|
||||
-0.078771 0.036687 0.080021 -0.230453 0.873143 0.429549
|
||||
-0.089268 0.036687 0.069801 -0.410062 0.875812 0.254565
|
||||
-0.093110 0.036687 0.055841 -0.479980 0.877221 0.010124
|
||||
-0.089268 0.036687 0.041881 -0.420061 0.875942 -0.237220
|
||||
-0.078771 0.036687 0.031661 -0.247407 0.873270 -0.419748
|
||||
-0.064432 0.036687 0.027920 -0.009683 0.871880 -0.489625
|
||||
-0.050092 0.036687 0.031661 0.230454 0.873143 -0.429549
|
||||
-0.064432 0.043965 0.055841 0.000000 1.000000 -0.000000
|
||||
-0.064432 -0.064684 0.055841 0.000000 -1.000000 -0.000000
|
||||
numsurf 13
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 25
|
||||
166 0.12500 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
|
||||
19 0.16667 0.08333 0.20078 0.00100 0.27261 -0.65958 0.06470 0.11207
|
||||
44 0.08333 0.08333 0.22774 0.00100 0.24337 -0.66338 0.11207 0.06470
|
||||
45 0.08333 0.16667 0.25662 0.00100 0.24258 -0.70570 0.21651 0.12500
|
||||
42 -0.00000 0.16667 0.29617 0.00100 0.18165 -0.65455 0.25000 0.00000
|
||||
45 0.08333 0.16667 0.25662 0.00100 0.24258 -0.70570 0.21651 0.12500
|
||||
46 -0.00000 0.25000 0.34675 0.00100 0.14154 -0.62617 0.35355 0.00000
|
||||
47 0.08333 0.25000 0.28254 0.00100 0.23215 -0.72379 0.30619 0.17678
|
||||
48 -0.00000 0.33333 0.39286 0.00100 0.09463 -0.54477 0.43301 0.00000
|
||||
49 0.08333 0.33333 0.30010 0.00100 0.20445 -0.70053 0.37500 0.21651
|
||||
50 -0.00000 0.41667 0.42672 0.00100 0.04684 -0.39635 0.48296 0.00000
|
||||
51 0.08333 0.41667 0.30053 0.00100 0.14994 -0.59217 0.41826 0.24148
|
||||
52 -0.00000 0.50000 0.43819 0.27990 0.01216 -0.18101 0.50000 0.00000
|
||||
53 0.08333 0.50000 0.27797 0.11146 0.07998 -0.31169 0.43301 0.25000
|
||||
54 -0.00000 0.58333 0.42036 0.71453 0.00746 0.06528 0.48296 0.00000
|
||||
55 0.08333 0.58333 0.25398 0.77247 0.06825 0.11068 0.41826 0.24148
|
||||
56 -0.00000 0.66667 0.37732 0.99900 0.03584 0.27934 0.43301 0.00000
|
||||
57 0.08333 0.66667 0.24356 0.99900 0.12085 0.40243 0.37500 0.21651
|
||||
58 -0.00000 0.75000 0.32156 0.99900 0.08264 0.41936 0.35355 0.00000
|
||||
59 0.08333 0.75000 0.23016 0.99900 0.16764 0.51660 0.30619 0.17678
|
||||
60 -0.00000 0.83333 0.26409 0.99900 0.13155 0.48413 0.25000 0.00000
|
||||
61 0.08333 0.83333 0.21022 0.99900 0.19350 0.53698 0.21651 0.12500
|
||||
62 -0.00000 0.91667 0.21082 0.99900 0.17434 0.49121 0.12941 0.00000
|
||||
63 0.08333 0.91667 0.18721 0.99900 0.20517 0.51082 0.11207 0.06470
|
||||
64 0.04167 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 4
|
||||
42 -0.00000 0.16667 0.29617 0.00100 0.18165 -0.65455 0.25000 0.00000
|
||||
43 -0.00000 0.08333 0.24596 0.00100 0.21392 -0.64381 0.12941 0.00000
|
||||
44 0.08333 0.08333 0.22774 0.00100 0.24337 -0.66338 0.11207 0.06470
|
||||
65 0.04167 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 26
|
||||
41 0.16667 0.91667 0.15686 0.99900 0.23923 0.50697 0.06470 0.11207
|
||||
165 0.12500 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
|
||||
41 0.16667 0.91667 0.15686 0.99900 0.23923 0.50697 0.06470 0.11207
|
||||
63 0.08333 0.91667 0.18721 0.99900 0.20517 0.51082 0.11207 0.06470
|
||||
164 0.16667 0.83333 0.14064 0.99900 0.27287 0.52638 0.12500 0.21651
|
||||
61 0.08333 0.83333 0.21022 0.99900 0.19350 0.53698 0.21651 0.12500
|
||||
153 0.16667 0.75000 0.11005 0.99900 0.30883 0.49554 0.17678 0.30619
|
||||
59 0.08333 0.75000 0.23016 0.99900 0.16764 0.51660 0.30619 0.17678
|
||||
142 0.16667 0.66667 0.06221 0.99900 0.34565 0.37156 0.21651 0.37500
|
||||
57 0.08333 0.66667 0.24356 0.99900 0.12085 0.40243 0.37500 0.21651
|
||||
131 0.16667 0.58333 0.01707 0.75383 0.37997 0.09731 0.24148 0.41826
|
||||
55 0.08333 0.58333 0.25398 0.77247 0.06825 0.11068 0.41826 0.24148
|
||||
120 0.16667 0.50000 0.02917 0.16155 0.40148 -0.27285 0.25000 0.43301
|
||||
53 0.08333 0.50000 0.27797 0.11146 0.07998 -0.31169 0.43301 0.25000
|
||||
109 0.16667 0.41667 0.09227 0.00100 0.39866 -0.54216 0.24148 0.41826
|
||||
51 0.08333 0.41667 0.30053 0.00100 0.14994 -0.59217 0.41826 0.24148
|
||||
98 0.16667 0.33333 0.14840 0.00100 0.37604 -0.66637 0.21651 0.37500
|
||||
49 0.08333 0.33333 0.30010 0.00100 0.20445 -0.70053 0.37500 0.21651
|
||||
87 0.16667 0.25000 0.18125 0.00100 0.34374 -0.70421 0.17678 0.30619
|
||||
47 0.08333 0.25000 0.28254 0.00100 0.23215 -0.72379 0.30619 0.17678
|
||||
76 0.16667 0.16667 0.19643 0.00100 0.30813 -0.69579 0.12500 0.21651
|
||||
45 0.08333 0.16667 0.25662 0.00100 0.24258 -0.70570 0.21651 0.12500
|
||||
76 0.16667 0.16667 0.19643 0.00100 0.30813 -0.69579 0.12500 0.21651
|
||||
19 0.16667 0.08333 0.20078 0.00100 0.27261 -0.65958 0.06470 0.11207
|
||||
17 0.25000 0.08333 0.17478 0.00100 0.29109 -0.63431 0.00000 0.12941
|
||||
20 0.20833 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 26
|
||||
39 0.25000 0.91667 0.13138 0.99900 0.26321 0.48188 0.00000 0.12941
|
||||
40 0.20833 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
|
||||
39 0.25000 0.91667 0.13138 0.99900 0.26321 0.48188 0.00000 0.12941
|
||||
41 0.16667 0.91667 0.15686 0.99900 0.23923 0.50697 0.06470 0.11207
|
||||
163 0.25000 0.83333 0.09337 0.99900 0.32380 0.46306 0.00000 0.25000
|
||||
164 0.16667 0.83333 0.14064 0.99900 0.27287 0.52638 0.12500 0.21651
|
||||
152 0.25000 0.75000 0.05350 0.99900 0.38666 0.38881 0.00000 0.35355
|
||||
153 0.16667 0.75000 0.11005 0.99900 0.30883 0.49554 0.17678 0.30619
|
||||
141 0.25000 0.66667 0.01921 0.99900 0.44417 0.25077 0.00000 0.43301
|
||||
142 0.16667 0.66667 0.06221 0.99900 0.34565 0.37156 0.21651 0.37500
|
||||
130 0.25000 0.58333 0.00104 0.70147 0.48527 0.05732 0.00000 0.48296
|
||||
131 0.16667 0.58333 0.01707 0.75383 0.37997 0.09731 0.24148 0.41826
|
||||
119 0.25000 0.50000 0.00634 0.30861 0.50000 -0.15875 0.00000 0.50000
|
||||
120 0.16667 0.50000 0.02917 0.16155 0.40148 -0.27285 0.25000 0.43301
|
||||
108 0.25000 0.41667 0.03263 0.00100 0.48620 -0.35427 0.00000 0.48296
|
||||
109 0.16667 0.41667 0.09227 0.00100 0.39866 -0.54216 0.24148 0.41826
|
||||
97 0.25000 0.33333 0.07009 0.00100 0.45008 -0.50072 0.00000 0.43301
|
||||
98 0.16667 0.33333 0.14840 0.00100 0.37604 -0.66637 0.21651 0.37500
|
||||
86 0.25000 0.25000 0.10926 0.00100 0.40081 -0.59156 0.00000 0.35355
|
||||
87 0.16667 0.25000 0.18125 0.00100 0.34374 -0.70421 0.17678 0.30619
|
||||
75 0.25000 0.16667 0.14481 0.00100 0.34608 -0.63293 0.00000 0.25000
|
||||
76 0.16667 0.16667 0.19643 0.00100 0.30813 -0.69579 0.12500 0.21651
|
||||
75 0.25000 0.16667 0.14481 0.00100 0.34608 -0.63293 0.00000 0.25000
|
||||
17 0.25000 0.08333 0.17478 0.00100 0.29109 -0.63431 0.00000 0.12941
|
||||
15 0.33333 0.08333 0.15726 0.00100 0.29335 -0.59942 -0.06470 0.11207
|
||||
18 0.29167 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 26
|
||||
37 0.33333 0.91667 0.11731 0.99900 0.26926 0.44859 -0.06470 0.11207
|
||||
38 0.29167 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
|
||||
37 0.33333 0.91667 0.11731 0.99900 0.26926 0.44859 -0.06470 0.11207
|
||||
39 0.25000 0.91667 0.13138 0.99900 0.26321 0.48188 0.00000 0.12941
|
||||
162 0.33333 0.83333 0.07414 0.99900 0.32883 0.39669 -0.12500 0.21651
|
||||
163 0.25000 0.83333 0.09337 0.99900 0.32380 0.46306 0.00000 0.25000
|
||||
151 0.33333 0.75000 0.03873 0.99900 0.38213 0.30552 -0.17678 0.30619
|
||||
152 0.25000 0.75000 0.05350 0.99900 0.38666 0.38881 0.00000 0.35355
|
||||
140 0.33333 0.66667 0.01433 0.96962 0.42405 0.18283 -0.21651 0.37500
|
||||
141 0.25000 0.66667 0.01921 0.99900 0.44417 0.25077 0.00000 0.43301
|
||||
129 0.33333 0.58333 0.00283 0.67965 0.45074 0.03994 -0.24148 0.41826
|
||||
130 0.25000 0.58333 0.00104 0.70147 0.48527 0.05732 0.00000 0.48296
|
||||
118 0.33333 0.50000 0.00464 0.37108 0.46020 -0.11023 -0.25000 0.43301
|
||||
119 0.25000 0.50000 0.00634 0.30861 0.50000 -0.15875 0.00000 0.50000
|
||||
107 0.33333 0.41667 0.01889 0.06946 0.45233 -0.25504 -0.24148 0.41826
|
||||
108 0.25000 0.41667 0.03263 0.00100 0.48620 -0.35427 0.00000 0.48296
|
||||
96 0.33333 0.33333 0.04378 0.00100 0.42865 -0.38353 -0.21651 0.37500
|
||||
97 0.25000 0.33333 0.07009 0.00100 0.45008 -0.50072 0.00000 0.43301
|
||||
85 0.33333 0.25000 0.07694 0.00100 0.39190 -0.48717 -0.17678 0.30619
|
||||
86 0.25000 0.25000 0.10926 0.00100 0.40081 -0.59156 0.00000 0.35355
|
||||
74 0.33333 0.16667 0.11569 0.00100 0.34553 -0.56015 -0.12500 0.21651
|
||||
75 0.25000 0.16667 0.14481 0.00100 0.34608 -0.63293 0.00000 0.25000
|
||||
74 0.33333 0.16667 0.11569 0.00100 0.34553 -0.56015 -0.12500 0.21651
|
||||
15 0.33333 0.08333 0.15726 0.00100 0.29335 -0.59942 -0.06470 0.11207
|
||||
13 0.41667 0.08333 0.15134 0.00100 0.28069 -0.56690 -0.11207 0.06470
|
||||
16 0.37500 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 26
|
||||
35 0.41667 0.91667 0.11568 0.99900 0.25826 0.41884 -0.11207 0.06470
|
||||
36 0.37500 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
|
||||
35 0.41667 0.91667 0.11568 0.99900 0.25826 0.41884 -0.11207 0.06470
|
||||
37 0.33333 0.91667 0.11731 0.99900 0.26926 0.44859 -0.06470 0.11207
|
||||
161 0.41667 0.83333 0.07575 0.99900 0.30096 0.34871 -0.21651 0.12500
|
||||
162 0.33333 0.83333 0.07414 0.99900 0.32883 0.39669 -0.12500 0.21651
|
||||
150 0.41667 0.75000 0.04562 0.99900 0.33524 0.25608 -0.30619 0.17678
|
||||
151 0.33333 0.75000 0.03873 0.99900 0.38213 0.30552 -0.17678 0.30619
|
||||
139 0.41667 0.66667 0.02569 0.92724 0.36024 0.14834 -0.37500 0.21651
|
||||
140 0.33333 0.66667 0.01433 0.96962 0.42405 0.18283 -0.21651 0.37500
|
||||
128 0.41667 0.58333 0.01596 0.67063 0.37568 0.03187 -0.41826 0.24148
|
||||
129 0.33333 0.58333 0.00283 0.67965 0.45074 0.03994 -0.24148 0.41826
|
||||
117 0.41667 0.50000 0.01621 0.39994 0.38162 -0.08785 -0.43301 0.25000
|
||||
118 0.33333 0.50000 0.00464 0.37108 0.46020 -0.11023 -0.25000 0.43301
|
||||
106 0.41667 0.41667 0.02609 0.13144 0.37828 -0.20590 -0.41826 0.24148
|
||||
107 0.33333 0.41667 0.01889 0.06946 0.45233 -0.25504 -0.24148 0.41826
|
||||
95 0.41667 0.33333 0.04522 0.00100 0.36600 -0.31762 -0.37500 0.21651
|
||||
96 0.33333 0.33333 0.04378 0.00100 0.42865 -0.38353 -0.21651 0.37500
|
||||
84 0.41667 0.25000 0.07305 0.00100 0.34519 -0.41833 -0.30619 0.17678
|
||||
85 0.33333 0.25000 0.07694 0.00100 0.39190 -0.48717 -0.17678 0.30619
|
||||
73 0.41667 0.16667 0.10881 0.00100 0.31647 -0.50313 -0.21651 0.12500
|
||||
74 0.33333 0.16667 0.11569 0.00100 0.34553 -0.56015 -0.12500 0.21651
|
||||
73 0.41667 0.16667 0.10881 0.00100 0.31647 -0.50313 -0.21651 0.12500
|
||||
13 0.41667 0.08333 0.15134 0.00100 0.28069 -0.56690 -0.11207 0.06470
|
||||
11 0.50000 0.08333 0.15695 0.00100 0.25836 -0.54379 -0.12941 0.00000
|
||||
14 0.45833 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 26
|
||||
33 0.50000 0.91667 0.12506 0.99900 0.23590 0.39836 -0.12941 0.00000
|
||||
34 0.45833 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
|
||||
33 0.50000 0.91667 0.12506 0.99900 0.23590 0.39836 -0.12941 0.00000
|
||||
35 0.41667 0.91667 0.11568 0.99900 0.25826 0.41884 -0.11207 0.06470
|
||||
160 0.50000 0.83333 0.09377 0.99900 0.25637 0.32013 -0.25000 0.00000
|
||||
161 0.41667 0.83333 0.07575 0.99900 0.30096 0.34871 -0.21651 0.12500
|
||||
149 0.50000 0.75000 0.07035 0.99900 0.27148 0.22961 -0.35355 0.00000
|
||||
150 0.41667 0.75000 0.04562 0.99900 0.33524 0.25608 -0.30619 0.17678
|
||||
138 0.50000 0.66667 0.05477 0.90616 0.28211 0.13113 -0.43301 0.00000
|
||||
139 0.41667 0.66667 0.02569 0.92724 0.36024 0.14834 -0.37500 0.21651
|
||||
127 0.50000 0.58333 0.04697 0.66642 0.28889 0.02798 -0.48296 0.00000
|
||||
128 0.41667 0.58333 0.01596 0.67063 0.37568 0.03187 -0.41826 0.24148
|
||||
116 0.50000 0.50000 0.04685 0.41393 0.29223 -0.07709 -0.50000 0.00000
|
||||
117 0.41667 0.50000 0.01621 0.39994 0.38162 -0.08785 -0.43301 0.25000
|
||||
105 0.50000 0.41667 0.05433 0.16212 0.29232 -0.18164 -0.48296 0.00000
|
||||
106 0.41667 0.41667 0.02609 0.13144 0.37828 -0.20590 -0.41826 0.24148
|
||||
94 0.50000 0.33333 0.06929 0.00100 0.28922 -0.28327 -0.43301 0.00000
|
||||
95 0.41667 0.33333 0.04522 0.00100 0.36600 -0.31762 -0.37500 0.21651
|
||||
83 0.50000 0.25000 0.09157 0.00100 0.28277 -0.37947 -0.35355 0.00000
|
||||
84 0.41667 0.25000 0.07305 0.00100 0.34519 -0.41833 -0.30619 0.17678
|
||||
72 0.50000 0.16667 0.12093 0.00100 0.27266 -0.46743 -0.25000 0.00000
|
||||
73 0.41667 0.16667 0.10881 0.00100 0.31647 -0.50313 -0.21651 0.12500
|
||||
72 0.50000 0.16667 0.12093 0.00100 0.27266 -0.46743 -0.25000 0.00000
|
||||
11 0.50000 0.08333 0.15695 0.00100 0.25836 -0.54379 -0.12941 0.00000
|
||||
9 0.58333 0.08333 0.17221 0.00100 0.23253 -0.53297 -0.11207 -0.06470
|
||||
12 0.54167 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 26
|
||||
31 0.58333 0.91667 0.14311 0.99900 0.20878 0.38894 -0.11207 -0.06470
|
||||
32 0.54167 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
|
||||
31 0.58333 0.91667 0.14311 0.99900 0.20878 0.38894 -0.11207 -0.06470
|
||||
33 0.50000 0.91667 0.12506 0.99900 0.23590 0.39836 -0.12941 0.00000
|
||||
159 0.58333 0.83333 0.12527 0.99900 0.20699 0.30801 -0.21651 -0.12500
|
||||
160 0.50000 0.83333 0.09377 0.99900 0.25637 0.32013 -0.25000 0.00000
|
||||
148 0.58333 0.75000 0.11143 0.99900 0.20500 0.21899 -0.30619 -0.17678
|
||||
149 0.50000 0.75000 0.07035 0.99900 0.27148 0.22961 -0.35355 0.00000
|
||||
137 0.58333 0.66667 0.10210 0.89651 0.20368 0.12444 -0.37500 -0.21651
|
||||
138 0.50000 0.66667 0.05477 0.90616 0.28211 0.13113 -0.43301 0.00000
|
||||
126 0.58333 0.58333 0.09758 0.66389 0.20355 0.02650 -0.41826 -0.24148
|
||||
127 0.50000 0.58333 0.04697 0.66642 0.28889 0.02798 -0.48296 0.00000
|
||||
115 0.58333 0.50000 0.09802 0.41933 0.20491 -0.07299 -0.43301 -0.25000
|
||||
116 0.50000 0.50000 0.04685 0.41393 0.29223 -0.07709 -0.50000 0.00000
|
||||
104 0.58333 0.41667 0.10346 0.17498 0.20788 -0.17229 -0.41826 -0.24148
|
||||
105 0.50000 0.41667 0.05433 0.16212 0.29232 -0.18164 -0.48296 0.00000
|
||||
93 0.58333 0.33333 0.11385 0.00100 0.21242 -0.26969 -0.37500 -0.21651
|
||||
94 0.50000 0.33333 0.06929 0.00100 0.28922 -0.28327 -0.43301 0.00000
|
||||
82 0.58333 0.25000 0.12901 0.00100 0.21834 -0.36350 -0.30619 -0.17678
|
||||
83 0.50000 0.25000 0.09157 0.00100 0.28277 -0.37947 -0.35355 0.00000
|
||||
71 0.58333 0.16667 0.14863 0.00100 0.22526 -0.45191 -0.21651 -0.12500
|
||||
72 0.50000 0.16667 0.12093 0.00100 0.27266 -0.46743 -0.25000 0.00000
|
||||
71 0.58333 0.16667 0.14863 0.00100 0.22526 -0.45191 -0.21651 -0.12500
|
||||
9 0.58333 0.08333 0.17221 0.00100 0.23253 -0.53297 -0.11207 -0.06470
|
||||
7 0.66667 0.08333 0.19399 0.00100 0.20888 -0.53519 -0.06470 -0.11207
|
||||
10 0.62500 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 26
|
||||
29 0.66667 0.91667 0.16656 0.99900 0.18279 0.39086 -0.06470 -0.11207
|
||||
30 0.62500 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
|
||||
29 0.66667 0.91667 0.16656 0.99900 0.18279 0.39086 -0.06470 -0.11207
|
||||
31 0.58333 0.91667 0.14311 0.99900 0.20878 0.38894 -0.11207 -0.06470
|
||||
158 0.66667 0.83333 0.16659 0.99900 0.16130 0.31057 -0.12500 -0.21651
|
||||
159 0.58333 0.83333 0.12527 0.99900 0.20699 0.30801 -0.21651 -0.12500
|
||||
147 0.66667 0.75000 0.16588 0.99900 0.14487 0.22131 -0.17678 -0.30619
|
||||
148 0.58333 0.75000 0.11143 0.99900 0.20500 0.21899 -0.30619 -0.17678
|
||||
136 0.66667 0.66667 0.16546 0.89633 0.13378 0.12594 -0.21651 -0.37500
|
||||
137 0.58333 0.66667 0.10210 0.89651 0.20368 0.12444 -0.37500 -0.21651
|
||||
125 0.66667 0.58333 0.16597 0.66293 0.12819 0.02683 -0.24148 -0.41826
|
||||
126 0.58333 0.58333 0.09758 0.66389 0.20355 0.02650 -0.41826 -0.24148
|
||||
114 0.66667 0.50000 0.16776 0.41811 0.12818 -0.07393 -0.25000 -0.43301
|
||||
115 0.58333 0.50000 0.09802 0.41933 0.20491 -0.07299 -0.43301 -0.25000
|
||||
103 0.66667 0.41667 0.17097 0.17362 0.13376 -0.17442 -0.24148 -0.41826
|
||||
104 0.58333 0.41667 0.10346 0.17498 0.20788 -0.17229 -0.41826 -0.24148
|
||||
92 0.66667 0.33333 0.17556 0.00100 0.14484 -0.27274 -0.21651 -0.37500
|
||||
93 0.58333 0.33333 0.11385 0.00100 0.21242 -0.26969 -0.37500 -0.21651
|
||||
81 0.66667 0.25000 0.18129 0.00100 0.16125 -0.36700 -0.17678 -0.30619
|
||||
82 0.58333 0.25000 0.12901 0.00100 0.21834 -0.36350 -0.30619 -0.17678
|
||||
70 0.66667 0.16667 0.18769 0.00100 0.18273 -0.45521 -0.12500 -0.21651
|
||||
71 0.58333 0.16667 0.14863 0.00100 0.22526 -0.45191 -0.21651 -0.12500
|
||||
70 0.66667 0.16667 0.18769 0.00100 0.18273 -0.45521 -0.12500 -0.21651
|
||||
7 0.66667 0.08333 0.19399 0.00100 0.20888 -0.53519 -0.06470 -0.11207
|
||||
5 0.75000 0.08333 0.21789 0.00100 0.19222 -0.55023 0.00000 -0.12941
|
||||
8 0.70833 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 26
|
||||
27 0.75000 0.91667 0.19095 0.99900 0.16283 0.40401 0.00000 -0.12941
|
||||
28 0.70833 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
|
||||
27 0.75000 0.91667 0.19095 0.99900 0.16283 0.40401 0.00000 -0.12941
|
||||
29 0.66667 0.91667 0.16656 0.99900 0.18279 0.39086 -0.06470 -0.11207
|
||||
157 0.75000 0.83333 0.21201 0.99900 0.12561 0.32796 0.00000 -0.25000
|
||||
158 0.66667 0.83333 0.16659 0.99900 0.16130 0.31057 -0.12500 -0.21651
|
||||
146 0.75000 0.75000 0.22797 0.99900 0.09754 0.23688 0.00000 -0.35355
|
||||
147 0.66667 0.75000 0.16588 0.99900 0.14487 0.22131 -0.17678 -0.30619
|
||||
135 0.75000 0.66667 0.23948 0.90806 0.07868 0.13588 0.00000 -0.43301
|
||||
136 0.66667 0.66667 0.16546 0.89633 0.13378 0.12594 -0.21651 -0.37500
|
||||
124 0.75000 0.58333 0.24702 0.66503 0.06897 0.02906 0.00000 -0.48296
|
||||
125 0.66667 0.58333 0.16597 0.66293 0.12819 0.02683 -0.24148 -0.41826
|
||||
113 0.75000 0.50000 0.25094 0.41006 0.06830 -0.08009 0.00000 -0.50000
|
||||
114 0.66667 0.50000 0.16776 0.41811 0.12818 -0.07393 -0.25000 -0.43301
|
||||
102 0.75000 0.41667 0.25144 0.15617 0.07651 -0.18841 0.00000 -0.48296
|
||||
103 0.66667 0.41667 0.17097 0.17362 0.13376 -0.17442 -0.24148 -0.41826
|
||||
91 0.75000 0.33333 0.24857 0.00100 0.09338 -0.29285 0.00000 -0.43301
|
||||
92 0.66667 0.33333 0.17556 0.00100 0.14484 -0.27274 -0.21651 -0.37500
|
||||
80 0.75000 0.25000 0.24221 0.00100 0.11860 -0.39028 0.00000 -0.35355
|
||||
81 0.66667 0.25000 0.18129 0.00100 0.16125 -0.36700 -0.17678 -0.30619
|
||||
69 0.75000 0.16667 0.23212 0.00100 0.15175 -0.47734 0.00000 -0.25000
|
||||
70 0.66667 0.16667 0.18769 0.00100 0.18273 -0.45521 -0.12500 -0.21651
|
||||
69 0.75000 0.16667 0.23212 0.00100 0.15175 -0.47734 0.00000 -0.25000
|
||||
5 0.75000 0.08333 0.21789 0.00100 0.19222 -0.55023 0.00000 -0.12941
|
||||
3 0.83333 0.08333 0.23838 0.00100 0.18630 -0.57670 0.06470 -0.11207
|
||||
6 0.79167 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 26
|
||||
25 0.83333 0.91667 0.21053 0.99900 0.15290 0.42768 0.06470 -0.11207
|
||||
26 0.79167 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
|
||||
25 0.83333 0.91667 0.21053 0.99900 0.15290 0.42768 0.06470 -0.11207
|
||||
27 0.75000 0.91667 0.19095 0.99900 0.16283 0.40401 0.00000 -0.12941
|
||||
156 0.83333 0.83333 0.25271 0.99900 0.10497 0.36222 0.12500 -0.21651
|
||||
157 0.75000 0.83333 0.21201 0.99900 0.12561 0.32796 0.00000 -0.25000
|
||||
145 0.83333 0.75000 0.28799 0.99900 0.06767 0.26941 0.17678 -0.30619
|
||||
146 0.75000 0.75000 0.22797 0.99900 0.09754 0.23688 0.00000 -0.35355
|
||||
134 0.83333 0.66667 0.31457 0.93678 0.04237 0.15738 0.21651 -0.37500
|
||||
135 0.75000 0.66667 0.23948 0.90806 0.07868 0.13588 0.00000 -0.43301
|
||||
123 0.83333 0.58333 0.33150 0.67193 0.02955 0.03395 0.24148 -0.41826
|
||||
124 0.75000 0.58333 0.24702 0.66503 0.06897 0.02906 0.00000 -0.48296
|
||||
112 0.83333 0.50000 0.33844 0.39249 0.02914 -0.09363 0.25000 -0.43301
|
||||
113 0.75000 0.50000 0.25094 0.41006 0.06830 -0.08009 0.00000 -0.50000
|
||||
101 0.83333 0.41667 0.33549 0.11627 0.04068 -0.21875 0.24148 -0.41826
|
||||
102 0.75000 0.41667 0.25144 0.15617 0.07651 -0.18841 0.00000 -0.48296
|
||||
90 0.83333 0.33333 0.32310 0.00100 0.06342 -0.33527 0.21651 -0.37500
|
||||
91 0.75000 0.33333 0.24857 0.00100 0.09338 -0.29285 0.00000 -0.43301
|
||||
79 0.83333 0.25000 0.30202 0.00100 0.09629 -0.43738 0.17678 -0.30619
|
||||
80 0.75000 0.25000 0.24221 0.00100 0.11860 -0.39028 0.00000 -0.35355
|
||||
68 0.83333 0.16667 0.27332 0.00100 0.13788 -0.51956 0.12500 -0.21651
|
||||
69 0.75000 0.16667 0.23212 0.00100 0.15175 -0.47734 0.00000 -0.25000
|
||||
68 0.83333 0.16667 0.27332 0.00100 0.13788 -0.51956 0.12500 -0.21651
|
||||
3 0.83333 0.08333 0.23838 0.00100 0.18630 -0.57670 0.06470 -0.11207
|
||||
0 0.91667 0.08333 0.24936 0.00100 0.19351 -0.61071 0.11207 -0.06470
|
||||
4 0.87500 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 26
|
||||
23 0.91667 0.91667 0.21882 0.99900 0.15617 0.45920 0.11207 -0.06470
|
||||
24 0.87500 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
|
||||
23 0.91667 0.91667 0.21882 0.99900 0.15617 0.45920 0.11207 -0.06470
|
||||
25 0.83333 0.91667 0.21053 0.99900 0.15290 0.42768 0.06470 -0.11207
|
||||
154 0.91667 0.83333 0.27563 0.99900 0.10447 0.41577 0.21651 -0.12500
|
||||
156 0.83333 0.83333 0.25271 0.99900 0.10497 0.36222 0.12500 -0.21651
|
||||
143 0.91667 0.75000 0.32918 0.99900 0.05945 0.32703 0.30619 -0.17678
|
||||
145 0.83333 0.75000 0.28799 0.99900 0.06767 0.26941 0.17678 -0.30619
|
||||
132 0.91667 0.66667 0.37332 0.99232 0.02664 0.19879 0.37500 -0.21651
|
||||
134 0.83333 0.66667 0.31457 0.93678 0.04237 0.15738 0.21651 -0.37500
|
||||
121 0.91667 0.58333 0.40266 0.68601 0.01006 0.04379 0.41826 -0.24148
|
||||
123 0.83333 0.58333 0.33150 0.67193 0.02955 0.03395 0.24148 -0.41826
|
||||
110 0.91667 0.50000 0.41387 0.35730 0.01120 -0.12091 0.43301 -0.25000
|
||||
112 0.83333 0.50000 0.33844 0.39249 0.02914 -0.09363 0.25000 -0.43301
|
||||
99 0.91667 0.41667 0.40641 0.03864 0.02889 -0.27785 0.41826 -0.24148
|
||||
101 0.83333 0.41667 0.33549 0.11627 0.04068 -0.21875 0.24148 -0.41826
|
||||
88 0.91667 0.33333 0.38226 0.00100 0.06003 -0.41261 0.37500 -0.21651
|
||||
90 0.83333 0.33333 0.32310 0.00100 0.06342 -0.33527 0.21651 -0.37500
|
||||
77 0.91667 0.25000 0.34511 0.00100 0.10054 -0.51553 0.30619 -0.17678
|
||||
79 0.83333 0.25000 0.30202 0.00100 0.09629 -0.43738 0.17678 -0.30619
|
||||
66 0.91667 0.16667 0.29935 0.00100 0.14628 -0.58181 0.21651 -0.12500
|
||||
68 0.83333 0.16667 0.27332 0.00100 0.13788 -0.51956 0.12500 -0.21651
|
||||
66 0.91667 0.16667 0.29935 0.00100 0.14628 -0.58181 0.21651 -0.12500
|
||||
0 0.91667 0.08333 0.24936 0.00100 0.19351 -0.61071 0.11207 -0.06470
|
||||
2 1.00000 0.08333 0.24596 0.00100 0.21392 -0.64381 0.12941 0.00000
|
||||
1 0.95833 0.00000 0.19898 0.00100 0.23912 -0.60440 0.00000 0.00000
|
||||
SURF 0x14
|
||||
mat 0
|
||||
refs 23
|
||||
66 0.91667 0.16667 0.29935 0.00100 0.14628 -0.58181 0.21651 -0.12500
|
||||
2 1.00000 0.08333 0.24596 0.00100 0.21392 -0.64381 0.12941 0.00000
|
||||
66 0.91667 0.16667 0.29935 0.00100 0.14628 -0.58181 0.21651 -0.12500
|
||||
67 1.00000 0.16667 0.29617 0.00100 0.18165 -0.65455 0.25000 0.00000
|
||||
77 0.91667 0.25000 0.34511 0.00100 0.10054 -0.51553 0.30619 -0.17678
|
||||
78 1.00000 0.25000 0.34675 0.00100 0.14154 -0.62617 0.35355 0.00000
|
||||
88 0.91667 0.33333 0.38226 0.00100 0.06003 -0.41261 0.37500 -0.21651
|
||||
89 1.00000 0.33333 0.39286 0.00100 0.09463 -0.54477 0.43301 0.00000
|
||||
99 0.91667 0.41667 0.40641 0.03864 0.02889 -0.27785 0.41826 -0.24148
|
||||
100 1.00000 0.41667 0.42672 0.00100 0.04684 -0.39635 0.48296 0.00000
|
||||
110 0.91667 0.50000 0.41387 0.35730 0.01120 -0.12091 0.43301 -0.25000
|
||||
111 1.00000 0.50000 0.43819 0.27990 0.01216 -0.18101 0.50000 0.00000
|
||||
121 0.91667 0.58333 0.40266 0.68601 0.01006 0.04379 0.41826 -0.24148
|
||||
122 1.00000 0.58333 0.42036 0.71453 0.00746 0.06528 0.48296 0.00000
|
||||
132 0.91667 0.66667 0.37332 0.99232 0.02664 0.19879 0.37500 -0.21651
|
||||
133 1.00000 0.66667 0.37732 0.99900 0.03584 0.27934 0.43301 0.00000
|
||||
143 0.91667 0.75000 0.32918 0.99900 0.05945 0.32703 0.30619 -0.17678
|
||||
144 1.00000 0.75000 0.32156 0.99900 0.08264 0.41936 0.35355 0.00000
|
||||
154 0.91667 0.83333 0.27563 0.99900 0.10447 0.41577 0.21651 -0.12500
|
||||
155 1.00000 0.83333 0.26409 0.99900 0.13155 0.48413 0.25000 0.00000
|
||||
23 0.91667 0.91667 0.21882 0.99900 0.15617 0.45920 0.11207 -0.06470
|
||||
21 1.00000 0.91667 0.21082 0.99900 0.17434 0.49121 0.12941 0.00000
|
||||
22 0.95833 1.00000 0.16417 0.99900 0.20895 0.45830 0.00000 0.00000
|
||||
kids 0
|
|
@ -32,7 +32,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="textures/editor_defaults/default_texture.png" />
|
||||
<texture name="Texture1" value="assets/default_texture.png" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -89,7 +89,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="skybox/default_skybox2.jpg" />
|
||||
<texture name="Texture1" value="assets/skybox/default_skybox2.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -128,7 +128,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="skybox/default_skybox1.jpg" />
|
||||
<texture name="Texture1" value="assets/skybox/default_skybox1.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -167,7 +167,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="skybox/default_skybox0.jpg" />
|
||||
<texture name="Texture1" value="assets/skybox/default_skybox0.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -206,7 +206,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="skybox/default_skybox3.jpg" />
|
||||
<texture name="Texture1" value="assets/skybox/default_skybox3.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -245,7 +245,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="skybox/default_skyboxup.jpg" />
|
||||
<texture name="Texture1" value="assets/skybox/default_skyboxup.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -284,7 +284,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="skybox/default_skyboxdn.jpg" />
|
||||
<texture name="Texture1" value="assets/skybox/default_skyboxdn.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -329,7 +329,7 @@
|
|||
<enum name="AutomaticCulling" value="box" />
|
||||
<int name="DebugDataVisible" value="0" />
|
||||
<bool name="IsDebugObject" value="false" />
|
||||
<string name="Mesh" value="dwarf.x" />
|
||||
<string name="Mesh" value="assets/dwarf.x" />
|
||||
<bool name="Looping" value="true" />
|
||||
<bool name="ReadOnlyMaterials" value="false" />
|
||||
<float name="FramesPerSecond" value="0.250000" />
|
||||
|
@ -345,7 +345,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="axe.jpg" />
|
||||
<texture name="Texture1" value="assets/axe.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -384,7 +384,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="dwarf.jpg" />
|
||||
<texture name="Texture1" value="assets/dwarf.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -468,7 +468,7 @@
|
|||
<enum name="AutomaticCulling" value="box" />
|
||||
<int name="DebugDataVisible" value="0" />
|
||||
<bool name="IsDebugObject" value="false" />
|
||||
<string name="Mesh" value="dwarf.x" />
|
||||
<string name="Mesh" value="assets/dwarf.x" />
|
||||
<bool name="Looping" value="true" />
|
||||
<bool name="ReadOnlyMaterials" value="false" />
|
||||
<float name="FramesPerSecond" value="0.250000" />
|
||||
|
@ -484,7 +484,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="axe.jpg" />
|
||||
<texture name="Texture1" value="assets/axe.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -523,7 +523,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="dwarf.jpg" />
|
||||
<texture name="Texture1" value="assets/dwarf.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -620,7 +620,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="textures/editor_defaults/default_texture.png" />
|
||||
<texture name="Texture1" value="assets/default_texture.png" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -678,7 +678,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="textures/editor_defaults/default_texture.png" />
|
||||
<texture name="Texture1" value="assets/default_texture.png" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -723,7 +723,7 @@
|
|||
<enum name="AutomaticCulling" value="box" />
|
||||
<int name="DebugDataVisible" value="0" />
|
||||
<bool name="IsDebugObject" value="false" />
|
||||
<string name="Mesh" value="dwarf.x" />
|
||||
<string name="Mesh" value="assets/dwarf.x" />
|
||||
<bool name="Looping" value="true" />
|
||||
<bool name="ReadOnlyMaterials" value="false" />
|
||||
<float name="FramesPerSecond" value="0.250000" />
|
||||
|
@ -739,7 +739,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="axe.jpg" />
|
||||
<texture name="Texture1" value="assets/axe.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -778,7 +778,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="dwarf.jpg" />
|
||||
<texture name="Texture1" value="assets/dwarf.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -875,7 +875,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="textures/editor_defaults/default_texture.png" />
|
||||
<texture name="Texture1" value="assets/default_texture.png" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -920,7 +920,7 @@
|
|||
<enum name="AutomaticCulling" value="box" />
|
||||
<int name="DebugDataVisible" value="0" />
|
||||
<bool name="IsDebugObject" value="false" />
|
||||
<string name="Mesh" value="dwarf.x" />
|
||||
<string name="Mesh" value="assets/dwarf.x" />
|
||||
<bool name="Looping" value="true" />
|
||||
<bool name="ReadOnlyMaterials" value="false" />
|
||||
<float name="FramesPerSecond" value="0.250000" />
|
||||
|
@ -936,7 +936,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="axe.jpg" />
|
||||
<texture name="Texture1" value="assets/axe.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -975,7 +975,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="dwarf.jpg" />
|
||||
<texture name="Texture1" value="assets/dwarf.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
<float name="Shininess" value="0.750000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="brownground_1-1.jpg" />
|
||||
<texture name="Texture2" value="1.png" />
|
||||
<texture name="Texture1" value="assets/brownground_1-1.jpg" />
|
||||
<texture name="Texture2" value="assets/1.png" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
<bool name="Wireframe" value="false" />
|
||||
|
@ -72,8 +72,8 @@
|
|||
<float name="Shininess" value="0.750000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="crackedground_1-6.jpg" />
|
||||
<texture name="Texture2" value="1.png" />
|
||||
<texture name="Texture1" value="assets/crackedground_1-6.jpg" />
|
||||
<texture name="Texture2" value="assets/1.png" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
<bool name="Wireframe" value="false" />
|
||||
|
@ -117,7 +117,7 @@
|
|||
<enum name="AutomaticCulling" value="box" />
|
||||
<int name="DebugDataVisible" value="0" />
|
||||
<bool name="IsDebugObject" value="false" />
|
||||
<string name="Mesh" value="dwarf.x" />
|
||||
<string name="Mesh" value="assets/dwarf.x" />
|
||||
<bool name="ReadOnlyMaterials" value="false" />
|
||||
</attributes>
|
||||
|
||||
|
@ -131,7 +131,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="axe.jpg" />
|
||||
<texture name="Texture1" value="assets/axe.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -170,7 +170,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="dwarf.jpg" />
|
||||
<texture name="Texture1" value="assets/dwarf.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -254,7 +254,7 @@
|
|||
<enum name="AutomaticCulling" value="box" />
|
||||
<int name="DebugDataVisible" value="0" />
|
||||
<bool name="IsDebugObject" value="false" />
|
||||
<string name="Mesh" value="dwarf.x" />
|
||||
<string name="Mesh" value="assets/dwarf.x" />
|
||||
<bool name="ReadOnlyMaterials" value="false" />
|
||||
</attributes>
|
||||
|
||||
|
@ -268,7 +268,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="axe.jpg" />
|
||||
<texture name="Texture1" value="assets/axe.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -307,7 +307,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="dwarf.jpg" />
|
||||
<texture name="Texture1" value="assets/dwarf.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -391,7 +391,7 @@
|
|||
<enum name="AutomaticCulling" value="box" />
|
||||
<int name="DebugDataVisible" value="0" />
|
||||
<bool name="IsDebugObject" value="false" />
|
||||
<string name="Mesh" value="dwarf.x" />
|
||||
<string name="Mesh" value="assets/dwarf.x" />
|
||||
<bool name="ReadOnlyMaterials" value="false" />
|
||||
</attributes>
|
||||
|
||||
|
@ -405,7 +405,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="axe.jpg" />
|
||||
<texture name="Texture1" value="assets/axe.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -444,7 +444,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="dwarf.jpg" />
|
||||
<texture name="Texture1" value="assets/dwarf.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -528,7 +528,7 @@
|
|||
<enum name="AutomaticCulling" value="box" />
|
||||
<int name="DebugDataVisible" value="0" />
|
||||
<bool name="IsDebugObject" value="false" />
|
||||
<string name="Mesh" value="dwarf.x" />
|
||||
<string name="Mesh" value="assets/dwarf.x" />
|
||||
<bool name="ReadOnlyMaterials" value="false" />
|
||||
</attributes>
|
||||
|
||||
|
@ -542,7 +542,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="axe.jpg" />
|
||||
<texture name="Texture1" value="assets/axe.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -581,7 +581,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="dwarf.jpg" />
|
||||
<texture name="Texture1" value="assets/dwarf.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -665,7 +665,7 @@
|
|||
<enum name="AutomaticCulling" value="box" />
|
||||
<int name="DebugDataVisible" value="0" />
|
||||
<bool name="IsDebugObject" value="false" />
|
||||
<string name="Mesh" value="dwarf.x" />
|
||||
<string name="Mesh" value="assets/dwarf.x" />
|
||||
<bool name="ReadOnlyMaterials" value="false" />
|
||||
</attributes>
|
||||
|
||||
|
@ -679,7 +679,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="axe.jpg" />
|
||||
<texture name="Texture1" value="assets/axe.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -718,7 +718,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="dwarf.jpg" />
|
||||
<texture name="Texture1" value="assets/dwarf.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<enum name="AutomaticCulling" value="box" />
|
||||
<int name="DebugDataVisible" value="0" />
|
||||
<bool name="IsDebugObject" value="false" />
|
||||
<string name="Mesh" value="dwarf.x" />
|
||||
<string name="Mesh" value="assets/dwarf.x" />
|
||||
<bool name="Looping" value="true" />
|
||||
<bool name="ReadOnlyMaterials" value="false" />
|
||||
<float name="FramesPerSecond" value="0.025000" />
|
||||
|
@ -35,7 +35,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="axe.jpg" />
|
||||
<texture name="Texture1" value="assets/axe.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
@ -73,7 +73,7 @@
|
|||
<float name="Shininess" value="0.000000" />
|
||||
<float name="Param1" value="0.000000" />
|
||||
<float name="Param2" value="0.000000" />
|
||||
<texture name="Texture1" value="dwarf.jpg" />
|
||||
<texture name="Texture1" value="assets/dwarf.jpg" />
|
||||
<texture name="Texture2" value="" />
|
||||
<texture name="Texture3" value="" />
|
||||
<texture name="Texture4" value="" />
|
||||
|
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 258 KiB |
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 199 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 412 KiB After Width: | Height: | Size: 412 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
@ -0,0 +1,11 @@
|
|||
This skybox is basing on a skydome texture from
|
||||
|
||||
http://mikepan.homeip.net/earth
|
||||
|
||||
Downloaded November 22th, 08
|
||||
Distribution note:
|
||||
"These royalty-free skydome textures work best when applied to a sphere or hemisphere"
|
||||
|
||||
|
||||
|
||||
Thanks for your great work!
|
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 9.2 KiB |