Compare commits
13 Commits
6588-bug-i
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
392a658f9c | ||
|
|
11a5d1b8ef | ||
|
|
9e56e52252 | ||
|
|
86ae4876fb | ||
|
|
fb9a58735d | ||
|
|
25a1318534 | ||
|
|
ede83d7fe2 | ||
|
|
17c12da558 | ||
|
|
de77101866 | ||
|
|
158da57515 | ||
|
|
021bbff3e5 | ||
|
|
9c10e7d2b5 | ||
|
|
048becec92 |
2
.github/workflows/ccpp.yml
vendored
2
.github/workflows/ccpp.yml
vendored
@@ -182,7 +182,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
steps:
|
||||
- uses: softprops/action-gh-release@v2
|
||||
- uses: softprops/action-gh-release@v3
|
||||
with:
|
||||
name: create-release
|
||||
- id: upload-url
|
||||
|
||||
2
.github/workflows/cd.yml
vendored
2
.github/workflows/cd.yml
vendored
@@ -45,7 +45,7 @@ jobs:
|
||||
filename: ${{ matrix.name }}-${{ github.event.release.tag_name }}.zip
|
||||
directory: build/bin/
|
||||
|
||||
- uses: softprops/action-gh-release@v2
|
||||
- uses: softprops/action-gh-release@v3
|
||||
with:
|
||||
files: build/bin/${{ matrix.name }}-${{ github.event.release.tag_name }}.zip
|
||||
append_body: true
|
||||
|
||||
@@ -149,11 +149,18 @@ aiQuaternion Read<aiQuaternion>(IOStream *stream) {
|
||||
template <>
|
||||
aiString Read<aiString>(IOStream *stream) {
|
||||
aiString s;
|
||||
stream->Read(&s.length, 4, 1);
|
||||
if (s.length) {
|
||||
stream->Read(s.data, s.length, 1);
|
||||
uint32_t len;
|
||||
if (stream->Read(&len, 4, 1) != 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;
|
||||
}
|
||||
|
||||
@@ -507,16 +507,20 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
|
||||
}
|
||||
|
||||
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
|
||||
// check whether we have mapping information for it.
|
||||
ApplyVertexToEffectSemanticMapping(mat.first->mTexDiffuse, *table);
|
||||
ApplyVertexToEffectSemanticMapping(mat.first->mTexAmbient, *table);
|
||||
ApplyVertexToEffectSemanticMapping(mat.first->mTexSpecular, *table);
|
||||
ApplyVertexToEffectSemanticMapping(mat.first->mTexEmissive, *table);
|
||||
ApplyVertexToEffectSemanticMapping(mat.first->mTexTransparent, *table);
|
||||
ApplyVertexToEffectSemanticMapping(mat.first->mTexBump, *table);
|
||||
// Iterate through all texture channels assigned to the effect and
|
||||
// check whether we have mapping information for it.
|
||||
ApplyVertexToEffectSemanticMapping(mat.first->mTexDiffuse, *table);
|
||||
ApplyVertexToEffectSemanticMapping(mat.first->mTexAmbient, *table);
|
||||
ApplyVertexToEffectSemanticMapping(mat.first->mTexSpecular, *table);
|
||||
ApplyVertexToEffectSemanticMapping(mat.first->mTexEmissive, *table);
|
||||
ApplyVertexToEffectSemanticMapping(mat.first->mTexTransparent, *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
|
||||
|
||||
@@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "FBXParser.h"
|
||||
#include "FBXDocument.h"
|
||||
#include "FBXMeshGeometry.h"
|
||||
@@ -144,8 +146,10 @@ BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc,
|
||||
for (const Connection* con : conns) {
|
||||
const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
|
||||
if (bspc) {
|
||||
auto pr = blendShapeChannels.insert(bspc);
|
||||
if (!pr.second) {
|
||||
// Only add a channel if it doesn't exist already
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -170,8 +174,10 @@ BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const
|
||||
for (const Connection* con : conns) {
|
||||
const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
|
||||
if (sg) {
|
||||
auto pr = shapeGeometries.insert(sg);
|
||||
if (!pr.second) {
|
||||
// Only add a geometry if it doesn't exist already
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -865,14 +865,14 @@ public:
|
||||
return fullWeights;
|
||||
}
|
||||
|
||||
const std::unordered_set<const ShapeGeometry*>& GetShapeGeometries() const {
|
||||
const std::vector<const ShapeGeometry*>& GetShapeGeometries() const {
|
||||
return shapeGeometries;
|
||||
}
|
||||
|
||||
private:
|
||||
float percent;
|
||||
WeightArray fullWeights;
|
||||
std::unordered_set<const ShapeGeometry*> shapeGeometries;
|
||||
std::vector<const ShapeGeometry*> shapeGeometries;
|
||||
};
|
||||
|
||||
/** DOM class for BlendShape deformers */
|
||||
@@ -882,12 +882,12 @@ public:
|
||||
|
||||
virtual ~BlendShape() = default;
|
||||
|
||||
const std::unordered_set<const BlendShapeChannel*>& BlendShapeChannels() const {
|
||||
const std::vector<const BlendShapeChannel*>& BlendShapeChannels() const {
|
||||
return blendShapeChannels;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_set<const BlendShapeChannel*> blendShapeChannels;
|
||||
std::vector<const BlendShapeChannel*> blendShapeChannels;
|
||||
};
|
||||
|
||||
/** DOM class for skin deformer clusters (aka sub-deformers) */
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace {
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
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
|
||||
static const char *tokens[] = { " \n\r\n " };
|
||||
static const char *tokens[] = { " \n\r\n ", "fbx" };
|
||||
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#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);
|
||||
if (bsp) {
|
||||
auto pr = blendShapes.insert(bsp);
|
||||
if (!pr.second) {
|
||||
// Only add a blendshape if it doesn't exist already
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,11 +72,11 @@ public:
|
||||
|
||||
/// @brief Get the BlendShape attached to this geometry or nullptr
|
||||
/// @return The blendshape arrays.
|
||||
const std::unordered_set<const BlendShape*>& GetBlendShapes() const;
|
||||
const std::vector<const BlendShape*>& GetBlendShapes() const;
|
||||
|
||||
private:
|
||||
const Skin* skin;
|
||||
std::unordered_set<const BlendShape*> blendShapes;
|
||||
std::vector<const BlendShape*> blendShapes;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
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)
|
||||
@@ -103,15 +102,68 @@ M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &b
|
||||
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
|
||||
// pass this IOHandler to the C callback in a thread-local pointer
|
||||
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
|
||||
m3dimporter_pIOHandler = nullptr;
|
||||
#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
|
||||
|
||||
// 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() {
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
|
||||
/// 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.
|
||||
/// 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);
|
||||
|
||||
/// Theclasss destructor.
|
||||
|
||||
@@ -1038,21 +1038,27 @@ size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remap
|
||||
|
||||
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];
|
||||
|
||||
if (remappingIndices != nullptr) {
|
||||
const unsigned int maxIndexCount = static_cast<unsigned int>(maxSize / stride);
|
||||
for (size_t i = 0; i < usedCount; ++i) {
|
||||
size_t srcIdx = (*remappingIndices)[i];
|
||||
if (srcIdx >= maxIndexCount) {
|
||||
throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
|
||||
if (srcIdx >= count) {
|
||||
throw DeadlyImportError("GLTF: index ", srcIdx, " >= count ", count, " in ", getContextForErrorMessages(id, name));
|
||||
}
|
||||
memcpy(outData + i, data + srcIdx * stride, elemSize);
|
||||
}
|
||||
} 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) {
|
||||
memcpy(outData, data, totalSize);
|
||||
} else {
|
||||
|
||||
@@ -556,12 +556,6 @@ void glTF2Exporter::GetMatTexProp(const aiMaterial &mat, unsigned int &prop, con
|
||||
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) {
|
||||
if (mat.GetTextureCount(tt) == 0) {
|
||||
return;
|
||||
@@ -652,7 +646,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, NormalTextureInfo &prop, ai
|
||||
|
||||
if (texture) {
|
||||
// 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) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,6 @@ protected:
|
||||
void WriteBinaryData(IOStream *outfile, std::size_t sceneLength);
|
||||
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, 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, glTF2::TextureInfo &prop, aiTextureType tt, unsigned int slot);
|
||||
void GetMatTex(const aiMaterial &mat, glTF2::NormalTextureInfo &prop, aiTextureType tt, unsigned int slot);
|
||||
|
||||
@@ -237,8 +237,7 @@ static void SetMaterialTextureProperty(std::vector<int> &embeddedTexIdxs, Asset
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, static_cast<TextureInfo>(prop), mat, texType, texSlot);
|
||||
|
||||
if (prop.texture && prop.texture->source) {
|
||||
std::string textureStrengthKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + "strength";
|
||||
mat->AddProperty(&prop.strength, 1, textureStrengthKey.c_str(), texType, texSlot);
|
||||
mat->AddProperty(&prop.strength, 1, AI_MATKEY_GLTF_TEXTURE_STRENGTH(texType, texSlot));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,11 +58,55 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <stack>
|
||||
|
||||
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
|
||||
ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() :
|
||||
mConfigCacheDepth(PP_ICL_PTCACHE_SIZE) {
|
||||
ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() : mConfigCacheDepth(PP_ICL_PTCACHE_SIZE) {
|
||||
// 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
|
||||
ai_real ImproveCacheLocalityProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshNum) {
|
||||
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
// ---------------------------------------------------------------------
|
||||
/// Get the remaining stream size (to the end of the stream)
|
||||
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
|
||||
* read limit has been set. */
|
||||
size_t GetRemainingSizeToLimit() const {
|
||||
return (unsigned int)(mLimit - mCurrent);
|
||||
return static_cast<size_t>(mLimit - mCurrent);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
/** Increase the file pointer (relative seeking) */
|
||||
void IncPtr(intptr_t plus) {
|
||||
mCurrent += plus;
|
||||
if (mCurrent > mLimit) {
|
||||
throw DeadlyImportError("End of file or read limit was reached");
|
||||
// Ensure internal pointer invariants hold
|
||||
if (mCurrent < mBuffer || mCurrent > mLimit) {
|
||||
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
|
||||
/// @return The current offset from the beginning of the file.
|
||||
int GetCurrentPos() const {
|
||||
return (unsigned int)(mCurrent - mBuffer);
|
||||
return static_cast<int>(mCurrent - mBuffer);
|
||||
}
|
||||
|
||||
void SetCurrentPos(size_t pos) {
|
||||
@@ -244,10 +258,10 @@ public:
|
||||
// ---------------------------------------------------------------------
|
||||
/** 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
|
||||
* 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 prev = GetReadLimit();
|
||||
if (UINT_MAX == _limit) {
|
||||
@@ -264,9 +278,10 @@ public:
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
/** 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 {
|
||||
return (unsigned int)(mLimit - mBuffer);
|
||||
return static_cast<unsigned int>(mLimit - mBuffer);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
@@ -299,7 +299,7 @@ typedef unsigned int ai_uint;
|
||||
|
||||
/* Numerical limits */
|
||||
#ifdef __cplusplus
|
||||
constexpr ai_real ai_epsilon = (ai_real) 1e-6;
|
||||
inline constexpr ai_real ai_epsilon = (ai_real) 1e-6;
|
||||
#else
|
||||
# define ai_epsilon ((ai_real)1e-6)
|
||||
#endif
|
||||
|
||||
6
port/assimp_rs/Cargo.lock
generated
6
port/assimp_rs/Cargo.lock
generated
@@ -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"
|
||||
|
||||
@@ -6,4 +6,5 @@ edition = "2018"
|
||||
|
||||
# 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
40
port/assimp_rs/build.rs
Normal 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!");
|
||||
}
|
||||
48
port/assimp_rs/src/assimp_wrapper.h
Normal file
48
port/assimp_rs/src/assimp_wrapper.h
Normal 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
|
||||
@@ -1 +0,0 @@
|
||||
pub use self::structs::{Camera};
|
||||
@@ -1,17 +1,21 @@
|
||||
pub mod camera;
|
||||
pub mod core;
|
||||
pub mod errors;
|
||||
pub mod formats;
|
||||
pub mod material;
|
||||
pub mod postprocess;
|
||||
pub mod shims;
|
||||
pub mod socket;
|
||||
pub mod structs;
|
||||
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn it_works() {
|
||||
assert_eq!(true, true);
|
||||
fn import_test() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
@@ -1,6 +0,0 @@
|
||||
mod anim;
|
||||
pub use self::anim::{
|
||||
Animation,
|
||||
NodeAnim,
|
||||
MeshAnim,
|
||||
MeshMorphAnim};
|
||||
@@ -1,2 +0,0 @@
|
||||
mod blob;
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
mod bone;
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
mod camera;
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
mod color;
|
||||
pub use self::color::{
|
||||
Color3D,
|
||||
Color4D
|
||||
};
|
||||
@@ -1,2 +0,0 @@
|
||||
mod face;
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
mod key;
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
mod light;
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
mod material;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
mod matrix;
|
||||
pub use self::matrix::{
|
||||
Matrix3x3,
|
||||
Matrix4x4};
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
mod memory;
|
||||
pub use self::memory::MemoryInfo;
|
||||
@@ -1,3 +0,0 @@
|
||||
mod mesh;
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
mod meta;
|
||||
|
||||
@@ -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 */
|
||||
@@ -1,2 +0,0 @@
|
||||
mod node;
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
mod plane;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
mod quaternion;
|
||||
|
||||
pub use self::quaternion::Quaternion;
|
||||
@@ -1,7 +0,0 @@
|
||||
use crate::vec;
|
||||
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub struct Quaternion {
|
||||
_coordinates: vec::Vector4d
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
mod ray;
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
mod scene;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
mod string;
|
||||
pub use self::string::MAXLEN;
|
||||
pub use self::string::Str;
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
mod texture;
|
||||
pub use self::texture::Texel;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
mod transform;
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
mod vec;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
mod vertex;
|
||||
// pub use self::vertex::
|
||||
@@ -155,7 +155,7 @@ TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3FromToTest) {
|
||||
const auto from = aiVector3D(1,2,1).Normalize(), to = aiVector3D(-1,1,1).Normalize();
|
||||
aiMatrix3x3::FromToMatrix(from, to, result_cpp);
|
||||
aiMatrix3FromTo(&result_c, &from, &to);
|
||||
EXPECT_EQ(result_cpp, result_c);
|
||||
EXPECT_TRUE(result_cpp.Equal(result_c, Epsilon));
|
||||
}
|
||||
|
||||
TEST_F(AssimpAPITest_aiMatrix3x3, operatorTest) {
|
||||
|
||||
@@ -261,7 +261,7 @@ TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4FromToTest) {
|
||||
const auto from = aiVector3D(1,2,1).Normalize(), to = aiVector3D(-1,1,1).Normalize();
|
||||
aiMatrix4x4::FromToMatrix(from, to, result_cpp);
|
||||
aiMatrix4FromTo(&result_c, &from, &to);
|
||||
EXPECT_EQ(result_cpp, result_c);
|
||||
EXPECT_TRUE(result_cpp.Equal(result_c, Epsilon));
|
||||
}
|
||||
|
||||
TEST_F(AssimpAPITest_aiMatrix4x4, operatorTest) {
|
||||
|
||||
@@ -88,7 +88,10 @@ TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionFromNormalizedQuaternionTest) {
|
||||
const auto qvec3 = random_unit_vec3();
|
||||
result_cpp = aiQuaternion(qvec3);
|
||||
aiQuaternionFromNormalizedQuaternion(&result_c, &qvec3);
|
||||
EXPECT_EQ(result_cpp, result_c);
|
||||
// Use a larger tolerance because FMA contraction differences in
|
||||
// 1.0 - x*x - y*y - z*z can flip the sign of a near-zero residual,
|
||||
// causing w = 0 vs w = sqrt(tiny) ≈ 1e-4.
|
||||
EXPECT_TRUE(result_cpp.Equal(result_c, 1e-4f));
|
||||
}
|
||||
|
||||
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionAreEqualTest) {
|
||||
|
||||
Reference in New Issue
Block a user