Merge branch 'master' into bug-3201-collada_root_meshes
commit
cfbdacb02a
|
@ -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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
@ -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
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
==================
|
||||
==================
|
||||
INSTALLATION GUIDE
|
||||
==================
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -4,5 +4,3 @@ http://assimp.sourceforge.net
|
|||
|
||||
Sourceforge.net project page:
|
||||
http://www.sourceforge.net/projects/assimp
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
@ -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]
|
|
@ -0,0 +1 @@
|
|||
pub use self::structs::{Camera};
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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 {}
|
|
@ -0,0 +1,6 @@
|
|||
mod anim;
|
||||
pub use self::anim::{
|
||||
Animation,
|
||||
NodeAnim,
|
||||
MeshAnim,
|
||||
MeshMorphAnim};
|
|
@ -0,0 +1,2 @@
|
|||
mod blob;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mod bone;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mod camera;
|
||||
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
mod color;
|
||||
pub use self::color::{
|
||||
Color3D,
|
||||
Color4D
|
||||
};
|
|
@ -0,0 +1,2 @@
|
|||
mod face;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mod key;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mod light;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mod material;
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
mod matrix;
|
||||
pub use self::matrix::{
|
||||
Matrix3x3,
|
||||
Matrix4x4};
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
mod memory;
|
||||
pub use self::memory::MemoryInfo;
|
|
@ -0,0 +1,3 @@
|
|||
mod mesh;
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mod meta;
|
||||
|
|
@ -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 */
|
|
@ -0,0 +1,2 @@
|
|||
mod node;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mod plane;
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
mod quaternion;
|
||||
|
||||
pub use self::quaternion::Quaternion;
|
|
@ -0,0 +1,7 @@
|
|||
use crate::vec;
|
||||
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub struct Quaternion {
|
||||
_coordinates: vec::Vector4d
|
||||
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
mod ray;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mod scene;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
mod string;
|
||||
pub use self::string::MAXLEN;
|
||||
pub use self::string::Str;
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
mod texture;
|
||||
pub use self::texture::Texel;
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
mod transform;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mod vec;
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mod vertex;
|
||||
// pub use self::vertex::
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue