Merge branch 'master' into bug-3201-collada_root_meshes

pull/3205/head
Kim Kulling 2020-05-16 20:50:34 +02:00 committed by GitHub
commit cfbdacb02a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
202 changed files with 3584 additions and 19959 deletions

6
.gitignore vendored
View File

@ -79,6 +79,12 @@ test/gtest/src/gtest-stamp/Debug/
tools/assimp_view/assimp_viewer.vcxproj.user
*.pyc
### Rust ###
# Generated by Cargo; will have compiled files and executables
port/assimp_rs/target/
# Backup files generated by rustfmt
port/assimp_rs/**/*.rs.bk
# Unix editor backups
*~
test/gtest/src/gtest-stamp/gtest-gitinfo.txt

View File

@ -1,4 +1,4 @@
/*
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/*
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/*
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/*
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------

View File

@ -83,6 +83,18 @@ static const aiImporterDesc desc = {
"dae zae"
};
static const float kMillisecondsFromSeconds = 1000.f;
// Add an item of metadata to a node
// Assumes the key is not already in the list
template <typename T>
inline void AddNodeMetaData(aiNode *node, const std::string &key, const T &value) {
if (nullptr == node->mMetaData) {
node->mMetaData = new aiMetadata();
}
node->mMetaData->Add(key, value);
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
ColladaLoader::ColladaLoader() :
@ -230,27 +242,15 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
}
}
// store all meshes
StoreSceneMeshes(pScene);
// store all materials
StoreSceneMaterials(pScene);
// store all textures
StoreSceneTextures(pScene);
// store all lights
StoreSceneLights(pScene);
// store all cameras
StoreSceneCameras(pScene);
// store all animations
StoreAnimations(pScene, parser);
// If no meshes have been loaded, it's probably just an animated skeleton.
if (0u == pScene->mNumMeshes) {
if (!noSkeletonMesh) {
SkeletonMeshBuilder hero(pScene);
}
@ -258,15 +258,6 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
}
}
// Add an item of metadata to a node
// Assumes the key is not already in the list
template <typename T>
inline void AddNodeMetaData(aiNode *node, const std::string &key, const T &value) {
if (nullptr == node->mMetaData)
node->mMetaData = new aiMetadata();
node->mMetaData->Add(key, value);
}
// ------------------------------------------------------------------------------------------------
// Recursively constructs a scene node for the given parser node and returns it.
aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collada::Node *pNode) {
@ -277,10 +268,12 @@ aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collad
node->mName.Set(FindNameForNode(pNode));
// if we're not using the unique IDs, hold onto them for reference and export
if (useColladaName) {
if (!pNode->mID.empty())
if (!pNode->mID.empty()) {
AddNodeMetaData(node, AI_METADATA_COLLADA_ID, aiString(pNode->mID));
if (!pNode->mSID.empty())
}
if (!pNode->mSID.empty()) {
AddNodeMetaData(node, AI_METADATA_COLLADA_SID, aiString(pNode->mSID));
}
}
// calculate the transformation matrix for it
@ -305,13 +298,8 @@ aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collad
node->mChildren[pNode->mChildren.size() + a]->mParent = node;
}
// construct meshes
BuildMeshesForNode(pParser, pNode, node);
// construct cameras
BuildCamerasForNode(pParser, pNode, node);
// construct lights
BuildLightsForNode(pParser, pNode, node);
return node;
@ -347,9 +335,7 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Col
// ------------------------------------------------------------------------------------------------
// Resolve UV channels
void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler,
const Collada::SemanticMappingTable &table) {
void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler, const Collada::SemanticMappingTable &table) {
std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel);
if (it != table.mMap.end()) {
if (it->second.mType != Collada::IT_Texcoord) {
@ -599,6 +585,10 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Colla
// ------------------------------------------------------------------------------------------------
// Find mesh from either meshes or morph target meshes
aiMesh *ColladaLoader::findMesh(const std::string &meshid) {
if ( meshid.empty()) {
return nullptr;
}
for (unsigned int i = 0; i < mMeshes.size(); ++i) {
if (std::string(mMeshes[i]->mName.data) == meshid) {
return mMeshes[i];
@ -1386,9 +1376,9 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
double time = double(mat.d4); // remember? time is stored in mat.d4
mat.d4 = 1.0f;
dstAnim->mPositionKeys[a].mTime = time;
dstAnim->mRotationKeys[a].mTime = time;
dstAnim->mScalingKeys[a].mTime = time;
dstAnim->mPositionKeys[a].mTime = time * kMillisecondsFromSeconds ;
dstAnim->mRotationKeys[a].mTime = time * kMillisecondsFromSeconds ;
dstAnim->mScalingKeys[a].mTime = time * kMillisecondsFromSeconds ;
mat.Decompose(dstAnim->mScalingKeys[a].mValue, dstAnim->mRotationKeys[a].mValue, dstAnim->mPositionKeys[a].mValue);
}
@ -1409,7 +1399,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
if (e.mTargetId.find("morph-weights") != std::string::npos)
morphChannels.push_back(e);
}
if (morphChannels.size() > 0) {
if (!morphChannels.empty() ) {
// either 1) morph weight animation count should contain morph target count channels
// or 2) one channel with morph target count arrays
// assume first
@ -1418,7 +1408,6 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
morphAnim->mName.Set(nodeName);
std::vector<MorphTimeValues> morphTimeValues;
int morphAnimChannelIndex = 0;
for (std::vector<Collada::ChannelEntry>::iterator it = morphChannels.begin(); it != morphChannels.end(); ++it) {
Collada::ChannelEntry &e = *it;
@ -1430,8 +1419,9 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// weight target can be in format Weight_M_N, Weight_N, WeightN, or some other way
// we ignore the name and just assume the channels are in the right order
for (unsigned int i = 0; i < e.mTimeData->mValues.size(); i++)
insertMorphTimeValue(morphTimeValues, e.mTimeData->mValues.at(i), e.mValueData->mValues.at(i), morphAnimChannelIndex);
for (unsigned int i = 0; i < e.mTimeData->mValues.size(); i++) {
insertMorphTimeValue(morphTimeValues, e.mTimeData->mValues[i], e.mValueData->mValues[i], morphAnimChannelIndex);
}
++morphAnimChannelIndex;
}
@ -1443,8 +1433,8 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
morphAnim->mKeys[key].mValues = new unsigned int[morphChannels.size()];
morphAnim->mKeys[key].mWeights = new double[morphChannels.size()];
morphAnim->mKeys[key].mTime = morphTimeValues[key].mTime;
for (unsigned int valueIndex = 0; valueIndex < morphChannels.size(); valueIndex++) {
morphAnim->mKeys[key].mTime = morphTimeValues[key].mTime * kMillisecondsFromSeconds ;
for (unsigned int valueIndex = 0; valueIndex < morphChannels.size(); ++valueIndex ) {
morphAnim->mKeys[key].mValues[valueIndex] = valueIndex;
morphAnim->mKeys[key].mWeights[valueIndex] = getWeightAtKey(morphTimeValues, key, valueIndex);
}
@ -1494,18 +1484,22 @@ void ColladaLoader::AddTexture(aiMaterial &mat, const ColladaParser &pParser,
// mapping mode
int map = aiTextureMapMode_Clamp;
if (sampler.mWrapU)
if (sampler.mWrapU) {
map = aiTextureMapMode_Wrap;
if (sampler.mWrapU && sampler.mMirrorU)
}
if (sampler.mWrapU && sampler.mMirrorU) {
map = aiTextureMapMode_Mirror;
}
mat.AddProperty(&map, 1, _AI_MATKEY_MAPPINGMODE_U_BASE, type, idx);
map = aiTextureMapMode_Clamp;
if (sampler.mWrapV)
if (sampler.mWrapV) {
map = aiTextureMapMode_Wrap;
if (sampler.mWrapV && sampler.mMirrorV)
}
if (sampler.mWrapV && sampler.mMirrorV) {
map = aiTextureMapMode_Mirror;
}
mat.AddProperty(&map, 1, _AI_MATKEY_MAPPINGMODE_V_BASE, type, idx);
@ -1526,9 +1520,9 @@ void ColladaLoader::AddTexture(aiMaterial &mat, const ColladaParser &pParser,
// number in the channel name. We assume it is the zero-based index into the
// UV channel array of all corresponding meshes. It could also be one-based
// for some exporters, but we won't care of it unless someone complains about.
if (sampler.mUVId != UINT_MAX)
if (sampler.mUVId != UINT_MAX) {
map = sampler.mUVId;
else {
} else {
map = -1;
for (std::string::const_iterator it = sampler.mUVChannel.begin(); it != sampler.mUVChannel.end(); ++it) {
if (IsNumeric(*it)) {
@ -1553,27 +1547,27 @@ void ColladaLoader::FillMaterials(const ColladaParser &pParser, aiScene * /*pSce
// resolve shading mode
int shadeMode;
if (effect.mFaceted) /* fixme */
if (effect.mFaceted) {
shadeMode = aiShadingMode_Flat;
else {
} else {
switch (effect.mShadeType) {
case Collada::Shade_Constant:
shadeMode = aiShadingMode_NoShading;
break;
case Collada::Shade_Lambert:
shadeMode = aiShadingMode_Gouraud;
break;
case Collada::Shade_Blinn:
shadeMode = aiShadingMode_Blinn;
break;
case Collada::Shade_Phong:
shadeMode = aiShadingMode_Phong;
break;
case Collada::Shade_Constant:
shadeMode = aiShadingMode_NoShading;
break;
case Collada::Shade_Lambert:
shadeMode = aiShadingMode_Gouraud;
break;
case Collada::Shade_Blinn:
shadeMode = aiShadingMode_Blinn;
break;
case Collada::Shade_Phong:
shadeMode = aiShadingMode_Phong;
break;
default:
ASSIMP_LOG_WARN("Collada: Unrecognized shading mode, using gouraud shading");
shadeMode = aiShadingMode_Gouraud;
break;
default:
ASSIMP_LOG_WARN("Collada: Unrecognized shading mode, using gouraud shading");
shadeMode = aiShadingMode_Gouraud;
break;
}
}
mat.AddProperty<int>(&shadeMode, 1, AI_MATKEY_SHADING_MODEL);
@ -1679,23 +1673,6 @@ void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/)
// ScenePreprocessor generates a default material automatically if none is there.
// All further code here in this loader works well without a valid material so
// we can safely let it to ScenePreprocessor.
#if 0
if (newMats.size() == 0)
{
aiMaterial* mat = new aiMaterial;
aiString name(AI_DEFAULT_MATERIAL_NAME);
mat->AddProperty(&name, AI_MATKEY_NAME);
const int shadeMode = aiShadingMode_Phong;
mat->AddProperty<int>(&shadeMode, 1, AI_MATKEY_SHADING_MODEL);
aiColor4D colAmbient(0.2, 0.2, 0.2, 1.0), colDiffuse(0.8, 0.8, 0.8, 1.0), colSpecular(0.5, 0.5, 0.5, 0.5);
mat->AddProperty(&colAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
mat->AddProperty(&colDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
mat->AddProperty(&colSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
const ai_real specExp = 5.0;
mat->AddProperty(&specExp, 1, AI_MATKEY_SHININESS);
}
#endif
}
// ------------------------------------------------------------------------------------------------
@ -1755,20 +1732,21 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
// and add this texture to the list
mTextures.push_back(tex);
} else {
if (imIt->second.mFileName.empty()) {
throw DeadlyImportError("Collada: Invalid texture, no data or file reference given");
}
result.Set(imIt->second.mFileName);
return result;
}
if (imIt->second.mFileName.empty()) {
throw DeadlyImportError("Collada: Invalid texture, no data or file reference given");
}
result.Set(imIt->second.mFileName);
return result;
}
// ------------------------------------------------------------------------------------------------
// Reads a float value from an accessor and its data array.
ai_real ColladaLoader::ReadFloat(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex, size_t pOffset) const {
// FIXME: (thom) Test for data type here in every access? For the moment, I leave this to the caller
size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
ai_assert(pos < pData.mValues.size());
return pData.mValues[pos];

View File

@ -3315,6 +3315,7 @@ void FBXConverter::InterpolateKeys(aiQuatKey *valOut, const KeyTimeList &keys, c
// http://www.3dkingdoms.com/weekly/weekly.php?a=36
if (quat.x * lastq.x + quat.y * lastq.y + quat.z * lastq.z + quat.w * lastq.w < 0) {
quat.Conjugate();
quat.w = -quat.w;
}
lastq = quat;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,114 +0,0 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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.
---------------------------------------------------------------------------
*/
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
#include "StepFileImporter.h"
#include "../../Importer/STEPParser/STEPFileReader.h"
#include <assimp/importerdesc.h>
#include <assimp/DefaultIOSystem.h>
namespace Assimp {
namespace StepFile {
using namespace STEP;
static const aiImporterDesc desc = { "StepFile Importer",
"",
"",
"",
0,
0,
0,
0,
0,
"stp" };
StepFileImporter::StepFileImporter()
: BaseImporter() {
}
StepFileImporter::~StepFileImporter() {
}
bool StepFileImporter::CanRead(const std::string& file, IOSystem* pIOHandler, bool checkSig) const {
const std::string &extension = GetExtension(file);
if ( extension == "stp" || extension == "step" ) {
return true;
} else if ((!extension.length() || checkSig) && pIOHandler) {
const char* tokens[] = { "ISO-10303-21" };
const bool found(SearchFileHeaderForToken(pIOHandler, file, tokens, 1));
return found;
}
return false;
}
const aiImporterDesc *StepFileImporter::GetInfo() const {
return &desc;
}
static const std::string mode = "rb";
static const std::string StepFileSchema = "CONFIG_CONTROL_DESIGN";
void StepFileImporter::InternReadFile(const std::string &file, aiScene*, IOSystem* pIOHandler) {
// Read file into memory
std::shared_ptr<IOStream> fileStream(pIOHandler->Open(file, mode));
if (!fileStream.get()) {
throw DeadlyImportError("Failed to open file " + file + ".");
}
std::unique_ptr<STEP::DB> db(STEP::ReadFileHeader(fileStream));
const STEP::HeaderInfo& head = static_cast<const STEP::DB&>(*db).GetHeader();
if (!head.fileSchema.size() || head.fileSchema != StepFileSchema) {
DeadlyImportError("Unrecognized file schema: " + head.fileSchema);
}
}
} // Namespace StepFile
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_STEP_IMPORTER

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/*
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/*
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/*
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------

View File

@ -363,20 +363,44 @@ struct Object {
// Classes for each glTF top-level object type
//
//! Base class for types that access binary data from a BufferView, such as accessors
//! or sparse accessors' indices.
//! N.B. not a virtual class. All owned pointers to BufferViewClient instances should
//! be to their most derived types (which may of course be just BufferViewClient).
struct BufferViewClient : public Object {
Ref<BufferView> bufferView; //!< The ID of the bufferView. (required)
size_t byteOffset; //!< The offset relative to the start of the bufferView in bytes. (required)
inline uint8_t *GetPointer();
void Read(Value &obj, Asset &r);
};
//! BufferViewClient with component type information.
//! N.B. not a virtual class. All owned pointers to ComponentTypedBufferViewClient
//! instances should be to their most derived types (which may of course be just
//! ComponentTypedBufferViewClient).
struct ComponentTypedBufferViewClient : public BufferViewClient {
ComponentType componentType; //!< The datatype of components in the attribute. (required)
unsigned int GetBytesPerComponent();
void Read(Value &obj, Asset &r);
};
//! A typed view into a BufferView. A BufferView contains raw binary data.
//! An accessor provides a typed view into a BufferView or a subset of a BufferView
//! similar to how WebGL's vertexAttribPointer() defines an attribute in a buffer.
struct Accessor : public Object {
Ref<BufferView> bufferView; //!< The ID of the bufferView. (required)
size_t byteOffset; //!< The offset relative to the start of the bufferView in bytes. (required)
ComponentType componentType; //!< The datatype of components in the attribute. (required)
struct Accessor : public ComponentTypedBufferViewClient {
struct Sparse;
size_t count; //!< The number of attributes referenced by this accessor. (required)
AttribType::Value type; //!< Specifies if the attribute is a scalar, vector, or matrix. (required)
std::vector<double> max; //!< Maximum value of each component in this attribute.
std::vector<double> min; //!< Minimum value of each component in this attribute.
std::unique_ptr<Sparse> sparse; //!< Sparse accessor information
unsigned int GetNumComponents();
unsigned int GetBytesPerComponent();
unsigned int GetElementSize();
inline uint8_t *GetPointer();
@ -417,11 +441,61 @@ struct Accessor : public Object {
}
};
//! Sparse accessor information
struct Sparse {
size_t count;
ComponentTypedBufferViewClient indices;
BufferViewClient values;
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.
inline void PopulateData(size_t numBytes, uint8_t *bytes) {
if (bytes) {
data.assign(bytes, bytes + numBytes);
} else {
data.resize(numBytes, 0x00);
}
}
inline void PatchData(unsigned int elementSize)
{
uint8_t *pIndices = indices.GetPointer();
const unsigned int indexSize = indices.GetBytesPerComponent();
uint8_t *indicesEnd = pIndices + count * indexSize;
uint8_t *pValues = values.GetPointer();
while (pIndices != indicesEnd) {
size_t offset;
switch (indices.componentType) {
case ComponentType_UNSIGNED_BYTE:
offset = *pIndices;
break;
case ComponentType_UNSIGNED_SHORT:
offset = *reinterpret_cast<uint16_t *>(pIndices);
break;
case ComponentType_UNSIGNED_INT:
offset = *reinterpret_cast<uint32_t *>(pIndices);
break;
default:
// have fun with float and negative values from signed types as indices.
throw DeadlyImportError("Unsupported component type in index.");
}
offset *= elementSize;
std::memcpy(data.data() + offset, pValues, elementSize);
pValues += elementSize;
pIndices += indexSize;
}
}
};
inline Indexer GetIndexer() {
return Indexer(*this);
}
Accessor() {}
void Read(Value &obj, Asset &r);
};

View File

@ -551,36 +551,10 @@ inline void BufferView::Read(Value &obj, Asset &r) {
}
//
// struct Accessor
// struct BufferViewClient
//
inline void Accessor::Read(Value &obj, Asset &r) {
if (Value *bufferViewVal = FindUInt(obj, "bufferView")) {
bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
}
byteOffset = MemberOrDefault(obj, "byteOffset", size_t(0));
componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
count = MemberOrDefault(obj, "count", size_t(0));
const char *typestr;
type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
}
inline unsigned int Accessor::GetNumComponents() {
return AttribType::GetNumComponents(type);
}
inline unsigned int Accessor::GetBytesPerComponent() {
return int(ComponentTypeSize(componentType));
}
inline unsigned int Accessor::GetElementSize() {
return GetNumComponents() * GetBytesPerComponent();
}
inline uint8_t *Accessor::GetPointer() {
inline uint8_t *BufferViewClient::GetPointer() {
if (!bufferView || !bufferView->buffer) return 0;
uint8_t *basePtr = bufferView->buffer->GetPointer();
if (!basePtr) return 0;
@ -599,6 +573,76 @@ inline uint8_t *Accessor::GetPointer() {
return basePtr + offset;
}
inline void BufferViewClient::Read(Value &obj, Asset &r) {
if (Value *bufferViewVal = FindUInt(obj, "bufferView")) {
bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
}
byteOffset = MemberOrDefault(obj, "byteOffset", size_t(0));
}
//
// struct ComponentTypedBufferViewClient
//
inline unsigned int ComponentTypedBufferViewClient::GetBytesPerComponent() {
return int(ComponentTypeSize(componentType));
}
inline void ComponentTypedBufferViewClient::Read(Value &obj, Asset &r) {
BufferViewClient::Read(obj, r);
componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
}
//
// struct Accessor
//
inline uint8_t *Accessor::GetPointer() {
if (!sparse) return BufferViewClient::GetPointer();
return sparse->data.data();
}
inline void Accessor::Read(Value &obj, Asset &r) {
ComponentTypedBufferViewClient::Read(obj, r);
count = MemberOrDefault(obj, "count", size_t(0));
const char *typestr;
type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
if (Value *sparseValue = FindObject(obj, "sparse")) {
sparse.reset(new Sparse);
ReadMember(*sparseValue, "count", sparse->count);
if (Value *indicesValue = FindObject(*sparseValue, "indices")) {
sparse->indices.Read(*indicesValue, r);
}
if (Value *valuesValue = FindObject(*sparseValue, "values")) {
sparse->values.Read(*valuesValue, r);
}
const unsigned int elementSize = GetElementSize();
const size_t dataSize = count * elementSize;
sparse->PopulateData(dataSize, BufferViewClient::GetPointer());
sparse->PatchData(elementSize);
}
}
inline unsigned int Accessor::GetNumComponents() {
return AttribType::GetNumComponents(type);
}
inline unsigned int Accessor::GetElementSize() {
return GetNumComponents() * GetBytesPerComponent();
}
namespace {
inline void CopyData(size_t count,
const uint8_t *src, size_t src_stride,
@ -635,7 +679,7 @@ void Accessor::ExtractData(T *&outData)
const size_t targetElemSize = sizeof(T);
ai_assert(elemSize <= targetElemSize);
ai_assert(count * stride <= bufferView->byteLength);
ai_assert(count * stride <= (bufferView ? bufferView->byteLength : sparse->data.size()));
outData = new T[count];
if (stride == elemSize && targetElemSize == elemSize) {
@ -1002,7 +1046,7 @@ inline void Mesh::Read(Value &pJSON_Object, Asset &pAsset_Root) {
// Valid attribute semantics include POSITION, NORMAL, TANGENT
int undPos = 0;
Mesh::AccessorList *vec = 0;
if (GetAttribTargetVector(prim, i, attr, vec, undPos)) {
if (GetAttribTargetVector(prim, j, attr, vec, undPos)) {
size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
if ((*vec).size() <= idx) {
(*vec).resize(idx + 1);
@ -1067,10 +1111,10 @@ inline void Camera::Read(Value &obj, Asset & /*r*/) {
cameraProperties.perspective.zfar = MemberOrDefault(*it, "zfar", 100.f);
cameraProperties.perspective.znear = MemberOrDefault(*it, "znear", 0.01f);
} else {
cameraProperties.ortographic.xmag = MemberOrDefault(obj, "xmag", 1.f);
cameraProperties.ortographic.ymag = MemberOrDefault(obj, "ymag", 1.f);
cameraProperties.ortographic.zfar = MemberOrDefault(obj, "zfar", 100.f);
cameraProperties.ortographic.znear = MemberOrDefault(obj, "znear", 0.01f);
cameraProperties.ortographic.xmag = MemberOrDefault(*it, "xmag", 1.f);
cameraProperties.ortographic.ymag = MemberOrDefault(*it, "ymag", 1.f);
cameraProperties.ortographic.zfar = MemberOrDefault(*it, "zfar", 100.f);
cameraProperties.ortographic.znear = MemberOrDefault(*it, "znear", 0.01f);
}
}

View File

@ -1,4 +1,4 @@
/*
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------

View File

@ -45,10 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "CInterfaceIOWrapper.h"
namespace Assimp {
namespace Assimp {
CIOStreamWrapper::~CIOStreamWrapper(void)
{
CIOStreamWrapper::~CIOStreamWrapper(void) {
/* Various places depend on this destructor to close the file */
if (mFile) {
mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile);
@ -57,28 +56,25 @@ CIOStreamWrapper::~CIOStreamWrapper(void)
}
// ...................................................................
size_t CIOStreamWrapper::Read(void* pvBuffer,
size_t pSize,
size_t pCount
){
size_t CIOStreamWrapper::Read(void *pvBuffer,
size_t pSize,
size_t pCount) {
// need to typecast here as C has no void*
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
return mFile->ReadProc(mFile, (char *)pvBuffer, pSize, pCount);
}
// ...................................................................
size_t CIOStreamWrapper::Write(const void* pvBuffer,
size_t pSize,
size_t pCount
){
size_t CIOStreamWrapper::Write(const void *pvBuffer,
size_t pSize,
size_t pCount) {
// need to typecast here as C has no void*
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
return mFile->WriteProc(mFile, (const char *)pvBuffer, pSize, pCount);
}
// ...................................................................
aiReturn CIOStreamWrapper::Seek(size_t pOffset,
aiOrigin pOrigin
){
return mFile->SeekProc(mFile,pOffset,pOrigin);
aiOrigin pOrigin) {
return mFile->SeekProc(mFile, pOffset, pOrigin);
}
// ...................................................................
@ -92,16 +88,16 @@ size_t CIOStreamWrapper::FileSize() const {
}
// ...................................................................
void CIOStreamWrapper::Flush () {
void CIOStreamWrapper::Flush() {
return mFile->FlushProc(mFile);
}
// ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API
bool CIOSystemWrapper::Exists( const char* pFile) const {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb");
if (p){
mFileSystem->CloseProc(mFileSystem,p);
bool CIOSystemWrapper::Exists(const char *pFile) const {
aiFile *p = mFileSystem->OpenProc(mFileSystem, pFile, "rb");
if (p) {
mFileSystem->CloseProc(mFileSystem, p);
return true;
}
return false;
@ -117,8 +113,8 @@ char CIOSystemWrapper::getOsSeparator() const {
}
// ...................................................................
IOStream* CIOSystemWrapper::Open(const char* pFile,const char* pMode) {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
IOStream *CIOSystemWrapper::Open(const char *pFile, const char *pMode) {
aiFile *p = mFileSystem->OpenProc(mFileSystem, pFile, pMode);
if (!p) {
return NULL;
}
@ -126,11 +122,11 @@ IOStream* CIOSystemWrapper::Open(const char* pFile,const char* pMode) {
}
// ...................................................................
void CIOSystemWrapper::Close( IOStream* pFile) {
void CIOSystemWrapper::Close(IOStream *pFile) {
if (!pFile) {
return;
}
delete pFile;
}
}
} // namespace Assimp

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -50,50 +48,47 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
namespace Assimp {
namespace Assimp {
class CIOSystemWrapper;
// ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API
class CIOStreamWrapper : public IOStream
{
class CIOStreamWrapper : public IOStream {
public:
explicit CIOStreamWrapper(aiFile* pFile, CIOSystemWrapper* io)
: mFile(pFile),
mIO(io)
{}
explicit CIOStreamWrapper(aiFile *pFile, CIOSystemWrapper *io) :
mFile(pFile),
mIO(io) {}
~CIOStreamWrapper(void);
size_t Read(void* pvBuffer, size_t pSize, size_t pCount);
size_t Write(const void* pvBuffer, size_t pSize, size_t pCount);
size_t Read(void *pvBuffer, size_t pSize, size_t pCount);
size_t Write(const void *pvBuffer, size_t pSize, size_t pCount);
aiReturn Seek(size_t pOffset, aiOrigin pOrigin);
size_t Tell(void) const;
size_t FileSize() const;
void Flush();
private:
aiFile* mFile;
CIOSystemWrapper* mIO;
aiFile *mFile;
CIOSystemWrapper *mIO;
};
class CIOSystemWrapper : public IOSystem
{
class CIOSystemWrapper : public IOSystem {
friend class CIOStreamWrapper;
public:
explicit CIOSystemWrapper(aiFileIO* pFile)
: mFileSystem(pFile)
{}
bool Exists( const char* pFile) const;
public:
explicit CIOSystemWrapper(aiFileIO *pFile) :
mFileSystem(pFile) {}
bool Exists(const char *pFile) const;
char getOsSeparator() const;
IOStream* Open(const char* pFile,const char* pMode = "rb");
void Close( IOStream* pFile);
IOStream *Open(const char *pFile, const char *pMode = "rb");
void Close(IOStream *pFile);
private:
aiFileIO* mFileSystem;
aiFileIO *mFileSystem;
};
}
} // namespace Assimp
#endif

View File

@ -1233,7 +1233,7 @@ if (APPLE)
# add ./Compiler/*.h to assimp.framework via copy command
ADD_CUSTOM_COMMAND(TARGET assimp POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_directory
"../${HEADER_PATH}/Compiler"
"${HEADER_PATH}/Compiler"
assimp.framework/Headers/Compiler
COMMENT "Copying public ./Compiler/ header files to framework bundle's Headers/Compiler/")
ENDIF()

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/*
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------

View File

@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits>
#include <assimp/TinyFormatter.h>
#include <assimp/Exceptional.h>
#include <set>
using namespace Assimp;
using namespace Assimp::Formatter;
@ -172,7 +173,15 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
const aiBone* bone = pMesh->mBones[a];
for( unsigned int b = 0; b < bone->mNumWeights; ++b)
{
vertexBones[ bone->mWeights[b].mVertexId ].push_back( BoneWeight( a, bone->mWeights[b].mWeight));
if (bone->mWeights[b].mWeight > 0.0f)
{
int vertexId = bone->mWeights[b].mVertexId;
vertexBones[vertexId].push_back( BoneWeight( a, bone->mWeights[b].mWeight));
if (vertexBones[vertexId].size() > mMaxBoneCount)
{
throw DeadlyImportError("SplitByBoneCountProcess: Single face requires more bones than specified max bone count!");
}
}
}
}
@ -188,9 +197,6 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
subMeshFaces.reserve( pMesh->mNumFaces);
// accumulated vertex count of all the faces in this submesh
unsigned int numSubMeshVertices = 0;
// a small local array of new bones for the current face. State of all used bones for that face
// can only be updated AFTER the face is completely analysed. Thanks to imre for the fix.
std::vector<unsigned int> newBonesAtCurrentFace;
// add faces to the new submesh as long as all bones affecting the faces' vertices fit in the limit
for( unsigned int a = 0; a < pMesh->mNumFaces; ++a)
@ -200,33 +206,25 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
{
continue;
}
// a small local set of new bones for the current face. State of all used bones for that face
// can only be updated AFTER the face is completely analysed. Thanks to imre for the fix.
std::set<unsigned int> newBonesAtCurrentFace;
const aiFace& face = pMesh->mFaces[a];
// check every vertex if its bones would still fit into the current submesh
for( unsigned int b = 0; b < face.mNumIndices; ++b )
{
const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]];
for( unsigned int c = 0; c < vb.size(); ++c)
const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]];
for( unsigned int c = 0; c < vb.size(); ++c)
{
unsigned int boneIndex = vb[c].first;
if( !isBoneUsed[boneIndex] )
{
unsigned int boneIndex = vb[c].first;
// if the bone is already used in this submesh, it's ok
if( isBoneUsed[boneIndex] )
{
continue;
}
// if it's not used, yet, we would need to add it. Store its bone index
if( std::find( newBonesAtCurrentFace.begin(), newBonesAtCurrentFace.end(), boneIndex) == newBonesAtCurrentFace.end() )
{
newBonesAtCurrentFace.push_back( boneIndex);
}
newBonesAtCurrentFace.insert(boneIndex);
}
}
}
if (newBonesAtCurrentFace.size() > mMaxBoneCount)
{
throw DeadlyImportError("SplitByBoneCountProcess: Single face requires more bones than specified max bone count!");
}
// leave out the face if the new bones required for this face don't fit the bone count limit anymore
if( numBones + newBonesAtCurrentFace.size() > mMaxBoneCount )
{
@ -234,17 +232,13 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
}
// mark all new bones as necessary
while( !newBonesAtCurrentFace.empty() )
for (std::set<unsigned int>::iterator it = newBonesAtCurrentFace.begin(); it != newBonesAtCurrentFace.end(); ++it)
{
unsigned int newIndex = newBonesAtCurrentFace.back();
newBonesAtCurrentFace.pop_back(); // this also avoids the deallocation which comes with a clear()
if( isBoneUsed[newIndex] )
{
continue;
}
isBoneUsed[newIndex] = true;
if (!isBoneUsed[*it])
{
isBoneUsed[*it] = true;
numBones++;
}
}
// store the face index and the vertex count

View File

@ -1,4 +1,4 @@
/*
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/*
/*
Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy

View File

@ -1,4 +1,4 @@
==================
==================
INSTALLATION GUIDE
==================

View File

@ -196,10 +196,7 @@ if(MINGW)
set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
endif(MINGW)
add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
set_target_properties(zlib PROPERTIES SOVERSION 1)
INSTALL( TARGETS zlibstatic
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -40,30 +38,19 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include <assimp/cimport.h>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#pragma once
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataSize) {
aiLogStream stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
aiAttachLogStream(&stream);
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
Importer importer;
const aiScene *sc = importer.ReadFileFromMemory(data, dataSize,
aiProcessPreset_TargetRealtime_Quality, nullptr );
#include <assimp/BaseImporter.h>
aiDetachLogStream(&stream);
namespace Assimp {
namespace StepFile {
class StepFileImporter : public BaseImporter {
public:
StepFileImporter();
~StepFileImporter();
bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
const aiImporterDesc* GetInfo() const override;
protected:
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) override;
private:
};
} // Namespace StepFile
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_STEP_IMPORTER
return 0;
}

View File

@ -1,4 +1,4 @@
/*
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------

View File

@ -4,5 +4,3 @@ http://assimp.sourceforge.net
Sourceforge.net project page:
http://www.sourceforge.net/projects/assimp

6
port/assimp_rs/Cargo.lock generated 100644
View File

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

View File

@ -0,0 +1,9 @@
[package]
name = "assimp_rs"
version = "0.1.0"
authors = ["David Golembiowski <dmgolembiowski@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

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

View File

View File

View File

View File

@ -0,0 +1,17 @@
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;
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(true, true);
}
}

View File

View File

View File

@ -0,0 +1,44 @@
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

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,27 @@
#[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

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,64 @@
#[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

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

View File

@ -0,0 +1,35 @@
#[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

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

View File

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

View File

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

View File

@ -0,0 +1,61 @@
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

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

View File

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

View File

@ -0,0 +1,23 @@
#[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

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,41 @@
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

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

View File

@ -0,0 +1,19 @@
#[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

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

View File

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

View File

@ -0,0 +1,48 @@
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

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

View File

@ -1,4 +1,4 @@
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Simple Assimp Directx11 Sample
// This is a very basic sample and only reads diffuse texture
// but this can load both embedded textures in fbx and non-embedded textures

View File

@ -124,8 +124,7 @@ SET( IMPORTERS
unit/utBlendImportMaterials.cpp
unit/utBlenderWork.cpp
unit/utBVHImportExport.cpp
unit/utColladaExportCamera.cpp
unit/utColladaExportLight.cpp
unit/utColladaExport.cpp
unit/utColladaImportExport.cpp
unit/utCSMImportExport.cpp
unit/utB3DImportExport.cpp

View File

@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_EXPORT
class ColladaExportLight : public ::testing::Test {
class utColladaExport : public ::testing::Test {
public:
void SetUp() override {
ex = new Assimp::Exporter();
@ -58,7 +58,9 @@ public:
void TearDown() override {
delete ex;
ex = nullptr;
delete im;
im = nullptr;
}
protected:
@ -66,8 +68,53 @@ protected:
Assimp::Importer *im;
};
TEST_F(utColladaExport, testExportCamera) {
const char *file = "cameraExp.dae";
const aiScene *pTest = im->ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/cameras.dae", aiProcess_ValidateDataStructure);
ASSERT_NE(nullptr, pTest);
ASSERT_TRUE(pTest->HasCameras());
EXPECT_EQ(AI_SUCCESS, ex->Export(pTest, "collada", file));
const unsigned int origNumCams(pTest->mNumCameras);
std::unique_ptr<float[]> origFOV(new float[origNumCams]);
std::unique_ptr<float[]> orifClipPlaneNear(new float[origNumCams]);
std::unique_ptr<float[]> orifClipPlaneFar(new float[origNumCams]);
std::unique_ptr<aiString[]> names(new aiString[origNumCams]);
std::unique_ptr<aiVector3D[]> pos(new aiVector3D[origNumCams]);
for (size_t i = 0; i < origNumCams; i++) {
const aiCamera *orig = pTest->mCameras[i];
ASSERT_NE(nullptr, orig);
origFOV[i] = orig->mHorizontalFOV;
orifClipPlaneNear[i] = orig->mClipPlaneNear;
orifClipPlaneFar[i] = orig->mClipPlaneFar;
names[i] = orig->mName;
pos[i] = orig->mPosition;
}
const aiScene *imported = im->ReadFile(file, aiProcess_ValidateDataStructure);
ASSERT_NE(nullptr, imported);
EXPECT_TRUE(imported->HasCameras());
EXPECT_EQ(origNumCams, imported->mNumCameras);
for (size_t i = 0; i < imported->mNumCameras; i++) {
const aiCamera *read = imported->mCameras[i];
EXPECT_TRUE(names[i] == read->mName);
EXPECT_NEAR(origFOV[i], read->mHorizontalFOV, 0.0001f);
EXPECT_FLOAT_EQ(orifClipPlaneNear[i], read->mClipPlaneNear);
EXPECT_FLOAT_EQ(orifClipPlaneFar[i], read->mClipPlaneFar);
EXPECT_FLOAT_EQ(pos[i].x, read->mPosition.x);
EXPECT_FLOAT_EQ(pos[i].y, read->mPosition.y);
EXPECT_FLOAT_EQ(pos[i].z, read->mPosition.z);
}
}
// ------------------------------------------------------------------------------------------------
TEST_F(ColladaExportLight, testExportLight) {
TEST_F(utColladaExport, testExportLight) {
const char *file = "lightsExp.dae";
const aiScene *pTest = im->ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/lights.dae", aiProcess_ValidateDataStructure);

View File

@ -1,115 +0,0 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include <assimp/cexport.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include <assimp/Exporter.hpp>
#include <assimp/Importer.hpp>
#ifndef ASSIMP_BUILD_NO_EXPORT
class ColladaExportCamera : public ::testing::Test {
public:
void SetUp() override {
ex = new Assimp::Exporter();
im = new Assimp::Importer();
}
void TearDown() override {
delete ex;
ex = nullptr;
delete im;
im = nullptr;
}
protected:
Assimp::Exporter *ex;
Assimp::Importer *im;
};
TEST_F(ColladaExportCamera, testExportCamera) {
const char *file = "cameraExp.dae";
const aiScene *pTest = im->ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/cameras.dae", aiProcess_ValidateDataStructure);
ASSERT_NE(nullptr, pTest);
ASSERT_TRUE(pTest->HasCameras());
EXPECT_EQ(AI_SUCCESS, ex->Export(pTest, "collada", file));
const unsigned int origNumCams(pTest->mNumCameras);
std::unique_ptr<float[]> origFOV(new float[origNumCams]);
std::unique_ptr<float[]> orifClipPlaneNear(new float[origNumCams]);
std::unique_ptr<float[]> orifClipPlaneFar(new float[origNumCams]);
std::unique_ptr<aiString[]> names(new aiString[origNumCams]);
std::unique_ptr<aiVector3D[]> pos(new aiVector3D[origNumCams]);
for (size_t i = 0; i < origNumCams; i++) {
const aiCamera *orig = pTest->mCameras[i];
ASSERT_NE(nullptr, orig);
origFOV[i] = orig->mHorizontalFOV;
orifClipPlaneNear[i] = orig->mClipPlaneNear;
orifClipPlaneFar[i] = orig->mClipPlaneFar;
names[i] = orig->mName;
pos[i] = orig->mPosition;
}
const aiScene *imported = im->ReadFile(file, aiProcess_ValidateDataStructure);
ASSERT_NE(nullptr, imported);
EXPECT_TRUE(imported->HasCameras());
EXPECT_EQ(origNumCams, imported->mNumCameras);
for (size_t i = 0; i < imported->mNumCameras; i++) {
const aiCamera *read = imported->mCameras[i];
EXPECT_TRUE(names[i] == read->mName);
EXPECT_NEAR(origFOV[i], read->mHorizontalFOV, 0.0001f);
EXPECT_FLOAT_EQ(orifClipPlaneNear[i], read->mClipPlaneNear);
EXPECT_FLOAT_EQ(orifClipPlaneFar[i], read->mClipPlaneFar);
EXPECT_FLOAT_EQ(pos[i].x, read->mPosition.x);
EXPECT_FLOAT_EQ(pos[i].y, read->mPosition.y);
EXPECT_FLOAT_EQ(pos[i].z, read->mPosition.z);
}
}
#endif // ASSIMP_BUILD_NO_EXPORT

View File

@ -65,8 +65,7 @@ void TriangulateProcessTest::SetUp() {
pcMesh->mFaces = new aiFace[1000];
pcMesh->mVertices = new aiVector3D[10000];
pcMesh->mPrimitiveTypes = aiPrimitiveType_POINT | aiPrimitiveType_LINE |
aiPrimitiveType_LINE | aiPrimitiveType_POLYGON;
pcMesh->mPrimitiveTypes = aiPrimitiveType_POINT | aiPrimitiveType_LINE | aiPrimitiveType_POLYGON;
for (unsigned int m = 0, t = 0, q = 4; m < 1000; ++m) {
++t;

View File

@ -47,10 +47,11 @@ using namespace AssimpView;
// ------------------------------------------------------------------------------------------------
// Constructor on a given animation.
AnimEvaluator::AnimEvaluator( const aiAnimation *pAnim )
: mAnim(pAnim)
, mLastTime(0.0) {
mLastPositions.resize( pAnim->mNumChannels, std::make_tuple( 0, 0, 0));
AnimEvaluator::AnimEvaluator(const aiAnimation *pAnim) :
mAnim(pAnim),
mLastTime(0.0) {
ai_assert(nullptr != pAnim);
mLastPositions.resize(pAnim->mNumChannels, std::make_tuple(0, 0, 0));
}
// ------------------------------------------------------------------------------------------------
@ -61,7 +62,7 @@ AnimEvaluator::~AnimEvaluator() {
// ------------------------------------------------------------------------------------------------
// Evaluates the animation tracks for a given time stamp.
void AnimEvaluator::Evaluate( double pTime ) {
void AnimEvaluator::Evaluate(double pTime) {
// extract ticks per second. Assume default value if not given
double ticksPerSecond = mAnim->mTicksPerSecond != 0.0 ? mAnim->mTicksPerSecond : 25.0;
// every following time calculation happens in ticks
@ -78,16 +79,16 @@ void AnimEvaluator::Evaluate( double pTime ) {
}
// calculate the transformations for each animation channel
for( unsigned int a = 0; a < mAnim->mNumChannels; ++a ) {
const aiNodeAnim* channel = mAnim->mChannels[a];
for (unsigned int a = 0; a < mAnim->mNumChannels; ++a) {
const aiNodeAnim *channel = mAnim->mChannels[a];
// ******** Position *****
aiVector3D presentPosition( 0, 0, 0);
if( channel->mNumPositionKeys > 0) {
aiVector3D presentPosition(0, 0, 0);
if (channel->mNumPositionKeys > 0) {
// Look for present frame number. Search from last position if time is after the last time, else from beginning
// Should be much quicker than always looking from start for the average use case.
unsigned int frame = (time >= mLastTime) ? std::get<0>(mLastPositions[a]) : 0;
while( frame < channel->mNumPositionKeys - 1) {
while (frame < channel->mNumPositionKeys - 1) {
if (time < channel->mPositionKeys[frame + 1].mTime) {
break;
}
@ -96,14 +97,14 @@ void AnimEvaluator::Evaluate( double pTime ) {
// interpolate between this frame's value and next frame's value
unsigned int nextFrame = (frame + 1) % channel->mNumPositionKeys;
const aiVectorKey& key = channel->mPositionKeys[frame];
const aiVectorKey& nextKey = channel->mPositionKeys[nextFrame];
const aiVectorKey &key = channel->mPositionKeys[frame];
const aiVectorKey &nextKey = channel->mPositionKeys[nextFrame];
double diffTime = nextKey.mTime - key.mTime;
if (diffTime < 0.0) {
diffTime += mAnim->mDuration;
}
if( diffTime > 0) {
float factor = float( (time - key.mTime) / diffTime);
if (diffTime > 0) {
float factor = float((time - key.mTime) / diffTime);
presentPosition = key.mValue + (nextKey.mValue - key.mValue) * factor;
} else {
presentPosition = key.mValue;
@ -113,10 +114,10 @@ void AnimEvaluator::Evaluate( double pTime ) {
}
// ******** Rotation *********
aiQuaternion presentRotation( 1, 0, 0, 0);
if( channel->mNumRotationKeys > 0) {
aiQuaternion presentRotation(1, 0, 0, 0);
if (channel->mNumRotationKeys > 0) {
unsigned int frame = (time >= mLastTime) ? std::get<1>(mLastPositions[a]) : 0;
while( frame < channel->mNumRotationKeys - 1) {
while (frame < channel->mNumRotationKeys - 1) {
if (time < channel->mRotationKeys[frame + 1].mTime) {
break;
}
@ -125,15 +126,15 @@ void AnimEvaluator::Evaluate( double pTime ) {
// interpolate between this frame's value and next frame's value
unsigned int nextFrame = (frame + 1) % channel->mNumRotationKeys;
const aiQuatKey& key = channel->mRotationKeys[frame];
const aiQuatKey& nextKey = channel->mRotationKeys[nextFrame];
const aiQuatKey &key = channel->mRotationKeys[frame];
const aiQuatKey &nextKey = channel->mRotationKeys[nextFrame];
double diffTime = nextKey.mTime - key.mTime;
if (diffTime < 0.0) {
diffTime += mAnim->mDuration;
}
if( diffTime > 0) {
float factor = float( (time - key.mTime) / diffTime);
aiQuaternion::Interpolate( presentRotation, key.mValue, nextKey.mValue, factor);
if (diffTime > 0) {
float factor = float((time - key.mTime) / diffTime);
aiQuaternion::Interpolate(presentRotation, key.mValue, nextKey.mValue, factor);
} else {
presentRotation = key.mValue;
}
@ -142,10 +143,10 @@ void AnimEvaluator::Evaluate( double pTime ) {
}
// ******** Scaling **********
aiVector3D presentScaling( 1, 1, 1);
if( channel->mNumScalingKeys > 0) {
aiVector3D presentScaling(1, 1, 1);
if (channel->mNumScalingKeys > 0) {
unsigned int frame = (time >= mLastTime) ? std::get<2>(mLastPositions[a]) : 0;
while( frame < channel->mNumScalingKeys - 1) {
while (frame < channel->mNumScalingKeys - 1) {
if (time < channel->mScalingKeys[frame + 1].mTime) {
break;
}
@ -158,12 +159,20 @@ void AnimEvaluator::Evaluate( double pTime ) {
}
// build a transformation matrix from it
aiMatrix4x4& mat = mTransforms[a];
mat = aiMatrix4x4( presentRotation.GetMatrix());
mat.a1 *= presentScaling.x; mat.b1 *= presentScaling.x; mat.c1 *= presentScaling.x;
mat.a2 *= presentScaling.y; mat.b2 *= presentScaling.y; mat.c2 *= presentScaling.y;
mat.a3 *= presentScaling.z; mat.b3 *= presentScaling.z; mat.c3 *= presentScaling.z;
mat.a4 = presentPosition.x; mat.b4 = presentPosition.y; mat.c4 = presentPosition.z;
aiMatrix4x4 &mat = mTransforms[a];
mat = aiMatrix4x4(presentRotation.GetMatrix());
mat.a1 *= presentScaling.x;
mat.b1 *= presentScaling.x;
mat.c1 *= presentScaling.x;
mat.a2 *= presentScaling.y;
mat.b2 *= presentScaling.y;
mat.c2 *= presentScaling.y;
mat.a3 *= presentScaling.z;
mat.b3 *= presentScaling.z;
mat.c3 *= presentScaling.z;
mat.a4 = presentPosition.x;
mat.b4 = presentPosition.y;
mat.c4 = presentPosition.z;
}
mLastTime = time;

View File

@ -58,7 +58,7 @@ public:
/// the object.
/// @param pAnim The animation to calculate poses for. Ownership of the animation object stays
/// at the caller, the evaluator just keeps a reference to it as long as it persists.
AnimEvaluator( const aiAnimation* pAnim);
AnimEvaluator(const aiAnimation *pAnim);
/// @brief The class destructor.
~AnimEvaluator();
@ -68,16 +68,16 @@ public:
* @param pTime The time for which you want to evaluate the animation, in seconds. Will be mapped into the animation cycle, so
* it can be an arbitrary value. Best use with ever-increasing time stamps.
*/
void Evaluate( double pTime);
void Evaluate(double pTime);
/** Returns the transform matrices calculated at the last Evaluate() call. The array matches the mChannels array of
* the aiAnimation. */
const std::vector<aiMatrix4x4>& GetTransformations() const { return mTransforms; }
const std::vector<aiMatrix4x4> &GetTransformations() const { return mTransforms; }
protected:
const aiAnimation* mAnim;
const aiAnimation *mAnim;
double mLastTime;
std::vector<std::tuple<unsigned int, unsigned int, unsigned int> > mLastPositions;
std::vector<std::tuple<unsigned int, unsigned int, unsigned int>> mLastPositions;
std::vector<aiMatrix4x4> mTransforms;
};

View File

@ -39,7 +39,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#if (!defined AV_ASSET_HELPER_H_INCLUDED)
#define AV_ASSET_HELPER_H_INCLUDED
@ -51,200 +50,187 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace AssimpView {
class SceneAnimator;
class SceneAnimator;
//-------------------------------------------------------------------------------
/** \brief Class to wrap ASSIMP's asset output structures
//-------------------------------------------------------------------------------
/** \brief Class to wrap ASSIMP's asset output structures
*/
//-------------------------------------------------------------------------------
class AssetHelper
{
public:
enum
{
// the original normal set will be used
ORIGINAL = 0x0u,
//-------------------------------------------------------------------------------
class AssetHelper {
public:
enum {
// the original normal set will be used
ORIGINAL = 0x0u,
// a smoothed normal set will be used
SMOOTH = 0x1u,
// a smoothed normal set will be used
SMOOTH = 0x1u,
// a hard normal set will be used
HARD = 0x2u,
};
// a hard normal set will be used
HARD = 0x2u,
};
// default constructor
AssetHelper()
: iNormalSet( ORIGINAL )
{
mAnimator = NULL;
apcMeshes = NULL;
pcScene = NULL;
// default constructor
AssetHelper() :
iNormalSet(ORIGINAL) {
mAnimator = NULL;
apcMeshes = NULL;
pcScene = NULL;
}
//---------------------------------------------------------------
// default vertex data structure
// (even if tangents, bitangents or normals aren't
// required by the shader they will be committed to the GPU)
//---------------------------------------------------------------
struct Vertex {
aiVector3D vPosition;
aiVector3D vNormal;
D3DCOLOR dColorDiffuse;
aiVector3D vTangent;
aiVector3D vBitangent;
aiVector2D vTextureUV;
aiVector2D vTextureUV2;
unsigned char mBoneIndices[4];
unsigned char mBoneWeights[4]; // last Weight not used, calculated inside the vertex shader
/** Returns the vertex declaration elements to create a declaration from. */
static D3DVERTEXELEMENT9 *GetDeclarationElements() {
static D3DVERTEXELEMENT9 decl[] = {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
{ 0, 28, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 },
{ 0, 40, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },
{ 0, 52, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
{ 0, 60, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
{ 0, 68, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0 },
{ 0, 72, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0 },
D3DDECL_END()
};
return decl;
}
};
//---------------------------------------------------------------
// default vertex data structure
// (even if tangents, bitangents or normals aren't
// required by the shader they will be committed to the GPU)
//---------------------------------------------------------------
struct Vertex
{
aiVector3D vPosition;
aiVector3D vNormal;
//---------------------------------------------------------------
// FVF vertex structure used for normals
//---------------------------------------------------------------
struct LineVertex {
aiVector3D vPosition;
DWORD dColorDiffuse;
D3DCOLOR dColorDiffuse;
aiVector3D vTangent;
aiVector3D vBitangent;
aiVector2D vTextureUV;
aiVector2D vTextureUV2;
unsigned char mBoneIndices[ 4 ];
unsigned char mBoneWeights[ 4 ]; // last Weight not used, calculated inside the vertex shader
// retrieves the FVF code of the vertex type
static DWORD GetFVF() {
return D3DFVF_DIFFUSE | D3DFVF_XYZ;
}
};
/** Returns the vertex declaration elements to create a declaration from. */
static D3DVERTEXELEMENT9* GetDeclarationElements()
{
static D3DVERTEXELEMENT9 decl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
{ 0, 28, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 },
{ 0, 40, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },
{ 0, 52, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
{ 0, 60, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
{ 0, 68, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0 },
{ 0, 72, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0 },
D3DDECL_END()
};
return decl;
}
};
//---------------------------------------------------------------
// FVF vertex structure used for normals
//---------------------------------------------------------------
struct LineVertex
{
aiVector3D vPosition;
DWORD dColorDiffuse;
// retrieves the FVF code of the vertex type
static DWORD GetFVF()
{
return D3DFVF_DIFFUSE | D3DFVF_XYZ;
}
};
//---------------------------------------------------------------
// Helper class to store GPU related resources created for
// a given aiMesh
//---------------------------------------------------------------
class MeshHelper
{
public:
MeshHelper()
:
//---------------------------------------------------------------
// Helper class to store GPU related resources created for
// a given aiMesh
//---------------------------------------------------------------
class MeshHelper {
public:
MeshHelper() :
eShadingMode(),
piVB( NULL ),
piIB( NULL ),
piVBNormals( NULL ),
piEffect( NULL ),
bSharedFX( false ),
piDiffuseTexture( NULL ),
piSpecularTexture( NULL ),
piAmbientTexture( NULL ),
piEmissiveTexture( NULL ),
piNormalTexture( NULL ),
piOpacityTexture( NULL ),
piShininessTexture( NULL ),
piLightmapTexture( NULL ),
piVB(NULL),
piIB(NULL),
piVBNormals(NULL),
piEffect(NULL),
bSharedFX(false),
piDiffuseTexture(NULL),
piSpecularTexture(NULL),
piAmbientTexture(NULL),
piEmissiveTexture(NULL),
piNormalTexture(NULL),
piOpacityTexture(NULL),
piShininessTexture(NULL),
piLightmapTexture(NULL),
fOpacity(),
fShininess(),
fSpecularStrength(),
twosided( false ),
pvOriginalNormals( NULL )
{}
twosided(false),
pvOriginalNormals(NULL) {}
~MeshHelper()
{
// NOTE: This is done in DeleteAssetData()
// TODO: Make this a proper d'tor
}
~MeshHelper() {
// NOTE: This is done in DeleteAssetData()
// TODO: Make this a proper d'tor
}
// shading mode to use. Either Lambert or otherwise phong
// will be used in every case
aiShadingMode eShadingMode;
// shading mode to use. Either Lambert or otherwise phong
// will be used in every case
aiShadingMode eShadingMode;
// vertex buffer
IDirect3DVertexBuffer9* piVB;
// vertex buffer
IDirect3DVertexBuffer9 *piVB;
// index buffer. For partially transparent meshes
// created with dynamic usage to be able to update
// the buffer contents quickly
IDirect3DIndexBuffer9* piIB;
// index buffer. For partially transparent meshes
// created with dynamic usage to be able to update
// the buffer contents quickly
IDirect3DIndexBuffer9 *piIB;
// vertex buffer to be used to draw vertex normals
// (vertex normals are generated in every case)
IDirect3DVertexBuffer9* piVBNormals;
// vertex buffer to be used to draw vertex normals
// (vertex normals are generated in every case)
IDirect3DVertexBuffer9 *piVBNormals;
// shader to be used
ID3DXEffect* piEffect;
bool bSharedFX;
// shader to be used
ID3DXEffect *piEffect;
bool bSharedFX;
// material textures
IDirect3DTexture9* piDiffuseTexture;
IDirect3DTexture9* piSpecularTexture;
IDirect3DTexture9* piAmbientTexture;
IDirect3DTexture9* piEmissiveTexture;
IDirect3DTexture9* piNormalTexture;
IDirect3DTexture9* piOpacityTexture;
IDirect3DTexture9* piShininessTexture;
IDirect3DTexture9* piLightmapTexture;
// material textures
IDirect3DTexture9 *piDiffuseTexture;
IDirect3DTexture9 *piSpecularTexture;
IDirect3DTexture9 *piAmbientTexture;
IDirect3DTexture9 *piEmissiveTexture;
IDirect3DTexture9 *piNormalTexture;
IDirect3DTexture9 *piOpacityTexture;
IDirect3DTexture9 *piShininessTexture;
IDirect3DTexture9 *piLightmapTexture;
// material colors
D3DXVECTOR4 vDiffuseColor;
D3DXVECTOR4 vSpecularColor;
D3DXVECTOR4 vAmbientColor;
D3DXVECTOR4 vEmissiveColor;
// material colors
D3DXVECTOR4 vDiffuseColor;
D3DXVECTOR4 vSpecularColor;
D3DXVECTOR4 vAmbientColor;
D3DXVECTOR4 vEmissiveColor;
// opacity for the material
float fOpacity;
// opacity for the material
float fOpacity;
// shininess for the material
float fShininess;
// shininess for the material
float fShininess;
// strength of the specular highlight
float fSpecularStrength;
// strength of the specular highlight
float fSpecularStrength;
// two-sided?
bool twosided;
// two-sided?
bool twosided;
// Stores a pointer to the original normal set of the asset
aiVector3D* pvOriginalNormals;
};
// One instance per aiMesh in the globally loaded asset
MeshHelper** apcMeshes;
// Scene wrapper instance
aiScene* pcScene;
// Animation player to animate the scene if necessary
SceneAnimator* mAnimator;
// Specifies the normal set to be used
unsigned int iNormalSet;
// ------------------------------------------------------------------
// set the normal set to be used
void SetNormalSet( unsigned int iSet );
// ------------------------------------------------------------------
// flip all normal vectors
void FlipNormals();
void FlipNormalsInt();
// Stores a pointer to the original normal set of the asset
aiVector3D *pvOriginalNormals;
};
}
// One instance per aiMesh in the globally loaded asset
MeshHelper **apcMeshes;
// Scene wrapper instance
aiScene *pcScene;
// Animation player to animate the scene if necessary
SceneAnimator *mAnimator;
// Specifies the normal set to be used
unsigned int iNormalSet;
// ------------------------------------------------------------------
// set the normal set to be used
void SetNormalSet(unsigned int iSet);
// ------------------------------------------------------------------
// flip all normal vectors
void FlipNormals();
void FlipNormalsInt();
};
} // namespace AssimpView
#endif // !! IG

View File

@ -118,8 +118,9 @@ CBackgroundPainter CBackgroundPainter::s_cInstance;
//-------------------------------------------------------------------------------
void CBackgroundPainter::SetColor(D3DCOLOR p_clrNew) {
if (TEXTURE_CUBE == eMode)
if (TEXTURE_CUBE == eMode) {
RemoveSBDeps();
}
clrColor = p_clrNew;
eMode = SIMPLE_COLOR;

View File

@ -45,164 +45,154 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssetHelper.h"
namespace AssimpView
{
namespace AssimpView {
//-------------------------------------------------------------------------------
/* Helper class to create, access and destroy materials
//-------------------------------------------------------------------------------
/* Helper class to create, access and destroy materials
*/
//-------------------------------------------------------------------------------
class CMaterialManager
{
private:
//-------------------------------------------------------------------------------
class CMaterialManager {
private:
friend class CDisplay;
friend class CDisplay;
// default constructor
CMaterialManager() :
m_iShaderCount(0), sDefaultTexture() {}
// default constructor
CMaterialManager()
: m_iShaderCount( 0 ), sDefaultTexture() {}
~CMaterialManager() {
if( sDefaultTexture ) {
sDefaultTexture->Release();
}
Reset();
~CMaterialManager() {
if (sDefaultTexture) {
sDefaultTexture->Release();
}
Reset();
}
public:
public:
//------------------------------------------------------------------
// Singleton accessors
static CMaterialManager s_cInstance;
inline static CMaterialManager &Instance() {
return s_cInstance;
}
//------------------------------------------------------------------
// Singleton accessors
static CMaterialManager s_cInstance;
inline static CMaterialManager& Instance()
{
return s_cInstance;
//------------------------------------------------------------------
// Delete all resources of a given material
//
// Must be called before CreateMaterial() to prevent memory leaking
void DeleteMaterial(AssetHelper::MeshHelper *pcIn);
//------------------------------------------------------------------
// Create the material for a mesh.
//
// The function checks whether an identical shader is already in use.
// A shader is considered to be identical if it has the same input
// signature and takes the same number of texture channels.
int CreateMaterial(AssetHelper::MeshHelper *pcMesh,
const aiMesh *pcSource);
//------------------------------------------------------------------
// Setup the material for a given mesh
// pcMesh Mesh to be rendered
// pcProj Projection matrix
// aiMe Current world matrix
// pcCam Camera matrix
// vPos Position of the camera
// TODO: Extract camera position from matrix ...
//
int SetupMaterial(AssetHelper::MeshHelper *pcMesh,
const aiMatrix4x4 &pcProj,
const aiMatrix4x4 &aiMe,
const aiMatrix4x4 &pcCam,
const aiVector3D &vPos);
//------------------------------------------------------------------
// End the material for a given mesh
// Called after mesh rendering is complete
// pcMesh Mesh object
int EndMaterial(AssetHelper::MeshHelper *pcMesh);
//------------------------------------------------------------------
// Recreate all specular materials depending on the current
// specularity settings
//
// Diffuse-only materials are ignored.
// Must be called after specular highlights have been toggled
int UpdateSpecularMaterials();
//------------------------------------------------------------------
// find a valid path to a texture file
//
// Handle 8.3 syntax correctly, search the environment of the
// executable and the asset for a texture with a name very similar
// to a given one
int FindValidPath(aiString *p_szString);
//------------------------------------------------------------------
// Load a texture into memory and create a native D3D texture resource
//
// The function tries to find a valid path for a texture
int LoadTexture(IDirect3DTexture9 **p_ppiOut, aiString *szPath);
//------------------------------------------------------------------
// Getter for m_iShaderCount
//
inline unsigned int GetShaderCount() {
return this->m_iShaderCount;
}
//------------------------------------------------------------------
// Reset the state of the class
// Called whenever a new asset is loaded
inline void Reset() {
this->m_iShaderCount = 0;
for (TextureCache::iterator it = sCachedTextures.begin(); it != sCachedTextures.end(); ++it) {
(*it).second->Release();
}
sCachedTextures.clear();
}
//------------------------------------------------------------------
// Delete all resources of a given material
//
// Must be called before CreateMaterial() to prevent memory leaking
void DeleteMaterial( AssetHelper::MeshHelper* pcIn );
private:
//------------------------------------------------------------------
// find a valid path to a texture file
//
// Handle 8.3 syntax correctly, search the environment of the
// executable and the asset for a texture with a name very similar
// to a given one
bool TryLongerPath(char *szTemp, aiString *p_szString);
//------------------------------------------------------------------
// Create the material for a mesh.
//
// The function checks whether an identical shader is already in use.
// A shader is considered to be identical if it has the same input
// signature and takes the same number of texture channels.
int CreateMaterial( AssetHelper::MeshHelper* pcMesh,
const aiMesh* pcSource );
//------------------------------------------------------------------
// Setup the default texture for a texture channel
//
// Generates a default checker pattern for a texture
int SetDefaultTexture(IDirect3DTexture9 **p_ppiOut);
//------------------------------------------------------------------
// Setup the material for a given mesh
// pcMesh Mesh to be rendered
// pcProj Projection matrix
// aiMe Current world matrix
// pcCam Camera matrix
// vPos Position of the camera
// TODO: Extract camera position from matrix ...
//
int SetupMaterial( AssetHelper::MeshHelper* pcMesh,
const aiMatrix4x4& pcProj,
const aiMatrix4x4& aiMe,
const aiMatrix4x4& pcCam,
const aiVector3D& vPos );
//------------------------------------------------------------------
// Convert a height map to a normal map if necessary
//
// The function tries to detect the type of a texture automatically.
// However, this won't work in every case.
void HMtoNMIfNecessary(IDirect3DTexture9 *piTexture,
IDirect3DTexture9 **piTextureOut,
bool bWasOriginallyHM = true);
//------------------------------------------------------------------
// End the material for a given mesh
// Called after mesh rendering is complete
// pcMesh Mesh object
int EndMaterial( AssetHelper::MeshHelper* pcMesh );
//------------------------------------------------------------------
// Search for non-opaque pixels in a texture
//
// A pixel is considered to be non-opaque if its alpha value is
// less than 255
//------------------------------------------------------------------
bool HasAlphaPixels(IDirect3DTexture9 *piTexture);
//------------------------------------------------------------------
// Recreate all specular materials depending on the current
// specularity settings
//
// Diffuse-only materials are ignored.
// Must be called after specular highlights have been toggled
int UpdateSpecularMaterials();
private:
//
// Specifies the number of different shaders generated for
// the current asset. This number is incremented by CreateMaterial()
// each time a shader isn't found in cache and needs to be created
//
unsigned int m_iShaderCount;
IDirect3DTexture9 *sDefaultTexture;
//------------------------------------------------------------------
// find a valid path to a texture file
//
// Handle 8.3 syntax correctly, search the environment of the
// executable and the asset for a texture with a name very similar
// to a given one
int FindValidPath( aiString* p_szString );
typedef std::map<std::string, IDirect3DTexture9 *> TextureCache;
TextureCache sCachedTextures;
};
//------------------------------------------------------------------
// Load a texture into memory and create a native D3D texture resource
//
// The function tries to find a valid path for a texture
int LoadTexture( IDirect3DTexture9** p_ppiOut, aiString* szPath );
//------------------------------------------------------------------
// Getter for m_iShaderCount
//
inline unsigned int GetShaderCount()
{
return this->m_iShaderCount;
}
//------------------------------------------------------------------
// Reset the state of the class
// Called whenever a new asset is loaded
inline void Reset()
{
this->m_iShaderCount = 0;
for( TextureCache::iterator it = sCachedTextures.begin(); it != sCachedTextures.end(); ++it ) {
( *it ).second->Release();
}
sCachedTextures.clear();
}
private:
//------------------------------------------------------------------
// find a valid path to a texture file
//
// Handle 8.3 syntax correctly, search the environment of the
// executable and the asset for a texture with a name very similar
// to a given one
bool TryLongerPath( char* szTemp, aiString* p_szString );
//------------------------------------------------------------------
// Setup the default texture for a texture channel
//
// Generates a default checker pattern for a texture
int SetDefaultTexture( IDirect3DTexture9** p_ppiOut );
//------------------------------------------------------------------
// Convert a height map to a normal map if necessary
//
// The function tries to detect the type of a texture automatically.
// However, this won't work in every case.
void HMtoNMIfNecessary( IDirect3DTexture9* piTexture,
IDirect3DTexture9** piTextureOut,
bool bWasOriginallyHM = true );
//------------------------------------------------------------------
// Search for non-opaque pixels in a texture
//
// A pixel is considered to be non-opaque if its alpha value is
// less than 255
//------------------------------------------------------------------
bool HasAlphaPixels( IDirect3DTexture9* piTexture );
private:
//
// Specifies the number of different shaders generated for
// the current asset. This number is incremented by CreateMaterial()
// each time a shader isn't found in cache and needs to be created
//
unsigned int m_iShaderCount;
IDirect3DTexture9* sDefaultTexture;
typedef std::map<std::string, IDirect3DTexture9*> TextureCache;
TextureCache sCachedTextures;
};
}
} // namespace AssimpView

View File

@ -58,8 +58,8 @@ namespace AssimpView {
*/
struct SceneAnimNode {
std::string mName;
SceneAnimNode* mParent;
std::vector<SceneAnimNode*> mChildren;
SceneAnimNode *mParent;
std::vector<SceneAnimNode *> mChildren;
//! most recently calculated local transform
aiMatrix4x4 mLocalTransform;
@ -71,30 +71,20 @@ struct SceneAnimNode {
int mChannelIndex;
//! Default construction
SceneAnimNode()
: mName()
, mParent(nullptr)
, mChildren()
, mLocalTransform()
, mGlobalTransform()
, mChannelIndex(-1) {
SceneAnimNode() :
mName(), mParent(nullptr), mChildren(), mLocalTransform(), mGlobalTransform(), mChannelIndex(-1) {
// empty
}
//! Construction from a given name
SceneAnimNode( const std::string& pName)
: mName( pName)
, mParent(nullptr)
, mChildren()
, mLocalTransform()
, mGlobalTransform()
, mChannelIndex(-1) {
SceneAnimNode(const std::string &pName) :
mName(pName), mParent(nullptr), mChildren(), mLocalTransform(), mGlobalTransform(), mChannelIndex(-1) {
// empty
}
//! Destruct all children recursively
~SceneAnimNode() {
for (std::vector<SceneAnimNode*>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) {
for (std::vector<SceneAnimNode *>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) {
delete *it;
}
}
@ -112,7 +102,6 @@ struct SceneAnimNode {
*/
class SceneAnimator {
public:
// ----------------------------------------------------------------------------
/** Constructor for a given scene.
*
@ -122,7 +111,7 @@ public:
* @param pAnimIndex [optional] Index of the animation to play. Assumed to
* be 0 if not given.
*/
SceneAnimator( const aiScene* pScene, size_t pAnimIndex = 0);
SceneAnimator(const aiScene *pScene, size_t pAnimIndex = 0);
/** Destructor */
~SceneAnimator();
@ -132,14 +121,14 @@ public:
* mapping structures, which might take a few cycles.
* @param pAnimIndex Index of the animation in the scene's animation array
*/
void SetAnimIndex( size_t pAnimIndex);
void SetAnimIndex(size_t pAnimIndex);
// ----------------------------------------------------------------------------
/** Calculates the node transformations for the scene. Call this to get
* uptodate results before calling one of the getters.
* @param pTime Current time. Can be an arbitrary range.
*/
void Calculate( double pTime);
void Calculate(double pTime);
// ----------------------------------------------------------------------------
/** Retrieves the most recent local transformation matrix for the given node.
@ -154,7 +143,7 @@ public:
* @return A reference to the node's most recently calculated local
* transformation matrix.
*/
const aiMatrix4x4& GetLocalTransform( const aiNode* node) const;
const aiMatrix4x4 &GetLocalTransform(const aiNode *node) const;
// ----------------------------------------------------------------------------
/** Retrieves the most recent global transformation matrix for the given node.
@ -169,7 +158,7 @@ public:
* @return A reference to the node's most recently calculated global
* transformation matrix.
*/
const aiMatrix4x4& GetGlobalTransform( const aiNode* node) const;
const aiMatrix4x4 &GetGlobalTransform(const aiNode *node) const;
// ----------------------------------------------------------------------------
/** Calculates the bone matrices for the given mesh.
@ -187,8 +176,8 @@ public:
* @return A reference to a vector of bone matrices. Stays stable till the
* next call to GetBoneMatrices();
*/
const std::vector<aiMatrix4x4>& GetBoneMatrices( const aiNode* pNode,
size_t pMeshIndex = 0);
const std::vector<aiMatrix4x4> &GetBoneMatrices(const aiNode *pNode,
size_t pMeshIndex = 0);
// ----------------------------------------------------------------------------
/** @brief Get the current animation index
@ -200,44 +189,43 @@ public:
// ----------------------------------------------------------------------------
/** @brief Get the current animation or NULL
*/
aiAnimation* CurrentAnim() const {
return static_cast<unsigned int>( mCurrentAnimIndex ) < mScene->mNumAnimations ? mScene->mAnimations[ mCurrentAnimIndex ] : NULL;
aiAnimation *CurrentAnim() const {
return static_cast<unsigned int>(mCurrentAnimIndex) < mScene->mNumAnimations ? mScene->mAnimations[mCurrentAnimIndex] : NULL;
}
protected:
/** Recursively creates an internal node structure matching the
* current scene and animation.
*/
SceneAnimNode* CreateNodeTree( aiNode* pNode, SceneAnimNode* pParent);
SceneAnimNode *CreateNodeTree(aiNode *pNode, SceneAnimNode *pParent);
/** Recursively updates the internal node transformations from the
* given matrix array
*/
void UpdateTransforms( SceneAnimNode* pNode, const std::vector<aiMatrix4x4>& pTransforms);
void UpdateTransforms(SceneAnimNode *pNode, const std::vector<aiMatrix4x4> &pTransforms);
/** Calculates the global transformation matrix for the given internal node */
void CalculateGlobalTransform( SceneAnimNode* pInternalNode);
void CalculateGlobalTransform(SceneAnimNode *pInternalNode);
protected:
/** The scene we're operating on */
const aiScene* mScene;
const aiScene *mScene;
/** Current animation index */
int mCurrentAnimIndex;
/** The AnimEvaluator we use to calculate the current pose for the current animation */
AnimEvaluator* mAnimEvaluator;
AnimEvaluator *mAnimEvaluator;
/** Root node of the internal scene structure */
SceneAnimNode* mRootNode;
SceneAnimNode *mRootNode;
/** Name to node map to quickly find nodes by their name */
typedef std::map<const aiNode*, SceneAnimNode*> NodeMap;
typedef std::map<const aiNode *, SceneAnimNode *> NodeMap;
NodeMap mNodesByName;
/** Name to node map to quickly find nodes for given bones by their name */
typedef std::map<const char*, const aiNode*> BoneMap;
typedef std::map<const char *, const aiNode *> BoneMap;
BoneMap mBoneNodesByName;
/** Array to return transformations results inside. */

Some files were not shown because too many files have changed in this diff Show More