Merge branch 'master' into fix_obj_progress_reporting
commit
19c3cea0db
|
@ -966,6 +966,9 @@ if( MSVC )
|
|||
set(LIBRARY_SUFFIX "${ASSIMP_LIBRARY_SUFFIX}-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library")
|
||||
endif()
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "WindowsStore")
|
||||
set(WindowsStore TRUE)
|
||||
endif()
|
||||
SET_TARGET_PROPERTIES( assimp PROPERTIES
|
||||
VERSION ${ASSIMP_VERSION}
|
||||
SOVERSION ${ASSIMP_SOVERSION} # use full version
|
||||
|
|
|
@ -728,8 +728,11 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|||
std::vector<aiAnimMesh*> animMeshes;
|
||||
for (unsigned int i = 0; i < targetMeshes.size(); i++)
|
||||
{
|
||||
aiAnimMesh *animMesh = aiCreateAnimMesh(targetMeshes.at(i));
|
||||
animMesh->mWeight = targetWeights[i];
|
||||
aiMesh* targetMesh = targetMeshes.at(i);
|
||||
aiAnimMesh *animMesh = aiCreateAnimMesh(targetMesh);
|
||||
float weight = targetWeights[i];
|
||||
animMesh->mWeight = weight == 0 ? 1.0f : weight;
|
||||
animMesh->mName = targetMesh->mName;
|
||||
animMeshes.push_back(animMesh);
|
||||
}
|
||||
dstMesh->mMethod = (method == Collada::Relative)
|
||||
|
|
|
@ -166,8 +166,9 @@ void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh) {
|
|||
for( size_t a = 0; a < pMesh->mNumVertices; ++a)
|
||||
{
|
||||
pMesh->mVertices[a].z *= -1.0f;
|
||||
if( pMesh->HasNormals())
|
||||
if (pMesh->HasNormals()) {
|
||||
pMesh->mNormals[a].z *= -1.0f;
|
||||
}
|
||||
if( pMesh->HasTangentsAndBitangents())
|
||||
{
|
||||
pMesh->mTangents[a].z *= -1.0f;
|
||||
|
@ -175,6 +176,23 @@ void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh) {
|
|||
}
|
||||
}
|
||||
|
||||
// mirror anim meshes positions, normals and stuff along the Z axis
|
||||
for (size_t m = 0; m < pMesh->mNumAnimMeshes; ++m)
|
||||
{
|
||||
for (size_t a = 0; a < pMesh->mAnimMeshes[m]->mNumVertices; ++a)
|
||||
{
|
||||
pMesh->mAnimMeshes[m]->mVertices[a].z *= -1.0f;
|
||||
if (pMesh->mAnimMeshes[m]->HasNormals()) {
|
||||
pMesh->mAnimMeshes[m]->mNormals[a].z *= -1.0f;
|
||||
}
|
||||
if (pMesh->mAnimMeshes[m]->HasTangentsAndBitangents())
|
||||
{
|
||||
pMesh->mAnimMeshes[m]->mTangents[a].z *= -1.0f;
|
||||
pMesh->mAnimMeshes[m]->mBitangents[a].z *= -1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mirror offset matrices of all bones
|
||||
for( size_t a = 0; a < pMesh->mNumBones; ++a)
|
||||
{
|
||||
|
@ -346,8 +364,50 @@ void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh)
|
|||
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
|
||||
{
|
||||
aiFace& face = pMesh->mFaces[a];
|
||||
for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
|
||||
std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
|
||||
for (unsigned int b = 0; b < face.mNumIndices / 2; b++) {
|
||||
std::swap(face.mIndices[b], face.mIndices[face.mNumIndices - 1 - b]);
|
||||
}
|
||||
}
|
||||
|
||||
// invert the order of all components in this mesh anim meshes
|
||||
for (unsigned int m = 0; m < pMesh->mNumAnimMeshes; m++) {
|
||||
aiAnimMesh* animMesh = pMesh->mAnimMeshes[m];
|
||||
unsigned int numVertices = animMesh->mNumVertices;
|
||||
if (animMesh->HasPositions()) {
|
||||
for (unsigned int a = 0; a < numVertices; a++)
|
||||
{
|
||||
std::swap(animMesh->mVertices[a], animMesh->mVertices[numVertices - 1 - a]);
|
||||
}
|
||||
}
|
||||
if (animMesh->HasNormals()) {
|
||||
for (unsigned int a = 0; a < numVertices; a++)
|
||||
{
|
||||
std::swap(animMesh->mNormals[a], animMesh->mNormals[numVertices - 1 - a]);
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) {
|
||||
if (animMesh->HasTextureCoords(i)) {
|
||||
for (unsigned int a = 0; a < numVertices; a++)
|
||||
{
|
||||
std::swap(animMesh->mTextureCoords[i][a], animMesh->mTextureCoords[i][numVertices - 1 - a]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (animMesh->HasTangentsAndBitangents()) {
|
||||
for (unsigned int a = 0; a < numVertices; a++)
|
||||
{
|
||||
std::swap(animMesh->mTangents[a], animMesh->mTangents[numVertices - 1 - a]);
|
||||
std::swap(animMesh->mBitangents[a], animMesh->mBitangents[numVertices - 1 - a]);
|
||||
}
|
||||
}
|
||||
for (unsigned int v = 0; v < AI_MAX_NUMBER_OF_COLOR_SETS; v++) {
|
||||
if (animMesh->HasVertexColors(v)) {
|
||||
for (unsigned int a = 0; a < numVertices; a++)
|
||||
{
|
||||
std::swap(animMesh->mColors[v][a], animMesh->mColors[v][numVertices - 1 - a]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ bool DefaultIOSystem::Exists( const char* pFile) const
|
|||
#ifdef _WIN32
|
||||
wchar_t fileName16[PATHLIMIT];
|
||||
|
||||
#ifndef WindowsStore
|
||||
bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL) != 0;
|
||||
if (isUnicode) {
|
||||
|
||||
|
@ -85,12 +86,15 @@ bool DefaultIOSystem::Exists( const char* pFile) const
|
|||
return false;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
FILE* file = ::fopen(pFile, "rb");
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
::fclose(file);
|
||||
#ifndef WindowsStore
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
FILE* file = ::fopen( pFile, "rb");
|
||||
if( !file)
|
||||
|
@ -110,14 +114,18 @@ IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
|
|||
FILE* file;
|
||||
#ifdef _WIN32
|
||||
wchar_t fileName16[PATHLIMIT];
|
||||
#ifndef WindowsStore
|
||||
bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL) != 0;
|
||||
if (isUnicode) {
|
||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
|
||||
std::string mode8(strMode);
|
||||
file = ::_wfopen(fileName16, std::wstring(mode8.begin(), mode8.end()).c_str());
|
||||
} else {
|
||||
#endif
|
||||
file = ::fopen(strFile, strMode);
|
||||
#ifndef WindowsStore
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
file = ::fopen(strFile, strMode);
|
||||
#endif
|
||||
|
@ -158,6 +166,7 @@ inline static void MakeAbsolutePath (const char* in, char* _out)
|
|||
{
|
||||
ai_assert(in && _out);
|
||||
#if defined( _MSC_VER ) || defined( __MINGW32__ )
|
||||
#ifndef WindowsStore
|
||||
bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL) != 0;
|
||||
if (isUnicode) {
|
||||
wchar_t out16[PATHLIMIT];
|
||||
|
@ -175,6 +184,7 @@ inline static void MakeAbsolutePath (const char* in, char* _out)
|
|||
}
|
||||
|
||||
} else {
|
||||
#endif
|
||||
char* ret = :: _fullpath(_out, in, PATHLIMIT);
|
||||
if (!ret) {
|
||||
// preserve the input path, maybe someone else is able to fix
|
||||
|
@ -182,7 +192,9 @@ inline static void MakeAbsolutePath (const char* in, char* _out)
|
|||
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
|
||||
strcpy(_out, in);
|
||||
}
|
||||
#ifndef WindowsStore
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
// use realpath
|
||||
char* ret = realpath(in, _out);
|
||||
|
|
|
@ -105,8 +105,8 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons
|
|||
const Scope& sc = GetRequiredScope(element);
|
||||
|
||||
// find target node
|
||||
const char* whitelist[] = {"Model","NodeAttribute"};
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,2);
|
||||
const char* whitelist[] = {"Model","NodeAttribute","Deformer"};
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,3);
|
||||
|
||||
for(const Connection* con : conns) {
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -63,6 +63,12 @@ struct aiScene;
|
|||
struct aiNode;
|
||||
struct aiMaterial;
|
||||
|
||||
struct morphKeyData {
|
||||
std::vector<unsigned int> values;
|
||||
std::vector<float> weights;
|
||||
};
|
||||
typedef std::map<int64_t, morphKeyData*> morphAnimData;
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
|
@ -272,6 +278,7 @@ private:
|
|||
// the function is guaranteed to provide consistent results over multiple invocations
|
||||
// UNLESS RenameNode() is called for a particular node name.
|
||||
std::string FixNodeName(const std::string& name);
|
||||
std::string FixAnimMeshName(const std::string& name);
|
||||
|
||||
typedef std::map<const AnimationCurveNode*, const AnimationLayer*> LayerMap;
|
||||
|
||||
|
@ -281,6 +288,9 @@ private:
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertAnimationStack(const AnimationStack& st);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessMorphAnimDatas(std::map<std::string, morphAnimData*>* morphAnimDatas, const BlendShapeChannel* bsc, const AnimationCurveNode* node);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void GenerateNodeAnimations(std::vector<aiNodeAnim*>& node_anims,
|
||||
const std::string& fixed_name,
|
||||
|
|
|
@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "FBXParser.h"
|
||||
#include "FBXDocument.h"
|
||||
#include "FBXMeshGeometry.h"
|
||||
#include "FBXImporter.h"
|
||||
#include "FBXDocumentUtil.h"
|
||||
|
||||
|
@ -158,9 +159,55 @@ Skin::~Skin()
|
|||
{
|
||||
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: Deformer(id, element, doc, name)
|
||||
{
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(), "Deformer");
|
||||
blendShapeChannels.reserve(conns.size());
|
||||
for (const Connection* con : conns) {
|
||||
const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
|
||||
if (bspc) {
|
||||
blendShapeChannels.push_back(bspc);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BlendShape::~BlendShape()
|
||||
{
|
||||
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: Deformer(id, element, doc, name)
|
||||
{
|
||||
const Scope& sc = GetRequiredScope(element);
|
||||
const Element* const DeformPercent = sc["DeformPercent"];
|
||||
if (DeformPercent) {
|
||||
percent = ParseTokenAsFloat(GetRequiredToken(*DeformPercent, 0));
|
||||
}
|
||||
const Element* const FullWeights = sc["FullWeights"];
|
||||
if (FullWeights) {
|
||||
ParseVectorDataArray(fullWeights, *FullWeights);
|
||||
}
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(), "Geometry");
|
||||
shapeGeometries.reserve(conns.size());
|
||||
for (const Connection* con : conns) {
|
||||
const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
|
||||
if (sg) {
|
||||
shapeGeometries.push_back(sg);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BlendShapeChannel::~BlendShapeChannel()
|
||||
{
|
||||
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -146,6 +146,9 @@ const Object* LazyObject::Get(bool dieOnError)
|
|||
if (!strcmp(classtag.c_str(),"Mesh")) {
|
||||
object.reset(new MeshGeometry(id,element,name,doc));
|
||||
}
|
||||
if (!strcmp(classtag.c_str(), "Shape")) {
|
||||
object.reset(new ShapeGeometry(id, element, name, doc));
|
||||
}
|
||||
}
|
||||
else if (!strncmp(obtype,"NodeAttribute",length)) {
|
||||
if (!strcmp(classtag.c_str(),"Camera")) {
|
||||
|
@ -171,6 +174,12 @@ const Object* LazyObject::Get(bool dieOnError)
|
|||
else if (!strcmp(classtag.c_str(),"Skin")) {
|
||||
object.reset(new Skin(id,element,doc,name));
|
||||
}
|
||||
else if (!strcmp(classtag.c_str(), "BlendShape")) {
|
||||
object.reset(new BlendShape(id, element, doc, name));
|
||||
}
|
||||
else if (!strcmp(classtag.c_str(), "BlendShapeChannel")) {
|
||||
object.reset(new BlendShapeChannel(id, element, doc, name));
|
||||
}
|
||||
}
|
||||
else if ( !strncmp( obtype, "Model", length ) ) {
|
||||
// FK and IK effectors are not supported
|
||||
|
|
|
@ -65,6 +65,7 @@ struct ImportSettings;
|
|||
class PropertyTable;
|
||||
class Document;
|
||||
class Material;
|
||||
class ShapeGeometry;
|
||||
class Geometry;
|
||||
|
||||
class Video;
|
||||
|
@ -74,6 +75,8 @@ class AnimationCurveNode;
|
|||
class AnimationLayer;
|
||||
class AnimationStack;
|
||||
|
||||
class BlendShapeChannel;
|
||||
class BlendShape;
|
||||
class Skin;
|
||||
class Cluster;
|
||||
|
||||
|
@ -869,6 +872,46 @@ private:
|
|||
typedef std::vector<float> WeightArray;
|
||||
typedef std::vector<unsigned int> WeightIndexArray;
|
||||
|
||||
|
||||
/** DOM class for BlendShapeChannel deformers */
|
||||
class BlendShapeChannel : public Deformer
|
||||
{
|
||||
public:
|
||||
BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
virtual ~BlendShapeChannel();
|
||||
|
||||
float DeformPercent() const {
|
||||
return percent;
|
||||
}
|
||||
|
||||
const WeightArray& GetFullWeights() const {
|
||||
return fullWeights;
|
||||
}
|
||||
|
||||
const std::vector<const ShapeGeometry*>& GetShapeGeometries() const {
|
||||
return shapeGeometries;
|
||||
}
|
||||
private:
|
||||
float percent;
|
||||
WeightArray fullWeights;
|
||||
std::vector<const ShapeGeometry*> shapeGeometries;
|
||||
};
|
||||
|
||||
/** DOM class for BlendShape deformers */
|
||||
class BlendShape : public Deformer
|
||||
{
|
||||
public:
|
||||
BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
virtual ~BlendShape();
|
||||
|
||||
const std::vector<const BlendShapeChannel*>& BlendShapeChannels() const {
|
||||
return blendShapeChannels;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<const BlendShapeChannel*> blendShapeChannels;
|
||||
};
|
||||
|
||||
/** DOM class for skin deformer clusters (aka subdeformers) */
|
||||
class Cluster : public Deformer
|
||||
{
|
||||
|
|
|
@ -62,7 +62,7 @@ using namespace Util;
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||
: Object(id, element,name)
|
||||
: Object(id, element, name)
|
||||
, skin()
|
||||
{
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
|
||||
|
@ -70,18 +70,26 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
|
|||
const Skin* const sk = ProcessSimpleConnection<Skin>(*con, false, "Skin -> Geometry", element);
|
||||
if(sk) {
|
||||
skin = sk;
|
||||
break;
|
||||
}
|
||||
const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element);
|
||||
if (bsp) {
|
||||
blendShapes.push_back(bsp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Geometry::~Geometry()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const {
|
||||
return blendShapes;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Skin* Geometry::DeformerSkin() const {
|
||||
return skin;
|
||||
}
|
||||
|
@ -232,7 +240,6 @@ const std::vector<aiColor4D>& MeshGeometry::GetVertexColors( unsigned int index
|
|||
const MatIndexArray& MeshGeometry::GetMaterialIndices() const {
|
||||
return m_materials;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const unsigned int* MeshGeometry::ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const {
|
||||
if ( in_index >= m_mapping_counts.size() ) {
|
||||
|
@ -640,9 +647,39 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
|
|||
<< MappingInformationType << "," << ReferenceInformationType);
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ShapeGeometry::ShapeGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||
: Geometry(id, element, name, doc)
|
||||
{
|
||||
const Scope* sc = element.Compound();
|
||||
if (!sc) {
|
||||
DOMError("failed to read Geometry object (class: Shape), no data scope found");
|
||||
}
|
||||
const Element& Indexes = GetRequiredElement(*sc, "Indexes", &element);
|
||||
const Element& Normals = GetRequiredElement(*sc, "Normals", &element);
|
||||
const Element& Vertices = GetRequiredElement(*sc, "Vertices", &element);
|
||||
ParseVectorDataArray(m_indices, Indexes);
|
||||
ParseVectorDataArray(m_vertices, Vertices);
|
||||
ParseVectorDataArray(m_normals, Normals);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ShapeGeometry::~ShapeGeometry() {
|
||||
// empty
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const std::vector<aiVector3D>& ShapeGeometry::GetVertices() const {
|
||||
return m_vertices;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const std::vector<aiVector3D>& ShapeGeometry::GetNormals() const {
|
||||
return m_normals;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const std::vector<unsigned int>& ShapeGeometry::GetIndices() const {
|
||||
return m_indices;
|
||||
}
|
||||
} // !FBX
|
||||
} // !Assimp
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -64,8 +64,13 @@ public:
|
|||
/** Get the Skin attached to this geometry or NULL */
|
||||
const Skin* DeformerSkin() const;
|
||||
|
||||
/** Get the BlendShape attached to this geometry or NULL */
|
||||
const std::vector<const BlendShape*>& GetBlendShapes() const;
|
||||
|
||||
private:
|
||||
const Skin* skin;
|
||||
std::vector<const BlendShape*> blendShapes;
|
||||
|
||||
};
|
||||
|
||||
typedef std::vector<int> MatIndexArray;
|
||||
|
@ -125,7 +130,6 @@ public:
|
|||
/** Determine the face to which a particular output vertex index belongs.
|
||||
* This mapping is always unique. */
|
||||
unsigned int FaceForVertexIndex( unsigned int in_index ) const;
|
||||
|
||||
private:
|
||||
void ReadLayer( const Scope& layer );
|
||||
void ReadLayerElement( const Scope& layerElement );
|
||||
|
@ -174,6 +178,34 @@ private:
|
|||
std::vector<unsigned int> m_mappings;
|
||||
};
|
||||
|
||||
/**
|
||||
* DOM class for FBX geometry of type "Shape"
|
||||
*/
|
||||
class ShapeGeometry : public Geometry
|
||||
{
|
||||
public:
|
||||
/** The class constructor */
|
||||
ShapeGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||
|
||||
/** The class destructor */
|
||||
virtual ~ShapeGeometry();
|
||||
|
||||
/** Get a list of all vertex points, non-unique*/
|
||||
const std::vector<aiVector3D>& GetVertices() const;
|
||||
|
||||
/** Get a list of all vertex normals or an empty array if
|
||||
* no normals are specified. */
|
||||
const std::vector<aiVector3D>& GetNormals() const;
|
||||
|
||||
/** Return list of vertex indices. */
|
||||
const std::vector<unsigned int>& GetIndices() const;
|
||||
|
||||
private:
|
||||
std::vector<aiVector3D> m_vertices;
|
||||
std::vector<aiVector3D> m_normals;
|
||||
std::vector<unsigned int> m_indices;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -207,10 +207,21 @@ void IFCImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
|||
}
|
||||
uint8_t* buff = new uint8_t[fileInfo.uncompressed_size];
|
||||
LogInfo("Decompressing IFCZIP file");
|
||||
unzOpenCurrentFile( zip );
|
||||
const int ret = unzReadCurrentFile( zip, buff, fileInfo.uncompressed_size);
|
||||
unzOpenCurrentFile(zip);
|
||||
size_t total = 0;
|
||||
int read = 0;
|
||||
do {
|
||||
int bufferSize = fileInfo.uncompressed_size < INT16_MAX ? fileInfo.uncompressed_size : INT16_MAX;
|
||||
void* buffer = malloc(bufferSize);
|
||||
read = unzReadCurrentFile(zip, buffer, bufferSize);
|
||||
if (read > 0) {
|
||||
memcpy((char*)buff + total, buffer, read);
|
||||
total += read;
|
||||
}
|
||||
free(buffer);
|
||||
} while (read > 0);
|
||||
size_t filesize = fileInfo.uncompressed_size;
|
||||
if ( ret < 0 || size_t(ret) != filesize )
|
||||
if (total == 0 || size_t(total) != filesize)
|
||||
{
|
||||
delete[] buff;
|
||||
ThrowException("Failed to decompress IFC ZIP file");
|
||||
|
|
|
@ -118,7 +118,7 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
|
|||
size_t lastFilePos( 0 );
|
||||
|
||||
std::vector<char> buffer;
|
||||
while ( streamBuffer.getNextDataLine( buffer, '\\' ) ) {
|
||||
while ( streamBuffer.getNextDataLine( buffer, '\0' ) ) {
|
||||
m_DataIt = buffer.begin();
|
||||
m_DataItEnd = buffer.end();
|
||||
|
||||
|
|
|
@ -438,13 +438,16 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
|
|||
}
|
||||
}
|
||||
|
||||
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
|
||||
if (!attr.texcoord[tc]) {
|
||||
DefaultLogger::get()->warn("NULL texcoord encountered in mesh \"" + mesh.name +
|
||||
"\" and will be ignored");
|
||||
for (size_t c = 0; c < attr.color.size() && c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) {
|
||||
if (attr.color[c]->count != aim->mNumVertices) {
|
||||
DefaultLogger::get()->warn("Color stream size in mesh \"" + mesh.name +
|
||||
"\" does not match the vertex count");
|
||||
continue;
|
||||
}
|
||||
|
||||
aim->mColors[c] = new aiColor4D[attr.color[c]->count];
|
||||
attr.color[c]->ExtractData(aim->mColors[c]);
|
||||
}
|
||||
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
|
||||
if (attr.texcoord[tc]->count != aim->mNumVertices) {
|
||||
DefaultLogger::get()->warn("Texcoord stream size in mesh \"" + mesh.name +
|
||||
"\" does not match the vertex count");
|
||||
|
|
|
@ -243,7 +243,7 @@ template<class T>
|
|||
inline
|
||||
bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) {
|
||||
buffer.resize( m_cacheSize );
|
||||
if ( m_cachePos == m_cacheSize || 0 == m_filePos ) {
|
||||
if ( m_cachePos >= m_cacheSize || 0 == m_filePos ) {
|
||||
if ( !readNextBlock() ) {
|
||||
return false;
|
||||
}
|
||||
|
@ -273,6 +273,9 @@ bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationT
|
|||
buffer[ i ] = m_cache[ m_cachePos ];
|
||||
++m_cachePos;
|
||||
++i;
|
||||
if (m_cachePos >= size()) {
|
||||
break;
|
||||
}
|
||||
if ( m_cachePos >= m_cacheSize ) {
|
||||
if ( !readNextBlock() ) {
|
||||
return false;
|
||||
|
|
|
@ -402,7 +402,7 @@ enum aiPrimitiveType
|
|||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @brief NOT CURRENTLY IN USE. An AnimMesh is an attachment to an #aiMesh stores per-vertex
|
||||
/** @brief An AnimMesh is an attachment to an #aiMesh stores per-vertex
|
||||
* animations for a particular frame.
|
||||
*
|
||||
* You may think of an #aiAnimMesh as a `patch` for the host mesh, which
|
||||
|
@ -414,6 +414,9 @@ enum aiPrimitiveType
|
|||
*/
|
||||
struct aiAnimMesh
|
||||
{
|
||||
/**Anim Mesh name */
|
||||
C_STRUCT aiString mName;
|
||||
|
||||
/** Replacement for aiMesh::mVertices. If this array is non-NULL,
|
||||
* it *must* contain mNumVertices entries. The corresponding
|
||||
* array in the host mesh must be non-NULL as well - animation
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "jassimp.h"
|
||||
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/ProgressHandler.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/IOStream.hpp>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
|
@ -248,7 +249,7 @@ static bool call(JNIEnv *env, jobject object, const char* typeName, const char*
|
|||
return false;
|
||||
}
|
||||
|
||||
jboolean jReturnValue = env->CallBooleanMethod(object, mid, params[0].l);
|
||||
jboolean jReturnValue = env->CallBooleanMethodA(object, mid, params);
|
||||
|
||||
return (bool)jReturnValue;
|
||||
}
|
||||
|
@ -591,6 +592,24 @@ class JavaIOSystem : public Assimp::IOSystem {
|
|||
|
||||
};
|
||||
|
||||
class JavaProgressHandler : public Assimp::ProgressHandler {
|
||||
private:
|
||||
JNIEnv* mJniEnv;
|
||||
jobject& mJavaProgressHandler;
|
||||
|
||||
public:
|
||||
JavaProgressHandler(JNIEnv* env, jobject& javaProgressHandler) :
|
||||
mJniEnv(env),
|
||||
mJavaProgressHandler(javaProgressHandler)
|
||||
{};
|
||||
|
||||
bool Update(float percentage)
|
||||
{
|
||||
jvalue params[1];
|
||||
params[0].f = percentage;
|
||||
return call(mJniEnv, mJavaProgressHandler, "jassimp/AiProgressHandler", "update", "(F)Z", params);
|
||||
}
|
||||
};
|
||||
|
||||
static bool loadMeshes(JNIEnv *env, const aiScene* cScene, jobject& jScene)
|
||||
{
|
||||
|
@ -1880,7 +1899,7 @@ JNIEXPORT jstring JNICALL Java_jassimp_Jassimp_getErrorString
|
|||
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_jassimp_Jassimp_aiImportFile
|
||||
(JNIEnv *env, jclass jClazz, jstring jFilename, jlong postProcess, jobject ioSystem)
|
||||
(JNIEnv *env, jclass jClazz, jstring jFilename, jlong postProcess, jobject ioSystem, jobject progressHandler)
|
||||
{
|
||||
jobject jScene = NULL;
|
||||
|
||||
|
@ -1896,6 +1915,11 @@ JNIEXPORT jobject JNICALL Java_jassimp_Jassimp_aiImportFile
|
|||
lprintf("Created aiFileIO\n");
|
||||
}
|
||||
|
||||
if(progressHandler != NULL)
|
||||
{
|
||||
imp.SetProgressHandler(new JavaProgressHandler(env, progressHandler));
|
||||
}
|
||||
|
||||
lprintf("opening file: %s\n", cFilename);
|
||||
|
||||
/* do import */
|
||||
|
|
|
@ -39,7 +39,7 @@ JNIEXPORT jstring JNICALL Java_jassimp_Jassimp_getErrorString
|
|||
* Signature: (Ljava/lang/String;J)Ljassimp/AiScene;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_jassimp_Jassimp_aiImportFile
|
||||
(JNIEnv *, jclass, jstring, jlong, jobject);
|
||||
(JNIEnv *, jclass, jstring, jlong, jobject, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -457,7 +457,7 @@ public final class AiMaterial {
|
|||
*
|
||||
* @return the data
|
||||
*/
|
||||
private Object getData() {
|
||||
public Object getData() {
|
||||
return m_data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library - Java Binding (jassimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2012, 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.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
package jassimp;
|
||||
|
||||
public interface AiProgressHandler
|
||||
{
|
||||
boolean update(float percentage);
|
||||
}
|
|
@ -47,11 +47,6 @@ import java.util.Set;
|
|||
* Status flags for {@link AiScene}s.
|
||||
*/
|
||||
public enum AiSceneFlag {
|
||||
/**
|
||||
* The mapped c/c++ integer enum value.
|
||||
*/
|
||||
private final int m_rawValue;
|
||||
|
||||
/**
|
||||
* Specifies that the scene data structure that was imported is not
|
||||
* complete.<p>
|
||||
|
@ -119,8 +114,12 @@ public enum AiSceneFlag {
|
|||
* you actually need to render it).
|
||||
*/
|
||||
TERRAIN(0x10);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The mapped c/c++ integer enum value.
|
||||
*/
|
||||
private final int m_rawValue;
|
||||
|
||||
/**
|
||||
* Utility method for converting from c/c++ based integer enums to java
|
||||
* enums.<p>
|
||||
|
|
|
@ -68,8 +68,9 @@ public final class Jassimp {
|
|||
* @return the loaded scene, or null if an error occurred
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
private static native AiScene aiImportFile(String filename,
|
||||
long postProcessing, AiIOSystem<?> ioSystem) throws IOException;
|
||||
private static native AiScene aiImportFile(String filename,
|
||||
long postProcessing, AiIOSystem<?> ioSystem,
|
||||
AiProgressHandler progressHandler) throws IOException;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -158,11 +159,26 @@ public final class Jassimp {
|
|||
public static AiScene importFile(String filename,
|
||||
Set<AiPostProcessSteps> postProcessing, AiIOSystem<?> ioSystem)
|
||||
throws IOException {
|
||||
|
||||
loadLibrary();
|
||||
|
||||
return importFile(filename, postProcessing, ioSystem, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a file via assimp.
|
||||
*
|
||||
* @param filename the file to import
|
||||
* @param postProcessing post processing flags
|
||||
* @param ioSystem ioSystem to load files, or null for default
|
||||
* @return the loaded scene, or null if an error occurred
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
public static AiScene importFile(String filename,
|
||||
Set<AiPostProcessSteps> postProcessing, AiIOSystem<?> ioSystem,
|
||||
AiProgressHandler progressHandler) throws IOException {
|
||||
|
||||
loadLibrary();
|
||||
|
||||
return aiImportFile(filename, AiPostProcessSteps.toRawValue(
|
||||
postProcessing), ioSystem);
|
||||
postProcessing), ioSystem, progressHandler);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue