Compare commits

...

11 Commits

Author SHA1 Message Date
Kim Kulling
392a658f9c Bugfix/sparky kitty studios (#6623)
* Fixed regression that scrambled FBX blendshape order.

* Merge master to this branch

---------

Co-authored-by: Lux <lxw404@gmail.com>
Co-authored-by: Lux <52231149+lxw404@users.noreply.github.com>
Co-authored-by: Kim Kulling <kim.kulling@draeger.com>
2026-04-30 11:15:09 +02:00
uwezkhan
11a5d1b8ef Fix out-of-bounds read in StreamReader::IncPtr (#6600)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2026-04-29 13:24:29 +02:00
uwezkhan
9e56e52252 Fix integer truncation in StreamReader size calculations (#6601)
* Fix integer truncation in StreamReader size calculations
* improves type clarity and avoids implicit conversions by replacing C-style casts with static_cast

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2026-04-29 08:27:50 +02:00
uwezkhan
86ae4876fb Hardening aiString deserialization in AssbinLoader to prevent stack b… (#6606)
* Hardening aiString deserialization in AssbinLoader to prevent stack buffer overflow

* Simplify string read error handling in AssbinLoader

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2026-04-28 14:44:07 +02:00
Kim Kulling
fb9a58735d M3D: fix overflow (#6610)
* M3D: fix overflow

---------

Co-authored-by: Kazuki Y <6259214+kazu0617@users.noreply.github.com>
Co-authored-by: kazu0617 <kazu0617@protonmail.com>
2026-04-27 11:35:28 +02:00
Matthew Pohlmann
25a1318534 Fix glTF2 occlusion strength import/export and normal scale export (#6602)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2026-04-23 14:20:06 +02:00
Matthew Pohlmann
ede83d7fe2 glTF2: Fix extracting interleaved buffer data (#6605)
* Fix extracting interleaved buffers

* Fix some issues noted by coderabbit:
- Remove narrowing cast from size_t to unsigned int
- Validate accessor count is <= space in buffer (maxCount)
- Ensure remapped indices only access data valid for this accessor by checking count and not maxCount
2026-04-23 14:02:06 +02:00
dependabot[bot]
17c12da558 Bump softprops/action-gh-release from 2 to 3 (#6597)
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2 to 3.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2...v3)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-14 14:04:53 +02:00
James Sharam
de77101866 Fix for CanRead function for FBXImporter (#6158)
* Fixed CanRead function for FBXImporter, which is important when reading from memory

* Update FBXImporter.cpp

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2026-04-07 10:52:24 +02:00
Bill Wendling
158da57515 Fixed a container-overflow vulnerability in Assimp::ColladaLoader::BuildMeshesForNode (#6575)
The root cause was an unchecked access to the `newMats` vector using `matIdx`.
When a material name (`meshMaterial`) is not found in `mMaterialIndexByName`,
`matIdx` defaults to 0.  If `newMats` is empty (which happens if the material
library is empty or failed to load), accessing `newMats[0]` results in a
container-overflow.

The fix involves adding a bounds check `matIdx < newMats.size()` to the
condition guarding the access to `newMats`. Additionally, based on maintainer
feedback, I added a warning log `ASSIMP_LOG_WARN` when the index is out of
bounds, to inform the user about the missing material definition or broken
reference.

I verified the fix using the provided reproduction command. The
container-overflow is no longer triggered. I also built and ran the unit tests.
Since `bin/unit` was missing, I manually built the unit tests using
`cmake.real` and `ninja` in `/src/assimp/build_tests` with
`ASSIMP_BUILD_TESTS=ON`, `ASSIMP_BUILD_ZLIB=ON`, and
`ASSIMP_WARNINGS_AS_ERRORS=OFF` (to bypass a gtest compilation warning), and
updated `run_tests.sh` to point to the built binary. All 584 tests passed.

Fixes: https://issues.oss-fuzz.com/issues/483102958

Signed-off-by: Bill Wendling <morbo@google.com>
Co-authored-by: CodeMender <codemender-patching@google.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2026-04-06 17:31:59 +02:00
Kim Kulling
021bbff3e5 Feature/rust bindings: Exterimental bindings (#6467)
* Add files for assimp rust wrapper

* Fix bindgen usage.

* Add missing includes for the rust bindings.

* Apply suggestion from @coderabbitai[bot]

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update build.rs

* Fix formatting in Cargo.toml

* Remove generated file

---------

Co-authored-by: Kim Kulling <kullingk@LDED5178.corp.draeger.global>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-04-06 16:34:15 +02:00
77 changed files with 298 additions and 556 deletions

View File

@@ -182,7 +182,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
steps: steps:
- uses: softprops/action-gh-release@v2 - uses: softprops/action-gh-release@v3
with: with:
name: create-release name: create-release
- id: upload-url - id: upload-url

View File

@@ -45,7 +45,7 @@ jobs:
filename: ${{ matrix.name }}-${{ github.event.release.tag_name }}.zip filename: ${{ matrix.name }}-${{ github.event.release.tag_name }}.zip
directory: build/bin/ directory: build/bin/
- uses: softprops/action-gh-release@v2 - uses: softprops/action-gh-release@v3
with: with:
files: build/bin/${{ matrix.name }}-${{ github.event.release.tag_name }}.zip files: build/bin/${{ matrix.name }}-${{ github.event.release.tag_name }}.zip
append_body: true append_body: true

View File

@@ -149,11 +149,18 @@ aiQuaternion Read<aiQuaternion>(IOStream *stream) {
template <> template <>
aiString Read<aiString>(IOStream *stream) { aiString Read<aiString>(IOStream *stream) {
aiString s; aiString s;
stream->Read(&s.length, 4, 1); uint32_t len;
if (s.length) { if (stream->Read(&len, 4, 1) != 1) {
stream->Read(s.data, s.length, 1); throw DeadlyImportError("ASSBIN: Unexpected EOF reading string length");
} }
s.data[s.length] = 0; if (len >= AI_MAXLEN) {
throw DeadlyImportError("ASSBIN: String length too large, potential buffer overflow attempt");
}
s.length = len;
if ((s.length > 0) && (stream->Read(s.data, s.length, 1) != 1)) {
throw DeadlyImportError("ASSBIN: Unexpected EOF reading string data");
}
s.data[s.length] = '\0';
return s; return s;
} }

View File

@@ -507,16 +507,20 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
} }
if (table && !table->mMap.empty()) { if (table && !table->mMap.empty()) {
std::pair<Collada::Effect *, aiMaterial *> &mat = newMats[matIdx]; if (matIdx < newMats.size()) {
std::pair<Collada::Effect *, aiMaterial *> &mat = newMats[matIdx];
// Iterate through all texture channels assigned to the effect and // Iterate through all texture channels assigned to the effect and
// check whether we have mapping information for it. // check whether we have mapping information for it.
ApplyVertexToEffectSemanticMapping(mat.first->mTexDiffuse, *table); ApplyVertexToEffectSemanticMapping(mat.first->mTexDiffuse, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexAmbient, *table); ApplyVertexToEffectSemanticMapping(mat.first->mTexAmbient, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexSpecular, *table); ApplyVertexToEffectSemanticMapping(mat.first->mTexSpecular, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexEmissive, *table); ApplyVertexToEffectSemanticMapping(mat.first->mTexEmissive, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexTransparent, *table); ApplyVertexToEffectSemanticMapping(mat.first->mTexTransparent, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexBump, *table); ApplyVertexToEffectSemanticMapping(mat.first->mTexBump, *table);
} else {
ASSIMP_LOG_WARN("Collada: Ignoring material mapping for mesh \"", mid.mMeshOrController, "\". Material index ", matIdx, " is out of bounds (newMats.size()=", newMats.size(), ").");
}
} }
// built lookup index of the Mesh-Submesh-Material combination // built lookup index of the Mesh-Submesh-Material combination

View File

@@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
#include <algorithm>
#include "FBXParser.h" #include "FBXParser.h"
#include "FBXDocument.h" #include "FBXDocument.h"
#include "FBXMeshGeometry.h" #include "FBXMeshGeometry.h"
@@ -144,8 +146,10 @@ BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc,
for (const Connection* con : conns) { for (const Connection* con : conns) {
const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element); const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
if (bspc) { if (bspc) {
auto pr = blendShapeChannels.insert(bspc); // Only add a channel if it doesn't exist already
if (!pr.second) { if (std::find(blendShapeChannels.begin(), blendShapeChannels.end(), bspc) == blendShapeChannels.end()) {
blendShapeChannels.push_back(bspc);
} else {
FBXImporter::LogWarn("there is the same blendShapeChannel id ", bspc->ID()); FBXImporter::LogWarn("there is the same blendShapeChannel id ", bspc->ID());
} }
} }
@@ -170,8 +174,10 @@ BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const
for (const Connection* con : conns) { for (const Connection* con : conns) {
const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element); const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
if (sg) { if (sg) {
auto pr = shapeGeometries.insert(sg); // Only add a geometry if it doesn't exist already
if (!pr.second) { if (std::find(shapeGeometries.begin(), shapeGeometries.end(), sg) == shapeGeometries.end()) {
shapeGeometries.push_back(sg);
} else {
FBXImporter::LogWarn("there is the same shapeGeometrie id ", sg->ID()); FBXImporter::LogWarn("there is the same shapeGeometrie id ", sg->ID());
} }
} }

View File

@@ -865,14 +865,14 @@ public:
return fullWeights; return fullWeights;
} }
const std::unordered_set<const ShapeGeometry*>& GetShapeGeometries() const { const std::vector<const ShapeGeometry*>& GetShapeGeometries() const {
return shapeGeometries; return shapeGeometries;
} }
private: private:
float percent; float percent;
WeightArray fullWeights; WeightArray fullWeights;
std::unordered_set<const ShapeGeometry*> shapeGeometries; std::vector<const ShapeGeometry*> shapeGeometries;
}; };
/** DOM class for BlendShape deformers */ /** DOM class for BlendShape deformers */
@@ -882,12 +882,12 @@ public:
virtual ~BlendShape() = default; virtual ~BlendShape() = default;
const std::unordered_set<const BlendShapeChannel*>& BlendShapeChannels() const { const std::vector<const BlendShapeChannel*>& BlendShapeChannels() const {
return blendShapeChannels; return blendShapeChannels;
} }
private: private:
std::unordered_set<const BlendShapeChannel*> blendShapeChannels; std::vector<const BlendShapeChannel*> blendShapeChannels;
}; };
/** DOM class for skin deformer clusters (aka sub-deformers) */ /** DOM class for skin deformer clusters (aka sub-deformers) */

View File

@@ -90,7 +90,7 @@ namespace {
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool FBXImporter::CanRead(const std::string & pFile, IOSystem * pIOHandler, bool /*checkSig*/) const { bool FBXImporter::CanRead(const std::string & pFile, IOSystem * pIOHandler, bool /*checkSig*/) const {
// at least ASCII-FBX files usually have a 'FBX' somewhere in their head // at least ASCII-FBX files usually have a 'FBX' somewhere in their head
static const char *tokens[] = { " \n\r\n " }; static const char *tokens[] = { " \n\r\n ", "fbx" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens)); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
} }

View File

@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
#include <algorithm>
#include <functional> #include <functional>
#include "FBXMeshGeometry.h" #include "FBXMeshGeometry.h"
@@ -69,8 +70,10 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
} }
const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element); const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element);
if (bsp) { if (bsp) {
auto pr = blendShapes.insert(bsp); // Only add a blendshape if it doesn't exist already
if (!pr.second) { if (std::find(blendShapes.begin(), blendShapes.end(), bsp) == blendShapes.end()) {
blendShapes.push_back(bsp);
} else {
FBXImporter::LogWarn("there is the same blendShape id ", bsp->ID()); FBXImporter::LogWarn("there is the same blendShape id ", bsp->ID());
} }
} }
@@ -78,7 +81,7 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const std::unordered_set<const BlendShape*>& Geometry::GetBlendShapes() const { const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const {
return blendShapes; return blendShapes;
} }

View File

@@ -72,11 +72,11 @@ public:
/// @brief Get the BlendShape attached to this geometry or nullptr /// @brief Get the BlendShape attached to this geometry or nullptr
/// @return The blendshape arrays. /// @return The blendshape arrays.
const std::unordered_set<const BlendShape*>& GetBlendShapes() const; const std::vector<const BlendShape*>& GetBlendShapes() const;
private: private:
const Skin* skin; const Skin* skin;
std::unordered_set<const BlendShape*> blendShapes; std::vector<const BlendShape*> blendShapes;
}; };

View File

@@ -36,7 +36,6 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#if !defined ASSIMP_BUILD_NO_M3D_IMPORTER || !(defined ASSIMP_BUILD_NO_EXPORT || defined ASSIMP_BUILD_NO_M3D_EXPORTER) #if !defined ASSIMP_BUILD_NO_M3D_IMPORTER || !(defined ASSIMP_BUILD_NO_EXPORT || defined ASSIMP_BUILD_NO_M3D_EXPORTER)
@@ -103,15 +102,68 @@ M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &b
ai_assert(nullptr != pIOHandler); ai_assert(nullptr != pIOHandler);
} }
// Security fix: Validate buffer size and content before processing
if (buffer.empty()) {
ASSIMP_LOG_ERROR("M3D: Empty buffer provided");
m3d_ = nullptr;
return;
}
// Check for minimum valid M3D file size (header + basic structure)
const size_t MIN_VALID_M3D_SIZE = 100; // Minimum reasonable size for a valid M3D file
if (buffer.size() < MIN_VALID_M3D_SIZE) {
ASSIMP_LOG_ERROR("M3D: Buffer too small to be a valid M3D file");
m3d_ = nullptr;
return;
}
// Validate M3D magic signature to ensure this is actually an M3D file
// M3D files should start with "3DMO" or "3dmo" magic signature
if (buffer.size() >= 4) {
bool valid_signature = false;
// Check for "3DMO" (uppercase)
if (buffer[0] == '3' && buffer[1] == 'D' && buffer[2] == 'M' && buffer[3] == 'O') {
valid_signature = true;
}
// Check for "3dmo" (lowercase)
else if (buffer[0] == '3' && buffer[1] == 'd' && buffer[2] == 'm' && buffer[3] == 'o') {
valid_signature = true;
}
if (!valid_signature) {
ASSIMP_LOG_ERROR("M3D: Invalid file signature - not a valid M3D file");
m3d_ = nullptr;
return;
}
}
// Create a safe copy of the buffer with guard pages/validation
// This helps prevent buffer overflows from affecting the main process
std::vector<unsigned char> safe_buffer = buffer;
// Add a guard page at the end to catch any overflow attempts
// Note: This is a defensive measure, not a complete fix for the underlying issue
safe_buffer.resize(safe_buffer.size() + 1);
safe_buffer.back() = 0xFF; // Guard byte
#ifdef ASSIMP_USE_M3D_READFILECB #ifdef ASSIMP_USE_M3D_READFILECB
// pass this IOHandler to the C callback in a thread-local pointer // pass this IOHandler to the C callback in a thread-local pointer
m3dimporter_pIOHandler = pIOHandler; m3dimporter_pIOHandler = pIOHandler;
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), m3dimporter_readfile, free, nullptr); m3d_ = m3d_load(const_cast<unsigned char *>(safe_buffer.data()), m3dimporter_readfile, free, nullptr);
// Clear the C callback // Clear the C callback
m3dimporter_pIOHandler = nullptr; m3dimporter_pIOHandler = nullptr;
#else #else
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), nullptr, nullptr, nullptr); m3d_ = m3d_load(const_cast<unsigned char *>(safe_buffer.data()), nullptr, nullptr, nullptr);
#endif #endif
// Verify the guard byte wasn't overwritten (indicating potential buffer overflow)
if (safe_buffer.empty() || safe_buffer.back() != 0xFF) {
ASSIMP_LOG_ERROR("M3D: Potential buffer overflow detected during loading");
if (m3d_) {
m3d_free(m3d_);
m3d_ = nullptr;
}
}
} }
M3DWrapper::~M3DWrapper() { M3DWrapper::~M3DWrapper() {

View File

@@ -72,7 +72,7 @@ public:
/// Construct an M3D model from provided buffer /// Construct an M3D model from provided buffer
/// @note The m3d.h SDK function does not mark the data as const. Have assumed it does not write. /// @note The m3d.h SDK function does not mark the data as const. Have assumed it does not write.
/// BUG: SECURITY: The m3d.h SDK cannot be informed of the buffer size. BUFFER OVERFLOW IS CERTAIN /// SECURITY: Buffer size validation and guard pages added to mitigate potential overflows
explicit M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer); explicit M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer);
/// Theclasss destructor. /// Theclasss destructor.

View File

@@ -1038,21 +1038,27 @@ size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remap
const size_t maxSize = GetMaxByteSize(); const size_t maxSize = GetMaxByteSize();
if (elemSize > maxSize) {
throw DeadlyImportError("GLTF: elemSize ", elemSize, " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
}
const size_t maxCount = (maxSize - elemSize) / stride + 1;
if (count > maxCount) {
throw DeadlyImportError("GLTF: count ", count, " > maxCount ", maxCount, " in ", getContextForErrorMessages(id, name));
}
outData = new T[usedCount]; outData = new T[usedCount];
if (remappingIndices != nullptr) { if (remappingIndices != nullptr) {
const unsigned int maxIndexCount = static_cast<unsigned int>(maxSize / stride);
for (size_t i = 0; i < usedCount; ++i) { for (size_t i = 0; i < usedCount; ++i) {
size_t srcIdx = (*remappingIndices)[i]; size_t srcIdx = (*remappingIndices)[i];
if (srcIdx >= maxIndexCount) { if (srcIdx >= count) {
throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name)); throw DeadlyImportError("GLTF: index ", srcIdx, " >= count ", count, " in ", getContextForErrorMessages(id, name));
} }
memcpy(outData + i, data + srcIdx * stride, elemSize); memcpy(outData + i, data + srcIdx * stride, elemSize);
} }
} else { // non-indexed cases } else { // non-indexed cases
if (usedCount * stride > maxSize) {
throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
}
if (stride == elemSize && targetElemSize == elemSize) { if (stride == elemSize && targetElemSize == elemSize) {
memcpy(outData, data, totalSize); memcpy(outData, data, totalSize);
} else { } else {

View File

@@ -556,12 +556,6 @@ void glTF2Exporter::GetMatTexProp(const aiMaterial &mat, unsigned int &prop, con
mat.Get(textureKey.c_str(), tt, slot, prop); mat.Get(textureKey.c_str(), tt, slot, prop);
} }
void glTF2Exporter::GetMatTexProp(const aiMaterial &mat, float &prop, const char *propName, aiTextureType tt, unsigned int slot) {
std::string textureKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName;
mat.Get(textureKey.c_str(), tt, slot, prop);
}
void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot = 0) { void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot = 0) {
if (mat.GetTextureCount(tt) == 0) { if (mat.GetTextureCount(tt) == 0) {
return; return;
@@ -652,7 +646,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, NormalTextureInfo &prop, ai
if (texture) { if (texture) {
// GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); // GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
GetMatTexProp(mat, prop.scale, "scale", tt, slot); mat.Get(AI_MATKEY_GLTF_TEXTURE_SCALE(tt, slot), prop.scale);
} }
} }
@@ -663,7 +657,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, OcclusionTextureInfo &prop,
if (texture) { if (texture) {
// GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); // GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
GetMatTexProp(mat, prop.strength, "strength", tt, slot); mat.Get(AI_MATKEY_GLTF_TEXTURE_STRENGTH(tt, slot), prop.strength);
} }
} }

View File

@@ -110,7 +110,6 @@ protected:
void WriteBinaryData(IOStream *outfile, std::size_t sceneLength); void WriteBinaryData(IOStream *outfile, std::size_t sceneLength);
void GetTexSampler(const aiMaterial &mat, glTFCommon::Ref<glTF2::Texture> texture, aiTextureType tt, unsigned int slot); void GetTexSampler(const aiMaterial &mat, glTFCommon::Ref<glTF2::Texture> texture, aiTextureType tt, unsigned int slot);
void GetMatTexProp(const aiMaterial &mat, unsigned int &prop, const char *propName, aiTextureType tt, unsigned int idx); void GetMatTexProp(const aiMaterial &mat, unsigned int &prop, const char *propName, aiTextureType tt, unsigned int idx);
void GetMatTexProp(const aiMaterial &mat, float &prop, const char *propName, aiTextureType tt, unsigned int idx);
void GetMatTex(const aiMaterial &mat, glTFCommon::Ref<glTF2::Texture> &texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot); void GetMatTex(const aiMaterial &mat, glTFCommon::Ref<glTF2::Texture> &texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot);
void GetMatTex(const aiMaterial &mat, glTF2::TextureInfo &prop, aiTextureType tt, unsigned int slot); void GetMatTex(const aiMaterial &mat, glTF2::TextureInfo &prop, aiTextureType tt, unsigned int slot);
void GetMatTex(const aiMaterial &mat, glTF2::NormalTextureInfo &prop, aiTextureType tt, unsigned int slot); void GetMatTex(const aiMaterial &mat, glTF2::NormalTextureInfo &prop, aiTextureType tt, unsigned int slot);

View File

@@ -237,8 +237,7 @@ static void SetMaterialTextureProperty(std::vector<int> &embeddedTexIdxs, Asset
SetMaterialTextureProperty(embeddedTexIdxs, r, static_cast<TextureInfo>(prop), mat, texType, texSlot); SetMaterialTextureProperty(embeddedTexIdxs, r, static_cast<TextureInfo>(prop), mat, texType, texSlot);
if (prop.texture && prop.texture->source) { if (prop.texture && prop.texture->source) {
std::string textureStrengthKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + "strength"; mat->AddProperty(&prop.strength, 1, AI_MATKEY_GLTF_TEXTURE_STRENGTH(texType, texSlot));
mat->AddProperty(&prop.strength, 1, textureStrengthKey.c_str(), texType, texSlot);
} }
} }

View File

@@ -58,11 +58,55 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stack> #include <stack>
namespace Assimp { namespace Assimp {
namespace {
ai_real calculateInputACMR(aiMesh *pMesh, const aiFace *const pcEnd,
unsigned int configCacheDepth, unsigned int meshNum) {
ai_real fACMR = 0.0f;
unsigned int *piFIFOStack = new unsigned int[configCacheDepth];
memset(piFIFOStack, 0xff, configCacheDepth * sizeof(unsigned int));
unsigned int *piCur = piFIFOStack;
const unsigned int *const piCurEnd = piFIFOStack + configCacheDepth;
// count the number of cache misses
unsigned int iCacheMisses = 0;
for (const aiFace *pcFace = pMesh->mFaces; pcFace != pcEnd; ++pcFace) {
for (unsigned int qq = 0; qq < 3; ++qq) {
bool bInCache = false;
for (unsigned int *pp = piFIFOStack; pp < piCurEnd; ++pp) {
if (*pp == pcFace->mIndices[qq]) {
// the vertex is in cache
bInCache = true;
break;
}
}
if (!bInCache) {
++iCacheMisses;
if (piCurEnd == piCur) {
piCur = piFIFOStack;
}
*piCur++ = pcFace->mIndices[qq];
}
}
}
delete[] piFIFOStack;
fACMR = (ai_real)iCacheMisses / pMesh->mNumFaces;
if (3.0 == fACMR) {
char szBuff[128]; // should be sufficiently large in every case
// the JoinIdenticalVertices process has not been executed on this
// mesh, otherwise this value would normally be at least minimally
// smaller than 3.0 ...
ai_snprintf(szBuff, 128, "Mesh %u: Not suitable for vcache optimization", meshNum);
ASSIMP_LOG_WARN(szBuff);
return static_cast<ai_real>(0.f);
}
return fACMR;
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() : ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() : mConfigCacheDepth(PP_ICL_PTCACHE_SIZE) {
mConfigCacheDepth(PP_ICL_PTCACHE_SIZE) {
// empty // empty
} }
@@ -107,51 +151,6 @@ void ImproveCacheLocalityProcess::Execute(aiScene *pScene) {
} }
} }
// ------------------------------------------------------------------------------------------------
static ai_real calculateInputACMR(aiMesh *pMesh, const aiFace *const pcEnd,
unsigned int configCacheDepth, unsigned int meshNum) {
ai_real fACMR = 0.0f;
unsigned int *piFIFOStack = new unsigned int[configCacheDepth];
memset(piFIFOStack, 0xff, configCacheDepth * sizeof(unsigned int));
unsigned int *piCur = piFIFOStack;
const unsigned int *const piCurEnd = piFIFOStack + configCacheDepth;
// count the number of cache misses
unsigned int iCacheMisses = 0;
for (const aiFace *pcFace = pMesh->mFaces; pcFace != pcEnd; ++pcFace) {
for (unsigned int qq = 0; qq < 3; ++qq) {
bool bInCache = false;
for (unsigned int *pp = piFIFOStack; pp < piCurEnd; ++pp) {
if (*pp == pcFace->mIndices[qq]) {
// the vertex is in cache
bInCache = true;
break;
}
}
if (!bInCache) {
++iCacheMisses;
if (piCurEnd == piCur) {
piCur = piFIFOStack;
}
*piCur++ = pcFace->mIndices[qq];
}
}
}
delete[] piFIFOStack;
fACMR = (ai_real)iCacheMisses / pMesh->mNumFaces;
if (3.0 == fACMR) {
char szBuff[128]; // should be sufficiently large in every case
// the JoinIdenticalVertices process has not been executed on this
// mesh, otherwise this value would normally be at least minimally
// smaller than 3.0 ...
ai_snprintf(szBuff, 128, "Mesh %u: Not suitable for vcache optimization", meshNum);
ASSIMP_LOG_WARN(szBuff);
return static_cast<ai_real>(0.f);
}
return fACMR;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Improves the cache coherency of a specific mesh // Improves the cache coherency of a specific mesh
ai_real ImproveCacheLocalityProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshNum) { ai_real ImproveCacheLocalityProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshNum) {

View File

@@ -182,7 +182,7 @@ public:
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
/// Get the remaining stream size (to the end of the stream) /// Get the remaining stream size (to the end of the stream)
size_t GetRemainingSize() const { size_t GetRemainingSize() const {
return (unsigned int)(mEnd - mCurrent); return static_cast<size_t>(mEnd - mCurrent);
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@@ -190,16 +190,29 @@ public:
* return value is the remaining size of the stream if no custom * return value is the remaining size of the stream if no custom
* read limit has been set. */ * read limit has been set. */
size_t GetRemainingSizeToLimit() const { size_t GetRemainingSizeToLimit() const {
return (unsigned int)(mLimit - mCurrent); return static_cast<size_t>(mLimit - mCurrent);
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
/** Increase the file pointer (relative seeking) */ /** Increase the file pointer (relative seeking) */
void IncPtr(intptr_t plus) { void IncPtr(intptr_t plus) {
mCurrent += plus; // Ensure internal pointer invariants hold
if (mCurrent > mLimit) { if (mCurrent < mBuffer || mCurrent > mLimit) {
throw DeadlyImportError("End of file or read limit was reached"); throw DeadlyImportError("StreamReader: Invalid internal pointer state");
} }
if (plus < 0) {
const size_t absPlus = static_cast<size_t>(-(plus + 1)) + 1;
if (absPlus > static_cast<size_t>(mCurrent - mBuffer)) {
throw DeadlyImportError("StreamReader: Attempted to seek outside buffer bounds");
}
} else if (plus > 0) {
if (static_cast<size_t>(plus) > static_cast<size_t>(mLimit - mCurrent)) {
throw DeadlyImportError("StreamReader: Attempted to seek outside buffer bounds");
}
}
mCurrent += plus;
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@@ -233,8 +246,9 @@ public:
} }
/// @brief Get the current offset from the beginning of the file /// @brief Get the current offset from the beginning of the file
/// @return The current offset from the beginning of the file.
int GetCurrentPos() const { int GetCurrentPos() const {
return (unsigned int)(mCurrent - mBuffer); return static_cast<int>(mCurrent - mBuffer);
} }
void SetCurrentPos(size_t pos) { void SetCurrentPos(size_t pos) {
@@ -244,10 +258,10 @@ public:
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
/** Setup a temporary read limit /** Setup a temporary read limit
* *
* @param limit Maximum number of bytes to be read from * @param _limit Maximum number of bytes to be read from
* the beginning of the file. Specifying UINT_MAX * the beginning of the file. Specifying UINT_MAX
* resets the limit to the original end of the stream. * resets the limit to the original end of the stream.
* Returns the previously set limit. */ * @return The previously set limit. */
unsigned int SetReadLimit(unsigned int _limit) { unsigned int SetReadLimit(unsigned int _limit) {
unsigned int prev = GetReadLimit(); unsigned int prev = GetReadLimit();
if (UINT_MAX == _limit) { if (UINT_MAX == _limit) {
@@ -264,9 +278,10 @@ public:
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
/** Get the current read limit in bytes. Reading over this limit /** Get the current read limit in bytes. Reading over this limit
* accidentally raises an exception. */ * accidentally raises an exception.
* @return The current limit. */
unsigned int GetReadLimit() const { unsigned int GetReadLimit() const {
return (unsigned int)(mLimit - mBuffer); return static_cast<unsigned int>(mLimit - mBuffer);
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------

View File

@@ -1,6 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "assimp_rs"
version = "0.1.0"

View File

@@ -6,4 +6,5 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [build-dependencies]
bindgen = "*"

40
port/assimp_rs/build.rs Normal file
View File

@@ -0,0 +1,40 @@
extern crate bindgen;
use std::env;
use std::path::PathBuf;
fn main() {
// Rerun if wrapper header changes
println!("cargo:rerun-if-changed=./src/assimp_wrapper.h");
// Tell cargo to look for shared libraries in the specified directory
println!("cargo:rustc-link-search=../../bin/");
// Tell cargo to tell rustc to link the assimp shared library.
println!("cargo:rustc-link-lib=assimp");
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header("./src/assimp_wrapper.h").clang_arg("-I../../include/")
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.blocklist_item("FP_ZERO")
.blocklist_item("FP_SUBNORMAL")
.blocklist_item("FP_NORMAL")
.blocklist_item("FP_INFINITE")
.blocklist_item("FP_NAN")
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}

View File

@@ -0,0 +1,48 @@
#ifndef ASSIMP_WRAPPER_H_INC
#define ASSIMP_WRAPPER_H_INC
#include <assimp/defs.h>
#include <assimp/camera.h>
#include <assimp/scene.h>
#include <assimp/types.h>
#include <assimp/vector3.h>
#include <assimp/matrix4x4.h>
#include <assimp/quaternion.h>
#include <assimp/color4.h>
#include <assimp/mesh.h>
#include <assimp/anim.h>
#include <assimp/metadata.h>
#include <assimp/light.h>
#include <assimp/material.h>
#include <assimp/texture.h>
#include <assimp/postprocess.h>
#include <assimp/version.h>
#include <assimp/importerdesc.h>
#include <assimp/aabb.h>
#include <assimp/anim.h>
#include <assimp/camera.h>
#include <assimp/cexport.h>
#include <assimp/cfileio.h>
#include <assimp/cimport.h>
#include <assimp/color4.h>
#include <assimp/commonMetaData.h>
#include <assimp/defs.h>
#include <assimp/importerdesc.h>
#include <assimp/light.h>
#include <assimp/material.h>
#include <assimp/matrix3x3.h>
#include <assimp/matrix4x4.h>
#include <assimp/mesh.h>
#include <assimp/metadata.h>
#include <assimp/pbrmaterial.h>
#include <assimp/postprocess.h>
#include <assimp/quaternion.h>
#include <assimp/revision.h>
#include <assimp/scene.h>
#include <assimp/texture.h>
#include <assimp/types.h>
#include <assimp/vector2.h>
#include <assimp/vector3.h>
#include <assimp/version.h>
#endif // ASSIMP_WRAPPER_H_INC

View File

@@ -1 +0,0 @@
pub use self::structs::{Camera};

View File

@@ -1,17 +1,21 @@
pub mod camera;
pub mod core; #![allow(non_upper_case_globals)]
pub mod errors; #![allow(non_camel_case_types)]
pub mod formats; #![allow(non_snake_case)]
pub mod material;
pub mod postprocess; include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
pub mod shims;
pub mod socket;
pub mod structs;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#[test] #[test]
fn it_works() { fn import_test() {
assert_eq!(true, true); unsafe {
use crate::aiImportFile;
let mut file: *mut dyn const i8 = std::ptr::null_mut();
//let file = String::from("test.obj");
//let (ptr, len, cap) = file.into_raw_parts();
//let raw_file = unsafe{String::from_raw_parts}
let asset = aiImportFile(file, 0);
}
} }
} }

View File

@@ -1,44 +0,0 @@
pub struct Animation<'mA, 'mMA, 'nA> {
/* The name of the animation. If the modeling package this data was
* exported from does support only a single animation channel, this
* name is usually empty (length is zero).
*/
m_name: Option<String>,
// Duration of the animation in ticks
m_duration: f64,
// Ticks per second. Zero (0.000... ticks/second) if not
// specified in the imported file
m_ticks_per_second: Option<f64>,
/* Number of bone animation channels.
Each channel affects a single node.
*/
m_num_channels: u64,
/* Node animation channels. Each channel
affects a single node.
?? -> The array is m_num_channels in size.
(maybe refine to a derivative type of usize?)
*/
m_channels: &'nA NodeAnim,
/* Number of mesh animation channels. Each
channel affects a single mesh and defines
vertex-based animation.
*/
m_num_mesh_channels: u64,
/* The mesh animation channels. Each channel
affects a single mesh.
The array is m_num_mesh_channels in size
(maybe refine to a derivative of usize?)
*/
m_mesh_channels: &'mA MeshAnim,
/* The number of mesh animation channels. Each channel
affects a single mesh and defines some morphing animation.
*/
m_num_morph_mesh_channels: u64,
/* The morph mesh animation channels. Each channel affects a single mesh.
The array is mNumMorphMeshChannels in size.
*/
m_morph_mesh_channels: &'mMA MeshMorphAnim
}
pub struct NodeAnim {}
pub struct MeshAnim {}
pub struct MeshMorphAnim {}

View File

@@ -1,6 +0,0 @@
mod anim;
pub use self::anim::{
Animation,
NodeAnim,
MeshAnim,
MeshMorphAnim};

View File

@@ -1,2 +0,0 @@
mod blob;

View File

@@ -1,2 +0,0 @@
mod bone;

View File

@@ -1,2 +0,0 @@
mod camera;

View File

@@ -1,27 +0,0 @@
#[derive(Clone, Debug, Copy)]
struct Color3D {
r: f32,
g: f32,
b: f32
}
impl Color3D {
pub fn new(r_f32: f32, g_f32: f32, b_f32: f32) -> Color3D {
Color3D {r: r_f32, g: g_f32, b: b_f32 }
}
}
#[derive(Clone, Debug, Copy)]
struct Color4D {
r: f32,
g: f32,
b: f32,
a: f32
}
impl Color4D {
pub fn new(r_f32: f32, g_f32: f32, b_f32: f32, a_f32: f32) -> Color4D {
Color4D {r: r_f32, g: g_f32, b: b_f32, a: a_f32 }
}
}

View File

@@ -1,5 +0,0 @@
mod color;
pub use self::color::{
Color3D,
Color4D
};

View File

@@ -1,2 +0,0 @@
mod face;

View File

@@ -1,2 +0,0 @@
mod key;

View File

@@ -1,2 +0,0 @@
mod light;

View File

@@ -1,2 +0,0 @@
mod material;

View File

@@ -1,64 +0,0 @@
#[derive(Clone, Debug, Copy)]
struct Matrix3x3 {
a1: f32,
a2: f32,
a3: f32,
b1: f32,
b2: f32,
b3: f32,
c1: f32,
c2: f32,
c3: f32
}
#[derive(Clone, Debug, Copy)]
struct Matrix4x4 {
a1: f32,
a2: f32,
a3: f32,
a4: f32,
b1: f32,
b2: f32,
b3: f32,
b4: f32,
c1: f32,
c2: f32,
c3: f32,
c4: f32,
d1: f32,
d2: f32,
d3: f32,
d4: f32
}
impl Matrix3x3 {
pub fn new(
a1_f32: f32, a2_f32: f32, a3_f32: f32,
b1_f32: f32, b2_f32: f32, b3_f32: f32,
c1_f32: f32, c2_f32: f32, c3_f32: f32
) -> Matrix3x3 {
Matrix3x3 {
a1: a1_f32, a2: a2_f32, a3: a3_f32,
b1: b1_f32, b2: b2_f32, b3: b3_f32,
c1: c1_f32, c2: c2_f32, c3: c3_f32
}
}
}
impl Matrix4x4 {
pub fn new(
a1_f32: f32, a2_f32: f32, a3_f32: f32, a4_f32: f32,
b1_f32: f32, b2_f32: f32, b3_f32: f32, b4_f32: f32,
c1_f32: f32, c2_f32: f32, c3_f32: f32, c4_f32: f32,
d1_f32: f32, d2_f32: f32, d3_f32: f32, d4_f32: f32
) -> Matrix4x4 {
Matrix4x4 {
a1: a1_f32, a2: a2_f32, a3: a3_f32, a4: a4_f32,
b1: b1_f32, b2: b2_f32, b3: b3_f32, b4: b4_f32,
c1: c1_f32, c2: c2_f32, c3: c3_f32, c4: c4_f32,
d1: d1_f32, d2: d2_f32, d3: d3_f32, d4: d4_f32
}
}
}

View File

@@ -1,4 +0,0 @@
mod matrix;
pub use self::matrix::{
Matrix3x3,
Matrix4x4};

View File

@@ -1,35 +0,0 @@
#[derive(Clone, Debug, Copy)]
struct MemoryInfo {
textures: u32,
materials: u32,
meshes: u32,
nodes: u32,
animations: u32,
cameras: u32,
lights: u32,
total: u32
}
impl MemoryInfo {
pub fn new(
textures_uint: u32,
materials_uint: u32,
meshes_uint: u32,
nodes_uint: u32,
animations_uint: u32,
cameras_uint: u32,
lights_uint: u32,
total_uint: u32) -> MemoryInfo {
MemoryInfo {
textures: textures_uint,
materials: materials_uint,
meshes: meshes_uint,
nodes: nodes_uint,
animations: animations_uint,
cameras: cameras_uint,
lights: lights_uint,
total: total_uint
}
}
}

View File

@@ -1,2 +0,0 @@
mod memory;
pub use self::memory::MemoryInfo;

View File

@@ -1,3 +0,0 @@
mod mesh;

View File

@@ -1,2 +0,0 @@
mod meta;

View File

@@ -1,61 +0,0 @@
mod anim;
/* Animation
* NodeAnim
* MeshAnim
* MeshMorphAnim
*/
mod blob;
/* ExportDataBlob
*/
mod vec;
/* Vector2d
* Vector3d
* */
mod matrix;
/* Matrix3by3
* Matrix4by4
*/
mod camera;
/* Camera */
mod color;
/* Color3d
* Color4d
*/
mod key;
/* MeshKey
* MeshMorphKey
* QuatKey
* VectorKey
*/
mod texel;
mod plane;
mod string;
/* String
*/
mod material;
/* Material
* MaterialPropery
* MaterialPropertyString
*/
mod mem;
mod quaternion;
mod face;
mod vertex_weight;
mod mesh;
/* Mesh
*/
mod meta;
/* Metadata
* MetadataEntry
*/
mod node;
/* Node
* */
mod light;
mod texture;
mod ray;
mod transform;
/* UVTransform */
mod bone;
mod scene;
/* Scene */

View File

@@ -1,2 +0,0 @@
mod node;

View File

@@ -1,2 +0,0 @@
mod plane;

View File

@@ -1,23 +0,0 @@
#[derive(Clone, Debug, Copy)]
struct Plane {
a: f32,
b: f32,
c: f32,
d: f32
}
impl Plane {
pub fn new(
a_f32: f32,
b_f32: f32,
c_f32: f32,
d_f32: f32
) -> Plane {
Plane {
a: a_f32,
b: b_f32,
c: b_f32,
d: d_f32
}
}
}

View File

@@ -1,3 +0,0 @@
mod quaternion;
pub use self::quaternion::Quaternion;

View File

@@ -1,7 +0,0 @@
use crate::vec;
#[derive(Clone, Debug, Copy)]
pub struct Quaternion {
_coordinates: vec::Vector4d
}

View File

@@ -1,2 +0,0 @@
mod ray;

View File

@@ -1,2 +0,0 @@
mod scene;

View File

@@ -1,3 +0,0 @@
mod string;
pub use self::string::MAXLEN;
pub use self::string::Str;

View File

@@ -1,41 +0,0 @@
pub const MAXLEN: usize = 1024;
/// Want to consider replacing `Vec<char>`
/// with a comparable definition at
/// https://doc.rust-lang.org/src/alloc/string.rs.html#415-417
#[derive(Clone, Debug)]
struct Str {
length: usize,
data: Vec<char>
}
impl Str {
pub fn new(len_u32: usize, data_string: String) -> Str {
Str {
length: len_u32,
data: data_string.chars().collect()
}
}
}
/// MaterialPropertyStr
/// The size of length is truncated to 4 bytes on a 64-bit platform when used as a
/// material property (see MaterialSystem.cpp, as aiMaterial::AddProperty() ).
#[derive(Clone, Debug)]
struct MaterialPropertyStr {
length: usize,
data: Vec<char>
}
impl MaterialPropertyStr {
pub fn new(len_u32: usize, data_string: String) -> MaterialPropertyStr {
MaterialPropertyStr {
length: len_u32,
data: data_string.chars().collect()
}
}
}

View File

@@ -1,3 +0,0 @@
mod texture;
pub use self::texture::Texel;

View File

@@ -1,19 +0,0 @@
#[derive(Clone, Debug, Copy)]
struct Texel {
b: u32,
g: u32,
r: u32,
a: u32
}
impl Texel {
pub fn new(b_u32: u32, g_u32: u32,
r_u32: u32, a_u32: u32) -> Texel {
Texel {
b: b_u32,
g: g_u32,
r: r_u32,
a: a_u32
}
}
}

View File

@@ -1,2 +0,0 @@
mod transform;

View File

@@ -1,2 +0,0 @@
mod vec;

View File

@@ -1,48 +0,0 @@
struct Vector2d {
x: f32,
y: f32
}
struct Vector3d {
x: f32,
y: f32,
z: f32
}
struct Vector4d {
x: f32,
y: f32,
z: f32,
w: f32
}
impl Vector2d {
pub fn new(x_f32: f32, y_f32: f32) -> Vector2d {
Vector2d {
x: x_f32,
y: y_f32
}
}
}
impl Vector3d {
pub fn new(x_f32: f32, y_f32: f32, z_f32: f32) -> Vector3d {
Vector3d {
x: x_f32,
y: y_f32,
z: z_f32
}
}
}
impl Vector4d {
pub fn new(x_f32: f32, y_f32: f32, z_f32: f32, w_f32: f32) -> Vector4d {
Vector4d {
x: x_f32,
y: y_f32,
z: z_f32,
w: w_f32
}
}
}

View File

@@ -1,2 +0,0 @@
mod vertex;
// pub use self::vertex::