Merge branch 'master' into export_3mf
commit
9ca7b00280
15
.travis.sh
15
.travis.sh
|
@ -43,9 +43,24 @@ if [ $ANDROID ]; then
|
||||||
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
|
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
|
||||||
fi
|
fi
|
||||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||||
|
if [ $ANALYZE = "ON" ] ; then
|
||||||
|
if [ "$CC" = "clang" ]; then
|
||||||
|
scan-build cmake -G "Unix Makefiles" -DBUILD_SHARED_LIBS=OFF -DASSIMP_BUILD_TESTS=OFF
|
||||||
|
scan-build --status-bugs make -j2
|
||||||
|
else
|
||||||
|
cppcheck --version
|
||||||
|
generate \
|
||||||
|
&& cppcheck --error-exitcode=1 -j2 -Iinclude -Icode code 2> cppcheck.txt
|
||||||
|
if [ -s cppcheck.txt ]; then
|
||||||
|
cat cppcheck.txt
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
generate \
|
generate \
|
||||||
&& make -j4 \
|
&& make -j4 \
|
||||||
&& sudo make install \
|
&& sudo make install \
|
||||||
&& sudo ldconfig \
|
&& sudo ldconfig \
|
||||||
&& (cd test/unit; ../../bin/unit)
|
&& (cd test/unit; ../../bin/unit)
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
18
.travis.yml
18
.travis.yml
|
@ -4,7 +4,7 @@ language: cpp
|
||||||
cache: ccache
|
cache: ccache
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq && sudo apt-get install cmake && sudo apt-get install cmake python3 && sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- ; fi
|
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq && sudo apt-get install cmake cppcheck && sudo apt-get install cmake python3 && sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- ; fi
|
||||||
- 'if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
- 'if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||||
if brew ls --versions cmake > /dev/null; then
|
if brew ls --versions cmake > /dev/null; then
|
||||||
echo cmake already installed.;
|
echo cmake already installed.;
|
||||||
|
@ -34,11 +34,8 @@ env:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: linux
|
- os: linux
|
||||||
compiler: gcc
|
compiler: clang
|
||||||
env: DISABLE_EXPORTERS=YES ENABLE_COVERALLS=ON
|
env: ANALYZE=ON
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env: SHARED_BUILD=ON
|
|
||||||
- os: linux
|
- os: linux
|
||||||
compiler: clang
|
compiler: clang
|
||||||
env: ASAN=ON
|
env: ASAN=ON
|
||||||
|
@ -48,6 +45,15 @@ matrix:
|
||||||
- os: linux
|
- os: linux
|
||||||
compiler: clang
|
compiler: clang
|
||||||
env: SHARED_BUILD=ON
|
env: SHARED_BUILD=ON
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
env: ANALYZE=ON
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
env: DISABLE_EXPORTERS=YES ENABLE_COVERALLS=ON
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
env: SHARED_BUILD=ON
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
|
- if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
|
||||||
|
|
|
@ -183,8 +183,11 @@ SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
|
||||||
|
|
||||||
IF( UNIX )
|
IF( UNIX )
|
||||||
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
|
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
|
||||||
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
|
IF( ${OPERATING_SYSTEM} MATCHES "Android")
|
||||||
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
|
ELSE()
|
||||||
|
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
|
||||||
|
#ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
|
||||||
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# Use GNUInstallDirs for Unix predefined directories
|
# Use GNUInstallDirs for Unix predefined directories
|
||||||
|
|
|
@ -310,7 +310,7 @@ foreach (GCOV_FILE ${GCOV_FILES})
|
||||||
message("MD5: ${GCOV_SRC_PATH} = ${GCOV_CONTENTS_MD5}")
|
message("MD5: ${GCOV_SRC_PATH} = ${GCOV_CONTENTS_MD5}")
|
||||||
|
|
||||||
# Loads the gcov file as a list of lines.
|
# Loads the gcov file as a list of lines.
|
||||||
# (We first open the file and replace all occurences of [] with _
|
# (We first open the file and replace all occurrences of [] with _
|
||||||
# because CMake will fail to parse a line containing unmatched brackets...
|
# because CMake will fail to parse a line containing unmatched brackets...
|
||||||
# also the \ to escaped \n in macros screws up things.)
|
# also the \ to escaped \n in macros screws up things.)
|
||||||
# https://public.kitware.com/Bug/view.php?id=15369
|
# https://public.kitware.com/Bug/view.php?id=15369
|
||||||
|
@ -329,7 +329,7 @@ foreach (GCOV_FILE ${GCOV_FILES})
|
||||||
# Instead of trying to parse the source from the
|
# Instead of trying to parse the source from the
|
||||||
# gcov file, simply read the file contents from the source file.
|
# gcov file, simply read the file contents from the source file.
|
||||||
# (Parsing it from the gcov is hard because C-code uses ; in many places
|
# (Parsing it from the gcov is hard because C-code uses ; in many places
|
||||||
# which also happens to be the same as the CMake list delimeter).
|
# which also happens to be the same as the CMake list delimiter).
|
||||||
file(READ ${GCOV_SRC_PATH} GCOV_FILE_SOURCE)
|
file(READ ${GCOV_SRC_PATH} GCOV_FILE_SOURCE)
|
||||||
|
|
||||||
string(REPLACE "\\" "\\\\" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
|
string(REPLACE "\\" "\\\\" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
|
||||||
|
|
|
@ -249,7 +249,7 @@ private:
|
||||||
|
|
||||||
/// \fn size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A)
|
/// \fn size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A)
|
||||||
/// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new
|
/// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new
|
||||||
/// converted texture will be returned. Convertion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
|
/// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
|
||||||
/// to converted textures list.
|
/// to converted textures list.
|
||||||
/// Any of source ID's can be absent(empty string) or even one ID only specified. But at least one ID must be specified.
|
/// Any of source ID's can be absent(empty string) or even one ID only specified. But at least one ID must be specified.
|
||||||
/// \param [in] pID_R - ID of source "red" texture.
|
/// \param [in] pID_R - ID of source "red" texture.
|
||||||
|
@ -378,7 +378,7 @@ private:
|
||||||
void XML_CheckNode_MustHaveChildren();
|
void XML_CheckNode_MustHaveChildren();
|
||||||
|
|
||||||
/// \fn bool XML_CheckNode_NameEqual(const std::string& pNodeName)
|
/// \fn bool XML_CheckNode_NameEqual(const std::string& pNodeName)
|
||||||
/// Chek if current node name is equal to pNodeName.
|
/// Check if current node name is equal to pNodeName.
|
||||||
/// \param [in] pNodeName - name for checking.
|
/// \param [in] pNodeName - name for checking.
|
||||||
/// return true if current node name is equal to pNodeName, else - false.
|
/// return true if current node name is equal to pNodeName, else - false.
|
||||||
bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
|
bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
|
||||||
|
|
|
@ -137,7 +137,7 @@ struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement
|
||||||
{
|
{
|
||||||
/****************** Variables ******************/
|
/****************** Variables ******************/
|
||||||
|
|
||||||
std::string ObjectID;///< ID of object for instanciation.
|
std::string ObjectID;///< ID of object for instantiation.
|
||||||
/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
|
/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
|
||||||
/// create an instance of the object in the current constellation.
|
/// create an instance of the object in the current constellation.
|
||||||
aiVector3D Delta;
|
aiVector3D Delta;
|
||||||
|
|
|
@ -281,8 +281,11 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string&
|
||||||
{
|
{
|
||||||
if(!pID.empty())
|
if(!pID.empty())
|
||||||
{
|
{
|
||||||
for(size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++)
|
for(size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++) {
|
||||||
converted_texture.Data[idx_target] = src_texture[pSrcTexNum]->Data.at(idx_src);
|
CAMFImporter_NodeElement_Texture* tex = src_texture[pSrcTexNum];
|
||||||
|
ai_assert(tex);
|
||||||
|
converted_texture.Data[idx_target] = tex->Data.at(idx_src);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};// auto CopyTextureData = [&](const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void
|
};// auto CopyTextureData = [&](const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void
|
||||||
|
|
||||||
|
|
|
@ -1021,6 +1021,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
|
||||||
|
|
||||||
// convert bones, if existing
|
// convert bones, if existing
|
||||||
if (!mesh.mBones.empty()) {
|
if (!mesh.mBones.empty()) {
|
||||||
|
ai_assert(avOutputBones);
|
||||||
// check whether there is a vertex weight for this vertex index
|
// check whether there is a vertex weight for this vertex index
|
||||||
if (iIndex2 < mesh.mBoneVertices.size()) {
|
if (iIndex2 < mesh.mBoneVertices.size()) {
|
||||||
|
|
||||||
|
|
|
@ -171,6 +171,7 @@ inline size_t Write<aiQuaternion>(IOStream * stream, const aiQuaternion& v)
|
||||||
t += Write<float>(stream,v.x);
|
t += Write<float>(stream,v.x);
|
||||||
t += Write<float>(stream,v.y);
|
t += Write<float>(stream,v.y);
|
||||||
t += Write<float>(stream,v.z);
|
t += Write<float>(stream,v.z);
|
||||||
|
ai_assert(t == 16);
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ namespace Assimp {
|
||||||
offset += Copy(&data[offset], header.size);
|
offset += Copy(&data[offset], header.size);
|
||||||
offset += Copy(&data[offset], header.reserved1);
|
offset += Copy(&data[offset], header.reserved1);
|
||||||
offset += Copy(&data[offset], header.reserved2);
|
offset += Copy(&data[offset], header.reserved2);
|
||||||
offset += Copy(&data[offset], header.offset);
|
Copy(&data[offset], header.offset);
|
||||||
|
|
||||||
file->Write(data, Header::header_size, 1);
|
file->Write(data, Header::header_size, 1);
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ namespace Assimp {
|
||||||
offset += Copy(&data[offset], dib.x_resolution);
|
offset += Copy(&data[offset], dib.x_resolution);
|
||||||
offset += Copy(&data[offset], dib.y_resolution);
|
offset += Copy(&data[offset], dib.y_resolution);
|
||||||
offset += Copy(&data[offset], dib.nb_colors);
|
offset += Copy(&data[offset], dib.nb_colors);
|
||||||
offset += Copy(&data[offset], dib.nb_important_colors);
|
Copy(&data[offset], dib.nb_important_colors);
|
||||||
|
|
||||||
file->Write(data, DIB::dib_size, 1);
|
file->Write(data, DIB::dib_size, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,12 @@ struct Error : DeadlyImportError {
|
||||||
* descendents. It serves as base class for all data structure fields. */
|
* descendents. It serves as base class for all data structure fields. */
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct ElemBase {
|
struct ElemBase {
|
||||||
|
ElemBase()
|
||||||
|
: dna_type(nullptr)
|
||||||
|
{
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~ElemBase() {
|
virtual ~ElemBase() {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,9 @@ template <> void Structure :: Convert<Object> (
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
|
int temp = 0;
|
||||||
|
ReadField<ErrorPolicy_Fail>(temp,"type",db);
|
||||||
|
dest.type = static_cast<Assimp::Blender::Object::Type>(temp);
|
||||||
ReadFieldArray2<ErrorPolicy_Warn>(dest.obmat,"obmat",db);
|
ReadFieldArray2<ErrorPolicy_Warn>(dest.obmat,"obmat",db);
|
||||||
ReadFieldArray2<ErrorPolicy_Warn>(dest.parentinv,"parentinv",db);
|
ReadFieldArray2<ErrorPolicy_Warn>(dest.parentinv,"parentinv",db);
|
||||||
ReadFieldArray<ErrorPolicy_Warn>(dest.parsubstr,"parsubstr",db);
|
ReadFieldArray<ErrorPolicy_Warn>(dest.parsubstr,"parsubstr",db);
|
||||||
|
@ -100,14 +102,21 @@ template <> void Structure :: Convert<MTex> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>((short&)dest.mapto,"mapto",db);
|
int temp_short = 0;
|
||||||
ReadField<ErrorPolicy_Igno>((int&)dest.blendtype,"blendtype",db);
|
ReadField<ErrorPolicy_Igno>(temp_short,"mapto",db);
|
||||||
|
dest.mapto = static_cast<Assimp::Blender::MTex::MapType>(temp_short);
|
||||||
|
int temp = 0;
|
||||||
|
ReadField<ErrorPolicy_Igno>(temp,"blendtype",db);
|
||||||
|
dest.blendtype = static_cast<Assimp::Blender::MTex::BlendType>(temp);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.object,"*object",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.object,"*object",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.tex,"*tex",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.tex,"*tex",db);
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.uvname,"uvname",db);
|
ReadFieldArray<ErrorPolicy_Igno>(dest.uvname,"uvname",db);
|
||||||
ReadField<ErrorPolicy_Igno>((int&)dest.projx,"projx",db);
|
ReadField<ErrorPolicy_Igno>(temp,"projx",db);
|
||||||
ReadField<ErrorPolicy_Igno>((int&)dest.projy,"projy",db);
|
dest.projx = static_cast<Assimp::Blender::MTex::Projection>(temp);
|
||||||
ReadField<ErrorPolicy_Igno>((int&)dest.projz,"projz",db);
|
ReadField<ErrorPolicy_Igno>(temp,"projy",db);
|
||||||
|
dest.projy = static_cast<Assimp::Blender::MTex::Projection>(temp);
|
||||||
|
ReadField<ErrorPolicy_Igno>(temp,"projz",db);
|
||||||
|
dest.projx = static_cast<Assimp::Blender::MTex::Projection>(temp);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mapping,"mapping",db);
|
ReadField<ErrorPolicy_Igno>(dest.mapping,"mapping",db);
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.ofs,"ofs",db);
|
ReadFieldArray<ErrorPolicy_Igno>(dest.ofs,"ofs",db);
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.size,"size",db);
|
ReadFieldArray<ErrorPolicy_Igno>(dest.size,"size",db);
|
||||||
|
@ -190,7 +199,9 @@ template <> void Structure :: Convert<Lamp> (
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
|
int temp = 0;
|
||||||
|
ReadField<ErrorPolicy_Fail>(temp,"type",db);
|
||||||
|
dest.type = static_cast<Assimp::Blender::Lamp::Type>(temp);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
|
ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
|
ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db);
|
ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db);
|
||||||
|
@ -204,7 +215,8 @@ template <> void Structure :: Convert<Lamp> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.spotblend,"spotblend",db);
|
ReadField<ErrorPolicy_Igno>(dest.spotblend,"spotblend",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.att1,"att1",db);
|
ReadField<ErrorPolicy_Igno>(dest.att1,"att1",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
|
ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
|
||||||
ReadField<ErrorPolicy_Igno>((int&)dest.falloff_type,"falloff_type",db);
|
ReadField<ErrorPolicy_Igno>(temp,"falloff_type",db);
|
||||||
|
dest.falloff_type = static_cast<Assimp::Blender::Lamp::FalloffType>(temp);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
|
ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.area_size,"area_size",db);
|
ReadField<ErrorPolicy_Igno>(dest.area_size,"area_size",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.area_sizey,"area_sizey",db);
|
ReadField<ErrorPolicy_Igno>(dest.area_sizey,"area_sizey",db);
|
||||||
|
@ -693,8 +705,12 @@ template <> void Structure :: Convert<Tex> (
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
ReadField<ErrorPolicy_Igno>((short&)dest.imaflag,"imaflag",db);
|
short temp_short = 0;
|
||||||
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
|
ReadField<ErrorPolicy_Igno>(temp_short,"imaflag",db);
|
||||||
|
dest.imaflag = static_cast<Assimp::Blender::Tex::ImageFlags>(temp_short);
|
||||||
|
int temp = 0;
|
||||||
|
ReadField<ErrorPolicy_Fail>(temp,"type",db);
|
||||||
|
dest.type = static_cast<Assimp::Blender::Tex::Type>(temp);
|
||||||
ReadFieldPtr<ErrorPolicy_Warn>(dest.ima,"*ima",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.ima,"*ima",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
|
@ -708,8 +724,11 @@ template <> void Structure :: Convert<Camera> (
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadField<ErrorPolicy_Warn>((int&)dest.type,"type",db);
|
int temp = 0;
|
||||||
ReadField<ErrorPolicy_Warn>((int&)dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Warn>(temp,"type",db);
|
||||||
|
dest.type = static_cast<Assimp::Blender::Camera::Type>(temp);
|
||||||
|
ReadField<ErrorPolicy_Warn>(temp,"flag",db);
|
||||||
|
dest.flag = static_cast<Assimp::Blender::Camera::Type>(temp);
|
||||||
ReadField<ErrorPolicy_Warn>(dest.lens,"lens",db);
|
ReadField<ErrorPolicy_Warn>(dest.lens,"lens",db);
|
||||||
ReadField<ErrorPolicy_Warn>(dest.sensor_x,"sensor_x",db);
|
ReadField<ErrorPolicy_Warn>(dest.sensor_x,"sensor_x",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.clipsta,"clipsta",db);
|
ReadField<ErrorPolicy_Igno>(dest.clipsta,"clipsta",db);
|
||||||
|
|
|
@ -225,6 +225,14 @@ struct TFace : ElemBase {
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MTFace : ElemBase {
|
struct MTFace : ElemBase {
|
||||||
|
MTFace()
|
||||||
|
: flag(0)
|
||||||
|
, mode(0)
|
||||||
|
, tile(0)
|
||||||
|
, unwrap(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
float uv[4][2] FAIL;
|
float uv[4][2] FAIL;
|
||||||
char flag;
|
char flag;
|
||||||
short mode;
|
short mode;
|
||||||
|
|
|
@ -141,6 +141,9 @@ void ColladaExporter::WriteFile()
|
||||||
WriteControllerLibrary();
|
WriteControllerLibrary();
|
||||||
|
|
||||||
WriteSceneLibrary();
|
WriteSceneLibrary();
|
||||||
|
|
||||||
|
// customized, Writes the animation library
|
||||||
|
WriteAnimationsLibrary();
|
||||||
|
|
||||||
// useless Collada fu at the end, just in case we haven't had enough indirections, yet.
|
// useless Collada fu at the end, just in case we haven't had enough indirections, yet.
|
||||||
mOutput << startstr << "<scene>" << endstr;
|
mOutput << startstr << "<scene>" << endstr;
|
||||||
|
@ -1129,6 +1132,7 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
|
||||||
case FloatType_Color: floatsPerElement = 3; break;
|
case FloatType_Color: floatsPerElement = 3; break;
|
||||||
case FloatType_Mat4x4: floatsPerElement = 16; break;
|
case FloatType_Mat4x4: floatsPerElement = 16; break;
|
||||||
case FloatType_Weight: floatsPerElement = 1; break;
|
case FloatType_Weight: floatsPerElement = 1; break;
|
||||||
|
case FloatType_Time: floatsPerElement = 1; break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1205,7 +1209,13 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
|
||||||
case FloatType_Weight:
|
case FloatType_Weight:
|
||||||
mOutput << startstr << "<param name=\"WEIGHT\" type=\"float\" />" << endstr;
|
mOutput << startstr << "<param name=\"WEIGHT\" type=\"float\" />" << endstr;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
// customized, add animation related
|
||||||
|
case FloatType_Time:
|
||||||
|
mOutput << startstr << "<param name=\"TIME\" type=\"float\" />" << endstr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</accessor>" << endstr;
|
mOutput << startstr << "</accessor>" << endstr;
|
||||||
|
@ -1235,7 +1245,172 @@ void ColladaExporter::WriteSceneLibrary()
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</library_visual_scenes>" << endstr;
|
mOutput << startstr << "</library_visual_scenes>" << endstr;
|
||||||
}
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
|
||||||
|
{
|
||||||
|
const aiAnimation * anim = mScene->mAnimations[pIndex];
|
||||||
|
|
||||||
|
if ( anim->mNumChannels == 0 && anim->mNumMeshChannels == 0 && anim->mNumMorphMeshChannels ==0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
const std::string animation_name_escaped = XMLEscape( anim->mName.C_Str() );
|
||||||
|
std::string idstr = anim->mName.C_Str();
|
||||||
|
std::string ending = std::string( "AnimId" ) + to_string(pIndex);
|
||||||
|
if (idstr.length() >= ending.length()) {
|
||||||
|
if (0 != idstr.compare (idstr.length() - ending.length(), ending.length(), ending)) {
|
||||||
|
idstr = idstr + ending;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
idstr = idstr + ending;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string idstrEscaped = XMLEscape(idstr);
|
||||||
|
|
||||||
|
mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr;
|
||||||
|
PushTag();
|
||||||
|
|
||||||
|
for (size_t a = 0; a < anim->mNumChannels; ++a) {
|
||||||
|
const aiNodeAnim * nodeAnim = anim->mChannels[a];
|
||||||
|
|
||||||
|
// sanity check
|
||||||
|
if ( nodeAnim->mNumPositionKeys != nodeAnim->mNumScalingKeys || nodeAnim->mNumPositionKeys != nodeAnim->mNumRotationKeys ) continue;
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-input");
|
||||||
|
|
||||||
|
std::vector<ai_real> frames;
|
||||||
|
for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
|
||||||
|
frames.push_back(nodeAnim->mPositionKeys[i].mTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteFloatArray( node_idstr , FloatType_Time, (const ai_real*) frames.data(), frames.size());
|
||||||
|
frames.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-output");
|
||||||
|
|
||||||
|
std::vector<ai_real> keyframes;
|
||||||
|
keyframes.reserve(nodeAnim->mNumPositionKeys * 16);
|
||||||
|
for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
|
||||||
|
|
||||||
|
aiVector3D Scaling = nodeAnim->mScalingKeys[i].mValue;
|
||||||
|
aiMatrix4x4 ScalingM; // identity
|
||||||
|
ScalingM[0][0] = Scaling.x; ScalingM[1][1] = Scaling.y; ScalingM[2][2] = Scaling.z;
|
||||||
|
|
||||||
|
aiQuaternion RotationQ = nodeAnim->mRotationKeys[i].mValue;
|
||||||
|
aiMatrix4x4 s = aiMatrix4x4( RotationQ.GetMatrix() );
|
||||||
|
aiMatrix4x4 RotationM(s.a1, s.a2, s.a3, 0, s.b1, s.b2, s.b3, 0, s.c1, s.c2, s.c3, 0, 0, 0, 0, 1);
|
||||||
|
|
||||||
|
aiVector3D Translation = nodeAnim->mPositionKeys[i].mValue;
|
||||||
|
aiMatrix4x4 TranslationM; // identity
|
||||||
|
TranslationM[0][3] = Translation.x; TranslationM[1][3] = Translation.y; TranslationM[2][3] = Translation.z;
|
||||||
|
|
||||||
|
// Combine the above transformations
|
||||||
|
aiMatrix4x4 mat = TranslationM * RotationM * ScalingM;
|
||||||
|
|
||||||
|
for( size_t j = 0; j < 4; ++j) {
|
||||||
|
keyframes.insert(keyframes.end(), mat[j], mat[j] + 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteFloatArray( node_idstr, FloatType_Mat4x4, (const ai_real*) keyframes.data(), keyframes.size() / 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::vector<std::string> names;
|
||||||
|
for ( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
|
||||||
|
if ( nodeAnim->mPreState == aiAnimBehaviour_DEFAULT
|
||||||
|
|| nodeAnim->mPreState == aiAnimBehaviour_LINEAR
|
||||||
|
|| nodeAnim->mPreState == aiAnimBehaviour_REPEAT
|
||||||
|
) {
|
||||||
|
names.push_back( "LINEAR" );
|
||||||
|
} else if (nodeAnim->mPostState == aiAnimBehaviour_CONSTANT) {
|
||||||
|
names.push_back( "STEP" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-interpolation");
|
||||||
|
std::string arrayId = node_idstr + "-array";
|
||||||
|
|
||||||
|
mOutput << startstr << "<source id=\"" << XMLEscape(node_idstr) << "\">" << endstr;
|
||||||
|
PushTag();
|
||||||
|
|
||||||
|
// source array
|
||||||
|
mOutput << startstr << "<Name_array id=\"" << XMLEscape(arrayId) << "\" count=\"" << names.size() << "\"> ";
|
||||||
|
for( size_t a = 0; a < names.size(); ++a ) {
|
||||||
|
mOutput << names[a] << " ";
|
||||||
|
}
|
||||||
|
mOutput << "</Name_array>" << endstr;
|
||||||
|
|
||||||
|
mOutput << startstr << "<technique_common>" << endstr;
|
||||||
|
PushTag();
|
||||||
|
|
||||||
|
mOutput << startstr << "<accessor source=\"#" << XMLEscape(arrayId) << "\" count=\"" << names.size() << "\" stride=\"" << 1 << "\">" << endstr;
|
||||||
|
PushTag();
|
||||||
|
|
||||||
|
mOutput << startstr << "<param name=\"INTERPOLATION\" type=\"name\"></param>" << endstr;
|
||||||
|
|
||||||
|
PopTag();
|
||||||
|
mOutput << startstr << "</accessor>" << endstr;
|
||||||
|
|
||||||
|
PopTag();
|
||||||
|
mOutput << startstr << "</technique_common>" << endstr;
|
||||||
|
|
||||||
|
PopTag();
|
||||||
|
mOutput << startstr << "</source>" << endstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t a = 0; a < anim->mNumChannels; ++a) {
|
||||||
|
const aiNodeAnim * nodeAnim = anim->mChannels[a];
|
||||||
|
|
||||||
|
{
|
||||||
|
// samplers
|
||||||
|
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-sampler");
|
||||||
|
mOutput << startstr << "<sampler id=\"" << XMLEscape(node_idstr) << "\">" << endstr;
|
||||||
|
PushTag();
|
||||||
|
|
||||||
|
mOutput << startstr << "<input semantic=\"INPUT\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-input") ) << "\"/>" << endstr;
|
||||||
|
mOutput << startstr << "<input semantic=\"OUTPUT\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-output") ) << "\"/>" << endstr;
|
||||||
|
mOutput << startstr << "<input semantic=\"INTERPOLATION\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-interpolation") ) << "\"/>" << endstr;
|
||||||
|
|
||||||
|
PopTag();
|
||||||
|
mOutput << startstr << "</sampler>" << endstr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t a = 0; a < anim->mNumChannels; ++a) {
|
||||||
|
const aiNodeAnim * nodeAnim = anim->mChannels[a];
|
||||||
|
|
||||||
|
{
|
||||||
|
// channels
|
||||||
|
mOutput << startstr << "<channel source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-sampler") ) << "\" target=\"" << XMLEscape(nodeAnim->mNodeName.data) << "/matrix\"/>" << endstr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PopTag();
|
||||||
|
mOutput << startstr << "</animation>" << endstr;
|
||||||
|
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ColladaExporter::WriteAnimationsLibrary()
|
||||||
|
{
|
||||||
|
const std::string scene_name_escaped = XMLEscape(mScene->mRootNode->mName.C_Str());
|
||||||
|
|
||||||
|
if ( mScene->mNumAnimations > 0 ) {
|
||||||
|
mOutput << startstr << "<library_animations>" << endstr;
|
||||||
|
PushTag();
|
||||||
|
|
||||||
|
// start recursive write at the root node
|
||||||
|
for( size_t a = 0; a < mScene->mNumAnimations; ++a)
|
||||||
|
WriteAnimationLibrary( a );
|
||||||
|
|
||||||
|
PopTag();
|
||||||
|
mOutput << startstr << "</library_animations>" << endstr;
|
||||||
|
}
|
||||||
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Helper to find a bone by name in the scene
|
// Helper to find a bone by name in the scene
|
||||||
aiBone* findBone( const aiScene* scene, const char * name) {
|
aiBone* findBone( const aiScene* scene, const char * name) {
|
||||||
|
@ -1251,6 +1426,59 @@ aiBone* findBone( const aiScene* scene, const char * name) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
const aiNode * findBoneNode( const aiNode* aNode, const aiBone* bone)
|
||||||
|
{
|
||||||
|
if ( aNode && bone && aNode->mName == bone->mName ) {
|
||||||
|
return aNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( aNode && bone ) {
|
||||||
|
for (unsigned int i=0; i < aNode->mNumChildren; ++i) {
|
||||||
|
aiNode * aChild = aNode->mChildren[i];
|
||||||
|
const aiNode * foundFromChild = 0;
|
||||||
|
if ( aChild ) {
|
||||||
|
foundFromChild = findBoneNode( aChild, bone );
|
||||||
|
if ( foundFromChild ) return foundFromChild;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const aiNode * findSkeletonRootNode( const aiScene* scene, const aiMesh * mesh)
|
||||||
|
{
|
||||||
|
std::set<const aiNode*> topParentBoneNodes;
|
||||||
|
if ( mesh && mesh->mNumBones > 0 ) {
|
||||||
|
for (unsigned int i=0; i < mesh->mNumBones; ++i) {
|
||||||
|
aiBone * bone = mesh->mBones[i];
|
||||||
|
|
||||||
|
const aiNode * node = findBoneNode( scene->mRootNode, bone);
|
||||||
|
if ( node ) {
|
||||||
|
while ( node->mParent && findBone(scene, node->mParent->mName.C_Str() ) != 0 ) {
|
||||||
|
node = node->mParent;
|
||||||
|
}
|
||||||
|
topParentBoneNodes.insert( node );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !topParentBoneNodes.empty() ) {
|
||||||
|
const aiNode * parentBoneNode = *topParentBoneNodes.begin();
|
||||||
|
if ( topParentBoneNodes.size() == 1 ) {
|
||||||
|
return parentBoneNode;
|
||||||
|
} else {
|
||||||
|
for (auto it : topParentBoneNodes) {
|
||||||
|
if ( it->mParent ) return it->mParent;
|
||||||
|
}
|
||||||
|
return parentBoneNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Recursively writes the given node
|
// Recursively writes the given node
|
||||||
void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
||||||
|
@ -1278,12 +1506,22 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string node_name_escaped = XMLEscape(pNode->mName.data);
|
const std::string node_name_escaped = XMLEscape(pNode->mName.data);
|
||||||
|
/* // customized, Note! the id field is crucial for inter-xml look up, it cannot be replaced with sid ?!
|
||||||
mOutput << startstr
|
mOutput << startstr
|
||||||
<< "<node ";
|
<< "<node ";
|
||||||
if(is_skeleton_root)
|
if(is_skeleton_root)
|
||||||
mOutput << "id=\"" << "skeleton_root" << "\" "; // For now, only support one skeleton in a scene.
|
mOutput << "id=\"" << "skeleton_root" << "\" "; // For now, only support one skeleton in a scene.
|
||||||
mOutput << (is_joint ? "s" : "") << "id=\"" << node_name_escaped;
|
mOutput << (is_joint ? "s" : "") << "id=\"" << node_name_escaped;
|
||||||
mOutput << "\" name=\"" << node_name_escaped
|
*/
|
||||||
|
mOutput << startstr << "<node ";
|
||||||
|
if(is_skeleton_root) {
|
||||||
|
mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"" : "") ; // For now, only support one skeleton in a scene.
|
||||||
|
mFoundSkeletonRootNodeID = node_name_escaped;
|
||||||
|
} else {
|
||||||
|
mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"": "") ;
|
||||||
|
}
|
||||||
|
|
||||||
|
mOutput << " name=\"" << node_name_escaped
|
||||||
<< "\" type=\"" << node_type
|
<< "\" type=\"" << node_type
|
||||||
<< "\">" << endstr;
|
<< "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
@ -1291,7 +1529,11 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
||||||
// write transformation - we can directly put the matrix there
|
// write transformation - we can directly put the matrix there
|
||||||
// TODO: (thom) decompose into scale - rot - quad to allow addressing it by animations afterwards
|
// TODO: (thom) decompose into scale - rot - quad to allow addressing it by animations afterwards
|
||||||
const aiMatrix4x4& mat = pNode->mTransformation;
|
const aiMatrix4x4& mat = pNode->mTransformation;
|
||||||
mOutput << startstr << "<matrix sid=\"transform\">";
|
|
||||||
|
// customized, sid should be 'matrix' to match with loader code.
|
||||||
|
//mOutput << startstr << "<matrix sid=\"transform\">";
|
||||||
|
mOutput << startstr << "<matrix sid=\"matrix\">";
|
||||||
|
|
||||||
mOutput << mat.a1 << " " << mat.a2 << " " << mat.a3 << " " << mat.a4 << " ";
|
mOutput << mat.a1 << " " << mat.a2 << " " << mat.a3 << " " << mat.a4 << " ";
|
||||||
mOutput << mat.b1 << " " << mat.b2 << " " << mat.b3 << " " << mat.b4 << " ";
|
mOutput << mat.b1 << " " << mat.b2 << " " << mat.b3 << " " << mat.b4 << " ";
|
||||||
mOutput << mat.c1 << " " << mat.c2 << " " << mat.c3 << " " << mat.c4 << " ";
|
mOutput << mat.c1 << " " << mat.c2 << " " << mat.c3 << " " << mat.c4 << " ";
|
||||||
|
@ -1319,7 +1561,7 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
||||||
for( size_t a = 0; a < pNode->mNumMeshes; ++a )
|
for( size_t a = 0; a < pNode->mNumMeshes; ++a )
|
||||||
{
|
{
|
||||||
const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]];
|
const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]];
|
||||||
// do not instanciate mesh if empty. I wonder how this could happen
|
// do not instantiate mesh if empty. I wonder how this could happen
|
||||||
if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
|
if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1335,7 +1577,13 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
||||||
<< endstr;
|
<< endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
mOutput << startstr << "<skeleton>#skeleton_root</skeleton>" << endstr;
|
// note! this mFoundSkeletonRootNodeID some how affects animation, it makes the mesh attaches to armature skeleton root node.
|
||||||
|
// use the first bone to find skeleton root
|
||||||
|
const aiNode * skeletonRootBoneNode = findSkeletonRootNode( pScene, mesh );
|
||||||
|
if ( skeletonRootBoneNode ) {
|
||||||
|
mFoundSkeletonRootNodeID = XMLEscape( skeletonRootBoneNode->mName.C_Str() );
|
||||||
|
}
|
||||||
|
mOutput << startstr << "<skeleton>#" << mFoundSkeletonRootNodeID << "</skeleton>" << endstr;
|
||||||
}
|
}
|
||||||
mOutput << startstr << "<bind_material>" << endstr;
|
mOutput << startstr << "<bind_material>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
|
@ -114,7 +114,9 @@ protected:
|
||||||
/// Writes the given mesh
|
/// Writes the given mesh
|
||||||
void WriteGeometry( size_t pIndex);
|
void WriteGeometry( size_t pIndex);
|
||||||
|
|
||||||
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight };
|
//enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight };
|
||||||
|
// customized to add animation related type
|
||||||
|
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight, FloatType_Time };
|
||||||
|
|
||||||
/// Writes a float array of the given type
|
/// Writes a float array of the given type
|
||||||
void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const ai_real* pData, size_t pElementCount);
|
void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const ai_real* pData, size_t pElementCount);
|
||||||
|
@ -122,6 +124,11 @@ protected:
|
||||||
/// Writes the scene library
|
/// Writes the scene library
|
||||||
void WriteSceneLibrary();
|
void WriteSceneLibrary();
|
||||||
|
|
||||||
|
// customized, Writes the animation library
|
||||||
|
void WriteAnimationsLibrary();
|
||||||
|
void WriteAnimationLibrary( size_t pIndex);
|
||||||
|
std::string mFoundSkeletonRootNodeID = "skeleton_root"; // will be replaced by found node id in the WriteNode call.
|
||||||
|
|
||||||
/// Recursively writes the given node
|
/// Recursively writes the given node
|
||||||
void WriteNode( const aiScene* scene, aiNode* pNode);
|
void WriteNode( const aiScene* scene, aiNode* pNode);
|
||||||
|
|
||||||
|
|
|
@ -302,7 +302,7 @@ struct Accessor
|
||||||
size_t mOffset; // in number of values
|
size_t mOffset; // in number of values
|
||||||
size_t mStride; // Stride in number of values
|
size_t mStride; // Stride in number of values
|
||||||
std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
|
std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
|
||||||
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, thats XYZ, for a color RGBA and so on.
|
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on.
|
||||||
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
|
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
|
||||||
std::string mSource; // URL of the source array
|
std::string mSource; // URL of the source array
|
||||||
mutable const Data* mData; // Pointer to the source array, if resolved. NULL else
|
mutable const Data* mData; // Pointer to the source array, if resolved. NULL else
|
||||||
|
|
|
@ -1619,7 +1619,7 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
|
||||||
mat.AddProperty( &effect.mRefractIndex, 1, AI_MATKEY_REFRACTI);
|
mat.AddProperty( &effect.mRefractIndex, 1, AI_MATKEY_REFRACTI);
|
||||||
|
|
||||||
// transparency, a very hard one. seemingly not all files are following the
|
// transparency, a very hard one. seemingly not all files are following the
|
||||||
// specification here (1.0 transparency => completly opaque)...
|
// specification here (1.0 transparency => completely opaque)...
|
||||||
// therefore, we let the opportunity for the user to manually invert
|
// therefore, we let the opportunity for the user to manually invert
|
||||||
// the transparency if necessary and we add preliminary support for RGB_ZERO mode
|
// the transparency if necessary and we add preliminary support for RGB_ZERO mode
|
||||||
if(effect.mTransparency >= 0.f && effect.mTransparency <= 1.f) {
|
if(effect.mTransparency >= 0.f && effect.mTransparency <= 1.f) {
|
||||||
|
|
|
@ -224,7 +224,7 @@ void ColladaParser::ReadStructure()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads asset informations such as coordinate system informations and legal blah
|
// Reads asset information such as coordinate system information and legal blah
|
||||||
void ColladaParser::ReadAssetInfo()
|
void ColladaParser::ReadAssetInfo()
|
||||||
{
|
{
|
||||||
if( mReader->isEmptyElement())
|
if( mReader->isEmptyElement())
|
||||||
|
|
|
@ -77,7 +77,7 @@ namespace Assimp
|
||||||
/** Reads the structure of the file */
|
/** Reads the structure of the file */
|
||||||
void ReadStructure();
|
void ReadStructure();
|
||||||
|
|
||||||
/** Reads asset informations such as coordinate system informations and legal blah */
|
/** Reads asset information such as coordinate system information and legal blah */
|
||||||
void ReadAssetInfo();
|
void ReadAssetInfo();
|
||||||
|
|
||||||
/** Reads the animation library */
|
/** Reads the animation library */
|
||||||
|
|
|
@ -49,7 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/ai_assert.h>
|
#include <assimp/ai_assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
@ -422,7 +422,6 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -566,7 +566,6 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
|
||||||
|
|
||||||
if ( !name_carrier ) {
|
if ( !name_carrier ) {
|
||||||
nodes_chain.push_back( new aiNode( original_name ) );
|
nodes_chain.push_back( new aiNode( original_name ) );
|
||||||
name_carrier = nodes_chain.back();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//setup metadata on newest node
|
//setup metadata on newest node
|
||||||
|
@ -645,7 +644,6 @@ void Converter::ConvertCameras( const Model& model )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Converter::ConvertLight( const Model& model, const Light& light )
|
void Converter::ConvertLight( const Model& model, const Light& light )
|
||||||
{
|
{
|
||||||
lights.push_back( new aiLight() );
|
lights.push_back( new aiLight() );
|
||||||
|
@ -783,7 +781,6 @@ const char* Converter::NameTransformationComp( TransformationComp comp )
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char* Converter::NameTransformationCompProperty( TransformationComp comp )
|
const char* Converter::NameTransformationCompProperty( TransformationComp comp )
|
||||||
{
|
{
|
||||||
switch ( comp )
|
switch ( comp )
|
||||||
|
@ -2239,9 +2236,17 @@ void Converter::ConvertAnimations()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Converter::RenameNode( const std::string& fixed_name, const std::string& new_name ) {
|
||||||
|
if ( node_names.find( fixed_name ) == node_names.end() ) {
|
||||||
|
FBXImporter::LogError( "Cannot rename node " + fixed_name + ", not existing.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( node_names.find( new_name ) != node_names.end() ) {
|
||||||
|
FBXImporter::LogError( "Cannot rename node " + fixed_name + " to " + new_name +", name already existing." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void Converter::RenameNode( const std::string& fixed_name, const std::string& new_name )
|
|
||||||
{
|
|
||||||
ai_assert( node_names.find( fixed_name ) != node_names.end() );
|
ai_assert( node_names.find( fixed_name ) != node_names.end() );
|
||||||
ai_assert( node_names.find( new_name ) == node_names.end() );
|
ai_assert( node_names.find( new_name ) == node_names.end() );
|
||||||
|
|
||||||
|
|
|
@ -45,13 +45,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||||
|
|
||||||
|
#include "FIReader.hpp"
|
||||||
|
#include "StringUtils.h"
|
||||||
|
|
||||||
// Workaround for issue #1361
|
// Workaround for issue #1361
|
||||||
// https://github.com/assimp/assimp/issues/1361
|
// https://github.com/assimp/assimp/issues/1361
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
#define _GLIBCXX_USE_C99 1
|
# define _GLIBCXX_USE_C99 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "FIReader.hpp"
|
|
||||||
#include "Exceptional.h"
|
#include "Exceptional.h"
|
||||||
#include <assimp/IOStream.hpp>
|
#include <assimp/IOStream.hpp>
|
||||||
#include <assimp/types.h>
|
#include <assimp/types.h>
|
||||||
|
@ -485,7 +487,9 @@ struct FIFloatDecoder: public FIDecoder {
|
||||||
value.reserve(numFloats);
|
value.reserve(numFloats);
|
||||||
for (size_t i = 0; i < numFloats; ++i) {
|
for (size_t i = 0; i < numFloats; ++i) {
|
||||||
int v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
|
int v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
|
||||||
value.push_back(*(float*)&v);
|
float f;
|
||||||
|
memcpy(&f, &v, 4);
|
||||||
|
value.push_back(f);
|
||||||
data += 4;
|
data += 4;
|
||||||
}
|
}
|
||||||
return FIFloatValue::create(std::move(value));
|
return FIFloatValue::create(std::move(value));
|
||||||
|
@ -503,7 +507,9 @@ struct FIDoubleDecoder: public FIDecoder {
|
||||||
for (size_t i = 0; i < numDoubles; ++i) {
|
for (size_t i = 0; i < numDoubles; ++i) {
|
||||||
long long b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7];
|
long long b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7];
|
||||||
long long v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
|
long long v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
|
||||||
value.push_back(*(double*)&v);
|
double f;
|
||||||
|
memcpy(&f, &v, 8);
|
||||||
|
value.push_back(f);
|
||||||
data += 8;
|
data += 8;
|
||||||
}
|
}
|
||||||
return FIDoubleValue::create(std::move(value));
|
return FIDoubleValue::create(std::move(value));
|
||||||
|
@ -685,7 +691,7 @@ public:
|
||||||
if (intValue) {
|
if (intValue) {
|
||||||
return intValue->value.size() == 1 ? intValue->value.front() : 0;
|
return intValue->value.size() == 1 ? intValue->value.front() : 0;
|
||||||
}
|
}
|
||||||
return stoi(attr->value->toString());
|
return atoi(attr->value->toString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int getAttributeValueAsInt(int idx) const /*override*/ {
|
virtual int getAttributeValueAsInt(int idx) const /*override*/ {
|
||||||
|
@ -696,7 +702,7 @@ public:
|
||||||
if (intValue) {
|
if (intValue) {
|
||||||
return intValue->value.size() == 1 ? intValue->value.front() : 0;
|
return intValue->value.size() == 1 ? intValue->value.front() : 0;
|
||||||
}
|
}
|
||||||
return stoi(attributes[idx].value->toString());
|
return atoi(attributes[idx].value->toString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual float getAttributeValueAsFloat(const char* name) const /*override*/ {
|
virtual float getAttributeValueAsFloat(const char* name) const /*override*/ {
|
||||||
|
@ -708,7 +714,7 @@ public:
|
||||||
if (floatValue) {
|
if (floatValue) {
|
||||||
return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
|
return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
|
||||||
}
|
}
|
||||||
return stof(attr->value->toString());
|
return atof(attr->value->toString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
|
virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
|
||||||
|
@ -719,7 +725,7 @@ public:
|
||||||
if (floatValue) {
|
if (floatValue) {
|
||||||
return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
|
return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
|
||||||
}
|
}
|
||||||
return stof(attributes[idx].value->toString());
|
return atof(attributes[idx].value->toString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* getNodeName() const /*override*/ {
|
virtual const char* getNodeName() const /*override*/ {
|
||||||
|
@ -984,13 +990,13 @@ private:
|
||||||
if (index < 32) {
|
if (index < 32) {
|
||||||
FIDecoder *decoder = defaultDecoder[index];
|
FIDecoder *decoder = defaultDecoder[index];
|
||||||
if (!decoder) {
|
if (!decoder) {
|
||||||
throw DeadlyImportError("Invalid encoding algorithm index " + std::to_string(index));
|
throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
|
||||||
}
|
}
|
||||||
return decoder->decode(dataP, len);
|
return decoder->decode(dataP, len);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (index - 32 >= vocabulary.encodingAlgorithmTable.size()) {
|
if (index - 32 >= vocabulary.encodingAlgorithmTable.size()) {
|
||||||
throw DeadlyImportError("Invalid encoding algorithm index " + std::to_string(index));
|
throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
|
||||||
}
|
}
|
||||||
std::string uri = vocabulary.encodingAlgorithmTable[index - 32];
|
std::string uri = vocabulary.encodingAlgorithmTable[index - 32];
|
||||||
auto it = decoderMap.find(uri);
|
auto it = decoderMap.find(uri);
|
||||||
|
@ -1014,12 +1020,12 @@ private:
|
||||||
alphabet = "0123456789-:TZ ";
|
alphabet = "0123456789-:TZ ";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw DeadlyImportError("Invalid restricted alphabet index " + std::to_string(index));
|
throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (index - 16 >= vocabulary.restrictedAlphabetTable.size()) {
|
if (index - 16 >= vocabulary.restrictedAlphabetTable.size()) {
|
||||||
throw DeadlyImportError("Invalid restricted alphabet index " + std::to_string(index));
|
throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
|
||||||
}
|
}
|
||||||
alphabet = vocabulary.restrictedAlphabetTable[index - 16];
|
alphabet = vocabulary.restrictedAlphabetTable[index - 16];
|
||||||
}
|
}
|
||||||
|
@ -1027,7 +1033,7 @@ private:
|
||||||
utf8::utf8to32(alphabet.begin(), alphabet.end(), back_inserter(alphabetUTF32));
|
utf8::utf8to32(alphabet.begin(), alphabet.end(), back_inserter(alphabetUTF32));
|
||||||
std::string::size_type alphabetLength = alphabetUTF32.size();
|
std::string::size_type alphabetLength = alphabetUTF32.size();
|
||||||
if (alphabetLength < 2) {
|
if (alphabetLength < 2) {
|
||||||
throw DeadlyImportError("Invalid restricted alphabet length " + std::to_string(alphabetLength));
|
throw DeadlyImportError("Invalid restricted alphabet length " + to_string(alphabetLength));
|
||||||
}
|
}
|
||||||
std::string::size_type bitsPerCharacter = 1;
|
std::string::size_type bitsPerCharacter = 1;
|
||||||
while ((1ull << bitsPerCharacter) <= alphabetLength) {
|
while ((1ull << bitsPerCharacter) <= alphabetLength) {
|
||||||
|
|
|
@ -46,11 +46,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef INCLUDED_AI_FI_READER_H
|
#ifndef INCLUDED_AI_FI_READER_H
|
||||||
#define INCLUDED_AI_FI_READER_H
|
#define INCLUDED_AI_FI_READER_H
|
||||||
|
|
||||||
#include <irrXML.h>
|
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||||
#include <memory>
|
|
||||||
|
//#include <wchar.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <cerrno>
|
||||||
|
#include <cwchar>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdint>
|
//#include <stdio.h>
|
||||||
|
//#include <cstdint>
|
||||||
|
#include <irrXML.h>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -154,7 +160,7 @@ class IOStream;
|
||||||
|
|
||||||
class FIReader: public irr::io::IIrrXMLReader<char, irr::io::IXMLBase> {
|
class FIReader: public irr::io::IIrrXMLReader<char, irr::io::IXMLBase> {
|
||||||
public:
|
public:
|
||||||
|
virtual ~FIReader();
|
||||||
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const = 0;
|
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const = 0;
|
||||||
|
|
||||||
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char *name) const = 0;
|
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char *name) const = 0;
|
||||||
|
@ -167,6 +173,13 @@ public:
|
||||||
|
|
||||||
};// class IFIReader
|
};// class IFIReader
|
||||||
|
|
||||||
|
inline
|
||||||
|
FIReader::~FIReader() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
}// namespace Assimp
|
}// namespace Assimp
|
||||||
|
|
||||||
|
#endif // #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||||
|
|
||||||
#endif // INCLUDED_AI_FI_READER_H
|
#endif // INCLUDED_AI_FI_READER_H
|
||||||
|
|
|
@ -56,98 +56,138 @@ using namespace Assimp;
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
FindDegeneratesProcess::FindDegeneratesProcess()
|
FindDegeneratesProcess::FindDegeneratesProcess()
|
||||||
: configRemoveDegenerates (false)
|
: mConfigRemoveDegenerates( false )
|
||||||
{}
|
, mConfigCheckAreaOfTriangle( false ){
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
FindDegeneratesProcess::~FindDegeneratesProcess()
|
FindDegeneratesProcess::~FindDegeneratesProcess() {
|
||||||
{
|
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const
|
bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const {
|
||||||
{
|
|
||||||
return 0 != (pFlags & aiProcess_FindDegenerates);
|
return 0 != (pFlags & aiProcess_FindDegenerates);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup import configuration
|
// Setup import configuration
|
||||||
void FindDegeneratesProcess::SetupProperties(const Importer* pImp)
|
void FindDegeneratesProcess::SetupProperties(const Importer* pImp) {
|
||||||
{
|
|
||||||
// Get the current value of AI_CONFIG_PP_FD_REMOVE
|
// Get the current value of AI_CONFIG_PP_FD_REMOVE
|
||||||
configRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
|
mConfigRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
|
||||||
|
mConfigCheckAreaOfTriangle = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_CHECKAREA) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void FindDegeneratesProcess::Execute( aiScene* pScene)
|
void FindDegeneratesProcess::Execute( aiScene* pScene) {
|
||||||
{
|
|
||||||
DefaultLogger::get()->debug("FindDegeneratesProcess begin");
|
DefaultLogger::get()->debug("FindDegeneratesProcess begin");
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
|
||||||
ExecuteOnMesh( pScene->mMeshes[i]);
|
ExecuteOnMesh( pScene->mMeshes[ i ] );
|
||||||
}
|
}
|
||||||
DefaultLogger::get()->debug("FindDegeneratesProcess finished");
|
DefaultLogger::get()->debug("FindDegeneratesProcess finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ai_real heron( ai_real a, ai_real b, ai_real c ) {
|
||||||
|
ai_real s = (a + b + c) / 2;
|
||||||
|
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), 0.5 );
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB ) {
|
||||||
|
const ai_real lx = ( vB.x - vA.x );
|
||||||
|
const ai_real ly = ( vB.y - vA.y );
|
||||||
|
const ai_real lz = ( vB.z - vA.z );
|
||||||
|
ai_real a = lx*lx + ly*ly + lz*lz;
|
||||||
|
ai_real d = pow( a, 0.5 );
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
|
||||||
|
ai_real area = 0;
|
||||||
|
|
||||||
|
aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
|
||||||
|
aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
|
||||||
|
aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
|
||||||
|
|
||||||
|
ai_real a( distance3D( vA, vB ) );
|
||||||
|
ai_real b( distance3D( vB, vC ) );
|
||||||
|
ai_real c( distance3D( vC, vA ) );
|
||||||
|
area = heron( a, b, c );
|
||||||
|
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported mesh
|
// Executes the post processing step on the given imported mesh
|
||||||
void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh)
|
void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
||||||
{
|
|
||||||
mesh->mPrimitiveTypes = 0;
|
mesh->mPrimitiveTypes = 0;
|
||||||
|
|
||||||
std::vector<bool> remove_me;
|
std::vector<bool> remove_me;
|
||||||
if (configRemoveDegenerates)
|
if (mConfigRemoveDegenerates) {
|
||||||
remove_me.resize(mesh->mNumFaces,false);
|
remove_me.resize( mesh->mNumFaces, false );
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int deg = 0, limit;
|
unsigned int deg = 0, limit;
|
||||||
for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
|
for ( unsigned int a = 0; a < mesh->mNumFaces; ++a ) {
|
||||||
{
|
|
||||||
aiFace& face = mesh->mFaces[a];
|
aiFace& face = mesh->mFaces[a];
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
// check whether the face contains degenerated entries
|
// check whether the face contains degenerated entries
|
||||||
for (unsigned int i = 0; i < face.mNumIndices; ++i)
|
for (unsigned int i = 0; i < face.mNumIndices; ++i) {
|
||||||
{
|
|
||||||
// Polygons with more than 4 points are allowed to have double points, that is
|
// Polygons with more than 4 points are allowed to have double points, that is
|
||||||
// simulating polygons with holes just with concave polygons. However,
|
// simulating polygons with holes just with concave polygons. However,
|
||||||
// double points may not come directly after another.
|
// double points may not come directly after another.
|
||||||
limit = face.mNumIndices;
|
limit = face.mNumIndices;
|
||||||
if (face.mNumIndices > 4)
|
if (face.mNumIndices > 4) {
|
||||||
limit = std::min(limit,i+2);
|
limit = std::min( limit, i+2 );
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int t = i+1; t < limit; ++t)
|
for (unsigned int t = i+1; t < limit; ++t) {
|
||||||
{
|
if (mesh->mVertices[face.mIndices[ i ] ] == mesh->mVertices[ face.mIndices[ t ] ]) {
|
||||||
if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]])
|
|
||||||
{
|
|
||||||
// we have found a matching vertex position
|
// we have found a matching vertex position
|
||||||
// remove the corresponding index from the array
|
// remove the corresponding index from the array
|
||||||
--face.mNumIndices;--limit;
|
--face.mNumIndices;
|
||||||
for (unsigned int m = t; m < face.mNumIndices; ++m)
|
--limit;
|
||||||
{
|
for (unsigned int m = t; m < face.mNumIndices; ++m) {
|
||||||
face.mIndices[m] = face.mIndices[m+1];
|
face.mIndices[ m ] = face.mIndices[ m+1 ];
|
||||||
}
|
}
|
||||||
--t;
|
--t;
|
||||||
|
|
||||||
// NOTE: we set the removed vertex index to an unique value
|
// NOTE: we set the removed vertex index to an unique value
|
||||||
// to make sure the developer gets notified when his
|
// to make sure the developer gets notified when his
|
||||||
// application attemps to access this data.
|
// application attemps to access this data.
|
||||||
face.mIndices[face.mNumIndices] = 0xdeadbeef;
|
face.mIndices[ face.mNumIndices ] = 0xdeadbeef;
|
||||||
|
|
||||||
if(first)
|
if(first) {
|
||||||
{
|
|
||||||
++deg;
|
++deg;
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configRemoveDegenerates) {
|
if ( mConfigRemoveDegenerates ) {
|
||||||
remove_me[a] = true;
|
remove_me[ a ] = true;
|
||||||
goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
|
goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( mConfigCheckAreaOfTriangle ) {
|
||||||
|
if ( face.mNumIndices == 3 ) {
|
||||||
|
ai_real area = calculateAreaOfTriangle( face, mesh );
|
||||||
|
if ( area < 1e-6 ) {
|
||||||
|
if ( mConfigRemoveDegenerates ) {
|
||||||
|
remove_me[ a ] = true;
|
||||||
|
goto evil_jump_outside;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: check for index which is corrupt.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to update the primitive flags array of the mesh.
|
// We need to update the primitive flags array of the mesh.
|
||||||
|
@ -171,7 +211,7 @@ evil_jump_outside:
|
||||||
}
|
}
|
||||||
|
|
||||||
// If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
|
// If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
|
||||||
if (configRemoveDegenerates && deg) {
|
if (mConfigRemoveDegenerates && deg) {
|
||||||
unsigned int n = 0;
|
unsigned int n = 0;
|
||||||
for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
|
for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,15 +54,11 @@ namespace Assimp {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** FindDegeneratesProcess: Searches a mesh for degenerated triangles.
|
/** FindDegeneratesProcess: Searches a mesh for degenerated triangles.
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API FindDegeneratesProcess : public BaseProcess
|
class ASSIMP_API FindDegeneratesProcess : public BaseProcess {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FindDegeneratesProcess();
|
FindDegeneratesProcess();
|
||||||
~FindDegeneratesProcess();
|
~FindDegeneratesProcess();
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Check whether step is active
|
// Check whether step is active
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const;
|
||||||
|
@ -79,28 +75,53 @@ public:
|
||||||
// Execute step on a given mesh
|
// Execute step on a given mesh
|
||||||
void ExecuteOnMesh( aiMesh* mesh);
|
void ExecuteOnMesh( aiMesh* mesh);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// @brief Enable the instant removal of degenerated primitives
|
||||||
|
/// @param enabled true for enabled.
|
||||||
|
void EnableInstantRemoval(bool enabled);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Enable the instant removal of degenerated primitives
|
/// @brief Check whether instant removal is currently enabled
|
||||||
* @param d hm ... difficult to guess what this means, hu!?
|
/// @return The instant removal state.
|
||||||
*/
|
bool IsInstantRemoval() const;
|
||||||
void EnableInstantRemoval(bool d) {
|
|
||||||
configRemoveDegenerates = d;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Check whether instant removal is currently enabled
|
/// @brief Enable the area check for triangles.
|
||||||
* @return ...
|
/// @param enabled true for enabled.
|
||||||
*/
|
void EnableAreaCheck( bool enabled );
|
||||||
bool IsInstantRemoval() const {
|
|
||||||
return configRemoveDegenerates;
|
// -------------------------------------------------------------------
|
||||||
}
|
/// @brief Check whether the area check is enabled.
|
||||||
|
/// @return The area check state.
|
||||||
|
bool isAreaCheckEnabled() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! Configuration option: remove degenerates faces immediately
|
//! Configuration option: remove degenerates faces immediately
|
||||||
bool configRemoveDegenerates;
|
bool mConfigRemoveDegenerates;
|
||||||
|
//! Configuration option: check for area
|
||||||
|
bool mConfigCheckAreaOfTriangle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
void FindDegeneratesProcess::EnableInstantRemoval(bool enabled) {
|
||||||
|
mConfigRemoveDegenerates = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool FindDegeneratesProcess::IsInstantRemoval() const {
|
||||||
|
return mConfigRemoveDegenerates;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void FindDegeneratesProcess::EnableAreaCheck( bool enabled ) {
|
||||||
|
mConfigCheckAreaOfTriangle = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool FindDegeneratesProcess::isAreaCheckEnabled() const {
|
||||||
|
return mConfigCheckAreaOfTriangle;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Namespace Assimp
|
||||||
|
|
||||||
#endif // !! AI_FINDDEGENERATESPROCESS_H_INC
|
#endif // !! AI_FINDDEGENERATESPROCESS_H_INC
|
||||||
|
|
|
@ -1499,7 +1499,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
||||||
|
|
||||||
|
|
||||||
IfcVector3 wall_extrusion;
|
IfcVector3 wall_extrusion;
|
||||||
bool do_connections = false, first = true;
|
bool first = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
@ -1527,7 +1527,6 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
if (dot > 0.f) {
|
if (dot > 0.f) {
|
||||||
do_connections = true;
|
|
||||||
wall_extrusion = t.extrusionDir;
|
wall_extrusion = t.extrusionDir;
|
||||||
if (is_extruded_side) {
|
if (is_extruded_side) {
|
||||||
wall_extrusion = - wall_extrusion;
|
wall_extrusion = - wall_extrusion;
|
||||||
|
@ -1607,44 +1606,6 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
||||||
old_verts.swap(curmesh.verts);
|
old_verts.swap(curmesh.verts);
|
||||||
old_vertcnt.swap(curmesh.vertcnt);
|
old_vertcnt.swap(curmesh.vertcnt);
|
||||||
|
|
||||||
|
|
||||||
// add connection geometry to close the adjacent 'holes' for the openings
|
|
||||||
// this should only be done from one side of the wall or the polygons
|
|
||||||
// would be emitted twice.
|
|
||||||
if (false && do_connections) {
|
|
||||||
|
|
||||||
std::vector<IfcVector3> tmpvec;
|
|
||||||
for(ClipperLib::Polygon& opening : holes_union) {
|
|
||||||
|
|
||||||
ai_assert(ClipperLib::Orientation(opening));
|
|
||||||
|
|
||||||
tmpvec.clear();
|
|
||||||
|
|
||||||
for(ClipperLib::IntPoint& point : opening) {
|
|
||||||
|
|
||||||
tmpvec.push_back( minv * IfcVector3(
|
|
||||||
vmin.x + from_int64(point.X) * vmax.x,
|
|
||||||
vmin.y + from_int64(point.Y) * vmax.y,
|
|
||||||
coord));
|
|
||||||
}
|
|
||||||
|
|
||||||
for(size_t i = 0, size = tmpvec.size(); i < size; ++i) {
|
|
||||||
const size_t next = (i+1)%size;
|
|
||||||
|
|
||||||
curmesh.vertcnt.push_back(4);
|
|
||||||
|
|
||||||
const IfcVector3& in_world = tmpvec[i];
|
|
||||||
const IfcVector3& next_world = tmpvec[next];
|
|
||||||
|
|
||||||
// Assumptions: no 'partial' openings, wall thickness roughly the same across the wall
|
|
||||||
curmesh.verts.push_back(in_world);
|
|
||||||
curmesh.verts.push_back(in_world+wall_extrusion);
|
|
||||||
curmesh.verts.push_back(next_world+wall_extrusion);
|
|
||||||
curmesh.verts.push_back(next_world);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector< std::vector<p2t::Point*> > contours;
|
std::vector< std::vector<p2t::Point*> > contours;
|
||||||
for(ClipperLib::ExPolygon& clip : clipped) {
|
for(ClipperLib::ExPolygon& clip : clipped) {
|
||||||
|
|
||||||
|
|
|
@ -394,7 +394,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
|
||||||
angles[1] %= 360;
|
angles[1] %= 360;
|
||||||
angles[2] %= 360;
|
angles[2] %= 360;
|
||||||
|
|
||||||
if ( bool(angles[0]*angles[1]) && bool(angles[1]*angles[2]) )
|
if ( (angles[0]*angles[1]) != 0 && (angles[1]*angles[2]) != 0 )
|
||||||
{
|
{
|
||||||
FindSuitableMultiple(angles[0]);
|
FindSuitableMultiple(angles[0]);
|
||||||
FindSuitableMultiple(angles[1]);
|
FindSuitableMultiple(angles[1]);
|
||||||
|
|
|
@ -274,10 +274,6 @@ aiReturn Importer::UnregisterLoader(BaseImporter* pImp)
|
||||||
|
|
||||||
if (it != pimpl->mImporter.end()) {
|
if (it != pimpl->mImporter.end()) {
|
||||||
pimpl->mImporter.erase(it);
|
pimpl->mImporter.erase(it);
|
||||||
|
|
||||||
std::set<std::string> st;
|
|
||||||
pImp->GetExtensionList(st);
|
|
||||||
|
|
||||||
DefaultLogger::get()->info("Unregistering custom importer: ");
|
DefaultLogger::get()->info("Unregistering custom importer: ");
|
||||||
return AI_SUCCESS;
|
return AI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,6 +223,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
|
||||||
iMaxRefTris = std::max(iMaxRefTris,*piCur);
|
iMaxRefTris = std::max(iMaxRefTris,*piCur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ai_assert(iMaxRefTris > 0);
|
||||||
unsigned int* piCandidates = new unsigned int[iMaxRefTris*3];
|
unsigned int* piCandidates = new unsigned int[iMaxRefTris*3];
|
||||||
unsigned int iCacheMisses = 0;
|
unsigned int iCacheMisses = 0;
|
||||||
|
|
||||||
|
|
|
@ -446,8 +446,6 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey>& out,
|
||||||
|
|
||||||
// Iterate through all three arrays at once - it's tricky, but
|
// Iterate through all three arrays at once - it's tricky, but
|
||||||
// rather interesting to implement.
|
// rather interesting to implement.
|
||||||
double lasttime = std::min(envl_x->keys[0].time,std::min(envl_y->keys[0].time,envl_z->keys[0].time));
|
|
||||||
|
|
||||||
cur_x = envl_x->keys.begin();
|
cur_x = envl_x->keys.begin();
|
||||||
cur_y = envl_y->keys.begin();
|
cur_y = envl_y->keys.begin();
|
||||||
cur_z = envl_z->keys.begin();
|
cur_z = envl_z->keys.begin();
|
||||||
|
@ -503,7 +501,7 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey>& out,
|
||||||
InterpolateTrack(out,fill,(end_y ? (*cur_x) : (*cur_y)).time);
|
InterpolateTrack(out,fill,(end_y ? (*cur_x) : (*cur_y)).time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lasttime = fill.mTime;
|
double lasttime = fill.mTime;
|
||||||
out.push_back(fill);
|
out.push_back(fill);
|
||||||
|
|
||||||
if (lasttime >= (*cur_x).time) {
|
if (lasttime >= (*cur_x).time) {
|
||||||
|
|
|
@ -483,7 +483,7 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
|
||||||
const LWO::VColorChannel& vc = layer.mVColorChannels[i];
|
const LWO::VColorChannel& vc = layer.mVColorChannels[i];
|
||||||
|
|
||||||
if (surf.mVCMap == vc.name) {
|
if (surf.mVCMap == vc.name) {
|
||||||
// The vertex color map is explicitely requested by the surface so we need to take special care of it
|
// The vertex color map is explicitly requested by the surface so we need to take special care of it
|
||||||
for (unsigned int a = 0; a < std::min(next,AI_MAX_NUMBER_OF_COLOR_SETS-1u); ++a) {
|
for (unsigned int a = 0; a < std::min(next,AI_MAX_NUMBER_OF_COLOR_SETS-1u); ++a) {
|
||||||
out[a+1] = out[a];
|
out[a+1] = out[a];
|
||||||
}
|
}
|
||||||
|
|
|
@ -471,7 +471,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
||||||
// Determine the exact location of a LWO file
|
// Determine the exact location of a LWO file
|
||||||
std::string LWSImporter::FindLWOFile(const std::string& in)
|
std::string LWSImporter::FindLWOFile(const std::string& in)
|
||||||
{
|
{
|
||||||
// insert missing directory seperator if necessary
|
// insert missing directory separator if necessary
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/')
|
if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/')
|
||||||
{
|
{
|
||||||
|
|
|
@ -274,11 +274,9 @@ void MD2Importer::InternReadFile( const std::string& pFile,
|
||||||
aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
|
aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
|
||||||
pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
||||||
|
|
||||||
// navigate to the begin of the frame data
|
// navigate to the begin of the current frame data
|
||||||
BE_NCONST MD2::Frame* pcFrame = (BE_NCONST MD2::Frame*) ((uint8_t*)
|
BE_NCONST MD2::Frame* pcFrame = (BE_NCONST MD2::Frame*) ((uint8_t*)
|
||||||
m_pcHeader + m_pcHeader->offsetFrames);
|
m_pcHeader + m_pcHeader->offsetFrames + (m_pcHeader->frameSize * configFrameID));
|
||||||
|
|
||||||
pcFrame += configFrameID;
|
|
||||||
|
|
||||||
// navigate to the begin of the triangle data
|
// navigate to the begin of the triangle data
|
||||||
MD2::Triangle* pcTriangles = (MD2::Triangle*) ((uint8_t*)
|
MD2::Triangle* pcTriangles = (MD2::Triangle*) ((uint8_t*)
|
||||||
|
|
|
@ -665,7 +665,9 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
||||||
if (0.0f != pcMatIn->Power)
|
if (0.0f != pcMatIn->Power)
|
||||||
{
|
{
|
||||||
iShadingMode = (int)aiShadingMode_Phong;
|
iShadingMode = (int)aiShadingMode_Phong;
|
||||||
pcMatOut->AddProperty<float>(&pcMatIn->Power,1,AI_MATKEY_SHININESS);
|
// pcMatIn is packed, we can't form pointers to its members
|
||||||
|
float power = pcMatIn->Power;
|
||||||
|
pcMatOut->AddProperty<float>(&power,1,AI_MATKEY_SHININESS);
|
||||||
}
|
}
|
||||||
pcMatOut->AddProperty<int>(&iShadingMode,1,AI_MATKEY_SHADING_MODEL);
|
pcMatOut->AddProperty<int>(&iShadingMode,1,AI_MATKEY_SHADING_MODEL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,8 +243,6 @@ void NFFImporter::InternReadFile( const std::string& pFile,
|
||||||
if( !file.get())
|
if( !file.get())
|
||||||
throw DeadlyImportError( "Failed to open NFF file " + pFile + ".");
|
throw DeadlyImportError( "Failed to open NFF file " + pFile + ".");
|
||||||
|
|
||||||
unsigned int m = (unsigned int)file->FileSize();
|
|
||||||
|
|
||||||
// allocate storage and copy the contents of the file to a memory buffer
|
// allocate storage and copy the contents of the file to a memory buffer
|
||||||
// (terminate it with zero)
|
// (terminate it with zero)
|
||||||
std::vector<char> mBuffer2;
|
std::vector<char> mBuffer2;
|
||||||
|
@ -469,7 +467,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
|
||||||
for (unsigned int a = 0; a < numIdx;++a)
|
for (unsigned int a = 0; a < numIdx;++a)
|
||||||
{
|
{
|
||||||
SkipSpaces(sz,&sz);
|
SkipSpaces(sz,&sz);
|
||||||
m = ::strtoul10(sz,&sz);
|
unsigned int m = ::strtoul10(sz,&sz);
|
||||||
if (m >= (unsigned int)tempPositions.size())
|
if (m >= (unsigned int)tempPositions.size())
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->error("NFF2: Vertex index overflow");
|
DefaultLogger::get()->error("NFF2: Vertex index overflow");
|
||||||
|
@ -635,7 +633,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
|
||||||
for (std::vector<unsigned int>::const_iterator it = tempIdx.begin(), end = tempIdx.end();
|
for (std::vector<unsigned int>::const_iterator it = tempIdx.begin(), end = tempIdx.end();
|
||||||
it != end;++it)
|
it != end;++it)
|
||||||
{
|
{
|
||||||
m = *it;
|
unsigned int m = *it;
|
||||||
|
|
||||||
// copy colors -vertex color specifications override polygon color specifications
|
// copy colors -vertex color specifications override polygon color specifications
|
||||||
if (hasColor)
|
if (hasColor)
|
||||||
|
@ -735,7 +733,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
|
||||||
sz = &line[1];out = currentMesh;
|
sz = &line[1];out = currentMesh;
|
||||||
}
|
}
|
||||||
SkipSpaces(sz,&sz);
|
SkipSpaces(sz,&sz);
|
||||||
m = strtoul10(sz);
|
unsigned int m = strtoul10(sz);
|
||||||
|
|
||||||
// ---- flip the face order
|
// ---- flip the face order
|
||||||
out->vertices.resize(out->vertices.size()+m);
|
out->vertices.resize(out->vertices.size()+m);
|
||||||
|
@ -1081,7 +1079,9 @@ void NFFImporter::InternReadFile( const std::string& pFile,
|
||||||
// generate the camera
|
// generate the camera
|
||||||
if (hasCam)
|
if (hasCam)
|
||||||
{
|
{
|
||||||
aiNode* nd = *ppcChildren = new aiNode();
|
ai_assert(ppcChildren);
|
||||||
|
aiNode* nd = new aiNode();
|
||||||
|
*ppcChildren = nd;
|
||||||
nd->mName.Set("<NFF_Camera>");
|
nd->mName.Set("<NFF_Camera>");
|
||||||
nd->mParent = root;
|
nd->mParent = root;
|
||||||
|
|
||||||
|
@ -1105,13 +1105,15 @@ void NFFImporter::InternReadFile( const std::string& pFile,
|
||||||
// generate light sources
|
// generate light sources
|
||||||
if (!lights.empty())
|
if (!lights.empty())
|
||||||
{
|
{
|
||||||
|
ai_assert(ppcChildren);
|
||||||
pScene->mNumLights = (unsigned int)lights.size();
|
pScene->mNumLights = (unsigned int)lights.size();
|
||||||
pScene->mLights = new aiLight*[pScene->mNumLights];
|
pScene->mLights = new aiLight*[pScene->mNumLights];
|
||||||
for (unsigned int i = 0; i < pScene->mNumLights;++i,++ppcChildren)
|
for (unsigned int i = 0; i < pScene->mNumLights;++i,++ppcChildren)
|
||||||
{
|
{
|
||||||
const Light& l = lights[i];
|
const Light& l = lights[i];
|
||||||
|
|
||||||
aiNode* nd = *ppcChildren = new aiNode();
|
aiNode* nd = new aiNode();
|
||||||
|
*ppcChildren = nd;
|
||||||
nd->mParent = root;
|
nd->mParent = root;
|
||||||
|
|
||||||
nd->mName.length = ::ai_snprintf(nd->mName.data,1024,"<NFF_Light%u>",i);
|
nd->mName.length = ::ai_snprintf(nd->mName.data,1024,"<NFF_Light%u>",i);
|
||||||
|
@ -1128,7 +1130,8 @@ void NFFImporter::InternReadFile( const std::string& pFile,
|
||||||
if (!pScene->mNumMeshes)throw DeadlyImportError("NFF: No meshes loaded");
|
if (!pScene->mNumMeshes)throw DeadlyImportError("NFF: No meshes loaded");
|
||||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||||
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = pScene->mNumMeshes];
|
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = pScene->mNumMeshes];
|
||||||
for (it = meshes.begin(), m = 0; it != end;++it)
|
unsigned int m = 0;
|
||||||
|
for (it = meshes.begin(); it != end;++it)
|
||||||
{
|
{
|
||||||
if ((*it).faces.empty())continue;
|
if ((*it).faces.empty())continue;
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ std::string ObjExporter :: GetMaterialLibName()
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::string ObjExporter::GetMaterialLibFileName() {
|
std::string ObjExporter::GetMaterialLibFileName() {
|
||||||
// Remove existing .obj file extention so that the final material file name will be fileName.mtl and not fileName.obj.mtl
|
// Remove existing .obj file extension so that the final material file name will be fileName.mtl and not fileName.obj.mtl
|
||||||
size_t lastdot = filename.find_last_of('.');
|
size_t lastdot = filename.find_last_of('.');
|
||||||
if (lastdot != std::string::npos)
|
if (lastdot != std::string::npos)
|
||||||
return filename.substr(0, lastdot) + MaterialExt;
|
return filename.substr(0, lastdot) + MaterialExt;
|
||||||
|
@ -258,7 +258,6 @@ void ObjExporter::WriteMaterialFile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ObjExporter::WriteGeometryFile(bool noMtl) {
|
void ObjExporter::WriteGeometryFile(bool noMtl) {
|
||||||
WriteHeader(mOutput);
|
WriteHeader(mOutput);
|
||||||
if (!noMtl)
|
if (!noMtl)
|
||||||
|
@ -280,8 +279,10 @@ void ObjExporter::WriteGeometryFile(bool noMtl) {
|
||||||
mOutput << "# " << vp.size() << " vertex positions and colors" << endl;
|
mOutput << "# " << vp.size() << " vertex positions and colors" << endl;
|
||||||
size_t colIdx = 0;
|
size_t colIdx = 0;
|
||||||
for ( const aiVector3D& v : vp ) {
|
for ( const aiVector3D& v : vp ) {
|
||||||
mOutput << "v " << v.x << " " << v.y << " " << v.z << " " << vc[ colIdx ].r << " " << vc[ colIdx ].g << " " << vc[ colIdx ].b << endl;
|
if ( colIdx < vc.size() ) {
|
||||||
colIdx++;
|
mOutput << "v " << v.x << " " << v.y << " " << v.z << " " << vc[ colIdx ].r << " " << vc[ colIdx ].g << " " << vc[ colIdx ].b << endl;
|
||||||
|
}
|
||||||
|
++colIdx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mOutput << endl;
|
mOutput << endl;
|
||||||
|
|
|
@ -258,7 +258,7 @@ aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste
|
||||||
ReadTechnique(Trim(techniqueName), ss, material);
|
ReadTechnique(Trim(techniqueName), ss, material);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read informations from a custom material
|
// Read information from a custom material
|
||||||
/** @todo This "set $x y" does not seem to be a official Ogre material system feature.
|
/** @todo This "set $x y" does not seem to be a official Ogre material system feature.
|
||||||
Materials can inherit other materials and override texture units by using the (unique)
|
Materials can inherit other materials and override texture units by using the (unique)
|
||||||
parent texture unit name in your cloned material.
|
parent texture unit name in your cloned material.
|
||||||
|
|
|
@ -652,6 +652,8 @@ static void setMatrix( aiNode *node, DataArrayList *transformData ) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ai_assert(i == 16);
|
||||||
|
|
||||||
node->mTransformation.a1 = m[ 0 ];
|
node->mTransformation.a1 = m[ 0 ];
|
||||||
node->mTransformation.a2 = m[ 4 ];
|
node->mTransformation.a2 = m[ 4 ];
|
||||||
node->mTransformation.a3 = m[ 8 ];
|
node->mTransformation.a3 = m[ 8 ];
|
||||||
|
|
|
@ -233,10 +233,12 @@ void OptimizeGraphProcess::CollectNewChildren(aiNode* nd, std::list<aiNode*>& no
|
||||||
|
|
||||||
nd->mNumChildren = static_cast<unsigned int>(child_nodes.size());
|
nd->mNumChildren = static_cast<unsigned int>(child_nodes.size());
|
||||||
|
|
||||||
aiNode** tmp = nd->mChildren;
|
if (nd->mChildren) {
|
||||||
for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end(); ++it) {
|
aiNode** tmp = nd->mChildren;
|
||||||
aiNode* node = *tmp++ = *it;
|
for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end(); ++it) {
|
||||||
node->mParent = nd;
|
aiNode* node = *tmp++ = *it;
|
||||||
|
node->mParent = nd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes_out += static_cast<unsigned int>(child_nodes.size());
|
nodes_out += static_cast<unsigned int>(child_nodes.size());
|
||||||
|
|
|
@ -671,7 +671,6 @@ bool PLY::ElementInstanceList::ParseInstanceList(
|
||||||
PLYImporter* loader)
|
PLYImporter* loader)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pcElement);
|
ai_assert(NULL != pcElement);
|
||||||
const char* pCur = (const char*)&buffer[0];
|
|
||||||
|
|
||||||
// parse all elements
|
// parse all elements
|
||||||
if (EEST_INVALID == pcElement->eSemantic || pcElement->alProperties.empty())
|
if (EEST_INVALID == pcElement->eSemantic || pcElement->alProperties.empty())
|
||||||
|
@ -683,11 +682,11 @@ bool PLY::ElementInstanceList::ParseInstanceList(
|
||||||
PLY::DOM::SkipComments(buffer);
|
PLY::DOM::SkipComments(buffer);
|
||||||
PLY::DOM::SkipLine(buffer);
|
PLY::DOM::SkipLine(buffer);
|
||||||
streamBuffer.getNextLine(buffer);
|
streamBuffer.getNextLine(buffer);
|
||||||
pCur = (buffer.empty()) ? NULL : (const char*)&buffer[0];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
const char* pCur = (const char*)&buffer[0];
|
||||||
// be sure to have enough storage
|
// be sure to have enough storage
|
||||||
for (unsigned int i = 0; i < pcElement->NumOccur; ++i)
|
for (unsigned int i = 0; i < pcElement->NumOccur; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -260,7 +260,7 @@ void RAWImporter::InternReadFile( const std::string& pFile,
|
||||||
node = *cc = new aiNode();
|
node = *cc = new aiNode();
|
||||||
node->mParent = pScene->mRootNode;
|
node->mParent = pScene->mRootNode;
|
||||||
}
|
}
|
||||||
else node = *cc;++cc;
|
else node = *cc;
|
||||||
node->mName.Set(outGroup.name);
|
node->mName.Set(outGroup.name);
|
||||||
|
|
||||||
// add all meshes
|
// add all meshes
|
||||||
|
|
|
@ -145,6 +145,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
|
||||||
if (!abReferenced[i]) {
|
if (!abReferenced[i]) {
|
||||||
++unreferencedRemoved;
|
++unreferencedRemoved;
|
||||||
delete pScene->mMaterials[i];
|
delete pScene->mMaterials[i];
|
||||||
|
pScene->mMaterials[i] = nullptr;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +159,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
|
||||||
me = 0;
|
me = 0;
|
||||||
aiMappingTable[i] = aiMappingTable[a];
|
aiMappingTable[i] = aiMappingTable[a];
|
||||||
delete pScene->mMaterials[i];
|
delete pScene->mMaterials[i];
|
||||||
|
pScene->mMaterials[i] = nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,6 +171,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
|
||||||
// If the new material count differs from the original,
|
// If the new material count differs from the original,
|
||||||
// we need to rebuild the material list and remap mesh material indexes.
|
// we need to rebuild the material list and remap mesh material indexes.
|
||||||
if (iNewNum != pScene->mNumMaterials) {
|
if (iNewNum != pScene->mNumMaterials) {
|
||||||
|
ai_assert(iNewNum > 0);
|
||||||
aiMaterial** ppcMaterials = new aiMaterial*[iNewNum];
|
aiMaterial** ppcMaterials = new aiMaterial*[iNewNum];
|
||||||
::memset(ppcMaterials,0,sizeof(void*)*iNewNum);
|
::memset(ppcMaterials,0,sizeof(void*)*iNewNum);
|
||||||
for (unsigned int p = 0; p < pScene->mNumMaterials;++p)
|
for (unsigned int p = 0; p < pScene->mNumMaterials;++p)
|
||||||
|
|
|
@ -902,6 +902,7 @@ void SIBImporter::InternReadFile(const std::string& pFile,
|
||||||
// Add nodes for each object.
|
// Add nodes for each object.
|
||||||
for (size_t n=0;n<sib.objs.size();n++)
|
for (size_t n=0;n<sib.objs.size();n++)
|
||||||
{
|
{
|
||||||
|
ai_assert(root->mChildren);
|
||||||
SIBObject& obj = sib.objs[n];
|
SIBObject& obj = sib.objs[n];
|
||||||
aiNode* node = new aiNode;
|
aiNode* node = new aiNode;
|
||||||
root->mChildren[childIdx++] = node;
|
root->mChildren[childIdx++] = node;
|
||||||
|
@ -926,6 +927,7 @@ void SIBImporter::InternReadFile(const std::string& pFile,
|
||||||
// (no transformation as the light is already in world space)
|
// (no transformation as the light is already in world space)
|
||||||
for (size_t n=0;n<sib.lights.size();n++)
|
for (size_t n=0;n<sib.lights.size();n++)
|
||||||
{
|
{
|
||||||
|
ai_assert(root->mChildren);
|
||||||
aiLight* light = sib.lights[n];
|
aiLight* light = sib.lights[n];
|
||||||
if ( nullptr != light ) {
|
if ( nullptr != light ) {
|
||||||
aiNode* node = new aiNode;
|
aiNode* node = new aiNode;
|
||||||
|
|
|
@ -334,7 +334,7 @@ bool STEP::StringToUTF8(std::string& s)
|
||||||
size_t j = basei, jend = s.size()-3;
|
size_t j = basei, jend = s.size()-3;
|
||||||
|
|
||||||
for (; j < jend; ++j) {
|
for (; j < jend; ++j) {
|
||||||
if (s[j] == '\\' && s[j] == 'X' && s[j] == '0' && s[j] == '\\') {
|
if (s[j] == '\\' && s[j+1] == 'X' && s[j+2] == '0' && s[j+3] == '\\') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,9 @@ static bool IsBinarySTL(const char* buffer, unsigned int fileSize) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t faceCount = *reinterpret_cast<const uint32_t*>(buffer + 80);
|
const char *facecount_pos = buffer + 80;
|
||||||
|
uint32_t faceCount( 0 );
|
||||||
|
::memcpy( &faceCount, facecount_pos, sizeof( uint32_t ) );
|
||||||
const uint32_t expectedBinaryFileSize = faceCount * 50 + 84;
|
const uint32_t expectedBinaryFileSize = faceCount * 50 + 84;
|
||||||
|
|
||||||
return expectedBinaryFileSize == fileSize;
|
return expectedBinaryFileSize == fileSize;
|
||||||
|
@ -200,17 +202,11 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
if (IsBinarySTL(mBuffer, fileSize)) {
|
if (IsBinarySTL(mBuffer, fileSize)) {
|
||||||
bMatClr = LoadBinaryFile();
|
bMatClr = LoadBinaryFile();
|
||||||
} else if (IsAsciiSTL(mBuffer, fileSize)) {
|
} else if (IsAsciiSTL(mBuffer, fileSize)) {
|
||||||
LoadASCIIFile();
|
LoadASCIIFile( pScene->mRootNode );
|
||||||
} else {
|
} else {
|
||||||
throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + ".");
|
throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
// add all created meshes to the single node
|
|
||||||
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
|
|
||||||
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
|
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
|
|
||||||
pScene->mRootNode->mMeshes[i] = i;
|
|
||||||
|
|
||||||
// create a single default material, using a white diffuse color for consistency with
|
// create a single default material, using a white diffuse color for consistency with
|
||||||
// other geometric types (e.g., PLY).
|
// other geometric types (e.g., PLY).
|
||||||
aiMaterial* pcMat = new aiMaterial();
|
aiMaterial* pcMat = new aiMaterial();
|
||||||
|
@ -231,11 +227,12 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
pScene->mMaterials = new aiMaterial*[1];
|
pScene->mMaterials = new aiMaterial*[1];
|
||||||
pScene->mMaterials[0] = pcMat;
|
pScene->mMaterials[0] = pcMat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Read an ASCII STL file
|
// Read an ASCII STL file
|
||||||
void STLImporter::LoadASCIIFile()
|
void STLImporter::LoadASCIIFile( aiNode *root ) {
|
||||||
{
|
|
||||||
std::vector<aiMesh*> meshes;
|
std::vector<aiMesh*> meshes;
|
||||||
|
std::vector<aiNode*> nodes;
|
||||||
const char* sz = mBuffer;
|
const char* sz = mBuffer;
|
||||||
const char* bufferEnd = mBuffer + fileSize;
|
const char* bufferEnd = mBuffer + fileSize;
|
||||||
std::vector<aiVector3D> positionBuffer;
|
std::vector<aiVector3D> positionBuffer;
|
||||||
|
@ -247,12 +244,15 @@ void STLImporter::LoadASCIIFile()
|
||||||
positionBuffer.reserve(sizeEstimate);
|
positionBuffer.reserve(sizeEstimate);
|
||||||
normalBuffer.reserve(sizeEstimate);
|
normalBuffer.reserve(sizeEstimate);
|
||||||
|
|
||||||
while (IsAsciiSTL(sz, static_cast<unsigned int>(bufferEnd - sz)))
|
while (IsAsciiSTL(sz, static_cast<unsigned int>(bufferEnd - sz))) {
|
||||||
{
|
std::vector<unsigned int> meshIndices;
|
||||||
aiMesh* pMesh = new aiMesh();
|
aiMesh* pMesh = new aiMesh();
|
||||||
pMesh->mMaterialIndex = 0;
|
pMesh->mMaterialIndex = 0;
|
||||||
|
meshIndices.push_back( meshes.size() );
|
||||||
meshes.push_back(pMesh);
|
meshes.push_back(pMesh);
|
||||||
|
aiNode *node = new aiNode;
|
||||||
|
node->mParent = root;
|
||||||
|
nodes.push_back( node );
|
||||||
SkipSpaces(&sz);
|
SkipSpaces(&sz);
|
||||||
ai_assert(!IsLineEnd(sz));
|
ai_assert(!IsLineEnd(sz));
|
||||||
|
|
||||||
|
@ -265,20 +265,21 @@ void STLImporter::LoadASCIIFile()
|
||||||
|
|
||||||
size_t temp;
|
size_t temp;
|
||||||
// setup the name of the node
|
// setup the name of the node
|
||||||
if ((temp = (size_t)(sz-szMe))) {
|
if ((temp = (size_t)(sz-szMe))) {
|
||||||
if (temp >= MAXLEN) {
|
if (temp >= MAXLEN) {
|
||||||
throw DeadlyImportError( "STL: Node name too long" );
|
throw DeadlyImportError( "STL: Node name too long" );
|
||||||
}
|
}
|
||||||
|
std::string name( szMe, temp );
|
||||||
pScene->mRootNode->mName.length = temp;
|
node->mName.Set( name.c_str() );
|
||||||
memcpy(pScene->mRootNode->mName.data,szMe,temp);
|
//pScene->mRootNode->mName.length = temp;
|
||||||
pScene->mRootNode->mName.data[temp] = '\0';
|
//memcpy(pScene->mRootNode->mName.data,szMe,temp);
|
||||||
|
//pScene->mRootNode->mName.data[temp] = '\0';
|
||||||
|
} else {
|
||||||
|
pScene->mRootNode->mName.Set("<STL_ASCII>");
|
||||||
}
|
}
|
||||||
else pScene->mRootNode->mName.Set("<STL_ASCII>");
|
|
||||||
|
|
||||||
unsigned int faceVertexCounter = 3;
|
unsigned int faceVertexCounter = 3;
|
||||||
for ( ;; )
|
for ( ;; ) {
|
||||||
{
|
|
||||||
// go to the next token
|
// go to the next token
|
||||||
if(!SkipSpacesAndLineEnd(&sz))
|
if(!SkipSpacesAndLineEnd(&sz))
|
||||||
{
|
{
|
||||||
|
@ -300,9 +301,7 @@ void STLImporter::LoadASCIIFile()
|
||||||
SkipSpaces(&sz);
|
SkipSpaces(&sz);
|
||||||
if (strncmp(sz,"normal",6)) {
|
if (strncmp(sz,"normal",6)) {
|
||||||
DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
|
DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (sz[6] == '\0') {
|
if (sz[6] == '\0') {
|
||||||
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
|
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
|
||||||
}
|
}
|
||||||
|
@ -316,16 +315,11 @@ void STLImporter::LoadASCIIFile()
|
||||||
normalBuffer.push_back(*vn);
|
normalBuffer.push_back(*vn);
|
||||||
normalBuffer.push_back(*vn);
|
normalBuffer.push_back(*vn);
|
||||||
}
|
}
|
||||||
}
|
} else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6))) { // vertex 1.50000 1.50000 0.00000
|
||||||
// vertex 1.50000 1.50000 0.00000
|
|
||||||
else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6)))
|
|
||||||
{
|
|
||||||
if (faceVertexCounter >= 3) {
|
if (faceVertexCounter >= 3) {
|
||||||
DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
|
DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
|
||||||
++sz;
|
++sz;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (sz[6] == '\0') {
|
if (sz[6] == '\0') {
|
||||||
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
|
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
|
||||||
}
|
}
|
||||||
|
@ -340,17 +334,14 @@ void STLImporter::LoadASCIIFile()
|
||||||
sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->z );
|
sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->z );
|
||||||
faceVertexCounter++;
|
faceVertexCounter++;
|
||||||
}
|
}
|
||||||
}
|
} else if (!::strncmp(sz,"endsolid",8)) {
|
||||||
else if (!::strncmp(sz,"endsolid",8)) {
|
|
||||||
do {
|
do {
|
||||||
++sz;
|
++sz;
|
||||||
} while (!::IsLineEnd(*sz));
|
} while (!::IsLineEnd(*sz));
|
||||||
SkipSpacesAndLineEnd(&sz);
|
SkipSpacesAndLineEnd(&sz);
|
||||||
// finished!
|
// finished!
|
||||||
break;
|
break;
|
||||||
}
|
} else { // else skip the whole identifier
|
||||||
// else skip the whole identifier
|
|
||||||
else {
|
|
||||||
do {
|
do {
|
||||||
++sz;
|
++sz;
|
||||||
} while (!::IsSpaceOrNewLine(*sz));
|
} while (!::IsSpaceOrNewLine(*sz));
|
||||||
|
@ -380,13 +371,22 @@ void STLImporter::LoadASCIIFile()
|
||||||
|
|
||||||
// now copy faces
|
// now copy faces
|
||||||
addFacesToMesh(pMesh);
|
addFacesToMesh(pMesh);
|
||||||
|
|
||||||
|
// assign the meshes to the current node
|
||||||
|
pushMeshesToNode( meshIndices, node );
|
||||||
}
|
}
|
||||||
|
|
||||||
// now add the loaded meshes
|
// now add the loaded meshes
|
||||||
pScene->mNumMeshes = (unsigned int)meshes.size();
|
pScene->mNumMeshes = (unsigned int)meshes.size();
|
||||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||||
for (size_t i = 0; i < meshes.size(); i++)
|
for (size_t i = 0; i < meshes.size(); i++) {
|
||||||
{
|
pScene->mMeshes[ i ] = meshes[i];
|
||||||
pScene->mMeshes[i] = meshes[i];
|
}
|
||||||
|
|
||||||
|
root->mNumChildren = nodes.size();
|
||||||
|
root->mChildren = new aiNode*[ root->mNumChildren ];
|
||||||
|
for ( size_t i=0; i<nodes.size(); ++i ) {
|
||||||
|
root->mChildren[ i ] = nodes[ i ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,4 +513,18 @@ bool STLImporter::LoadBinaryFile()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void STLImporter::pushMeshesToNode( std::vector<unsigned int> &meshIndices, aiNode *node ) {
|
||||||
|
ai_assert( nullptr != node );
|
||||||
|
if ( meshIndices.empty() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->mNumMeshes = static_cast<unsigned int>( meshIndices.size() );
|
||||||
|
node->mMeshes = new unsigned int[ meshIndices.size() ];
|
||||||
|
for ( size_t i=0; i<meshIndices.size(); ++i ) {
|
||||||
|
node->mMeshes[ i ] = meshIndices[ i ];
|
||||||
|
}
|
||||||
|
meshIndices.clear();
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_STL_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_STL_IMPORTER
|
||||||
|
|
|
@ -48,53 +48,61 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include <assimp/types.h>
|
#include <assimp/types.h>
|
||||||
|
|
||||||
namespace Assimp {
|
// Forward declarations
|
||||||
|
struct aiNode;
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Importer class for the sterolithography STL file format
|
/**
|
||||||
*/
|
* @brief Importer class for the sterolithography STL file format.
|
||||||
class STLImporter : public BaseImporter
|
*/
|
||||||
{
|
class STLImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief STLImporter, the class default constructor.
|
||||||
|
*/
|
||||||
STLImporter();
|
STLImporter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The class destructor.
|
||||||
|
*/
|
||||||
~STLImporter();
|
~STLImporter();
|
||||||
|
|
||||||
|
/**
|
||||||
public:
|
* @brief Returns whether the class can handle the format of the given file.
|
||||||
|
* See BaseImporter::CanRead() for details.
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Returns whether the class can handle the format of the given file.
|
|
||||||
* See BaseImporter::CanRead() for details.
|
|
||||||
*/
|
*/
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
||||||
bool checkSig) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
/**
|
||||||
/** Return importer meta information.
|
* @brief Return importer meta information.
|
||||||
* See #BaseImporter::GetInfo for the details
|
* See #BaseImporter::GetInfo for the details
|
||||||
*/
|
*/
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
/**
|
||||||
/** Imports the given file into the given scene structure.
|
* @brief Imports the given file into the given scene structure.
|
||||||
* See BaseImporter::InternReadFile() for details
|
* See BaseImporter::InternReadFile() for details
|
||||||
*/
|
*/
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
/**
|
||||||
// -------------------------------------------------------------------
|
* @brief Loads a binary .stl file
|
||||||
/** Loads a binary .stl file
|
|
||||||
* @return true if the default vertex color must be used as material color
|
* @return true if the default vertex color must be used as material color
|
||||||
*/
|
*/
|
||||||
bool LoadBinaryFile();
|
bool LoadBinaryFile();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
/**
|
||||||
/** Loads a ASCII text .stl file
|
* @brief Loads a ASCII text .stl file
|
||||||
*/
|
*/
|
||||||
void LoadASCIIFile();
|
void LoadASCIIFile( aiNode *root );
|
||||||
|
|
||||||
|
void pushMeshesToNode( std::vector<unsigned int> &meshIndices, aiNode *node );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file Defines a helper class to evaluate subdivision surfaces.*/
|
/** @file Defines a helper class to evaluate subdivision surfaces.*/
|
||||||
|
#pragma once
|
||||||
#ifndef AI_SUBDISIVION_H_INC
|
#ifndef AI_SUBDISIVION_H_INC
|
||||||
#define AI_SUBDISIVION_H_INC
|
#define AI_SUBDISIVION_H_INC
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <assimp/types.h>
|
||||||
|
|
||||||
struct aiMesh;
|
struct aiMesh;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
@ -52,8 +55,7 @@ namespace Assimp {
|
||||||
/** Helper class to evaluate subdivision surfaces. Different algorithms
|
/** Helper class to evaluate subdivision surfaces. Different algorithms
|
||||||
* are provided for choice. */
|
* are provided for choice. */
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
class Subdivider
|
class ASSIMP_API Subdivider {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Enumerates all supported subvidision algorithms */
|
/** Enumerates all supported subvidision algorithms */
|
||||||
|
@ -61,12 +63,7 @@ public:
|
||||||
CATMULL_CLARKE = 0x1
|
CATMULL_CLARKE = 0x1
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
virtual ~Subdivider();
|
||||||
|
|
||||||
virtual ~Subdivider() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
/** Create a subdivider of a specific type
|
/** Create a subdivider of a specific type
|
||||||
|
@ -119,9 +116,13 @@ public:
|
||||||
unsigned int num,
|
unsigned int num,
|
||||||
bool discard_input = false) = 0;
|
bool discard_input = false) = 0;
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
Subdivider::~Subdivider() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace Assimp
|
} // end namespace Assimp
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -141,9 +141,6 @@ void TerragenImporter::InternReadFile( const std::string& pFile,
|
||||||
throw DeadlyImportError( "TER: Magic string \'TERRAIN\' not found" );
|
throw DeadlyImportError( "TER: Magic string \'TERRAIN\' not found" );
|
||||||
|
|
||||||
unsigned int x = 0,y = 0,mode = 0;
|
unsigned int x = 0,y = 0,mode = 0;
|
||||||
float rad = 6370.f;
|
|
||||||
(void)rad;
|
|
||||||
|
|
||||||
|
|
||||||
aiNode* root = pScene->mRootNode = new aiNode();
|
aiNode* root = pScene->mRootNode = new aiNode();
|
||||||
root->mName.Set("<TERRAGEN.TERRAIN>");
|
root->mName.Set("<TERRAGEN.TERRAIN>");
|
||||||
|
@ -187,7 +184,7 @@ void TerragenImporter::InternReadFile( const std::string& pFile,
|
||||||
// mapping == 1: earth radius
|
// mapping == 1: earth radius
|
||||||
else if (!::strncmp(head,AI_TERR_CHUNK_CRAD,4))
|
else if (!::strncmp(head,AI_TERR_CHUNK_CRAD,4))
|
||||||
{
|
{
|
||||||
rad = reader.GetF4();
|
reader.GetF4();
|
||||||
}
|
}
|
||||||
// mapping mode
|
// mapping mode
|
||||||
else if (!::strncmp(head,AI_TERR_CHUNK_CRVM,4))
|
else if (!::strncmp(head,AI_TERR_CHUNK_CRVM,4))
|
||||||
|
|
|
@ -317,7 +317,7 @@ void TextureTransformStep::Execute( aiScene* pScene)
|
||||||
info.lockedPos = AI_TT_UV_IDX_LOCK_TBD;
|
info.lockedPos = AI_TT_UV_IDX_LOCK_TBD;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all coresponding meshes
|
// Get all corresponding meshes
|
||||||
for (unsigned int n = 0; n < pScene->mNumMeshes;++n) {
|
for (unsigned int n = 0; n < pScene->mNumMeshes;++n) {
|
||||||
aiMesh* mesh = pScene->mMeshes[n];
|
aiMesh* mesh = pScene->mMeshes[n];
|
||||||
if (mesh->mMaterialIndex != i || !mesh->mTextureCoords[0])
|
if (mesh->mMaterialIndex != i || !mesh->mTextureCoords[0])
|
||||||
|
|
|
@ -334,28 +334,28 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
|
||||||
case 1:
|
case 1:
|
||||||
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT))
|
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT))
|
||||||
{
|
{
|
||||||
ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimtiveTypes "
|
ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes "
|
||||||
"does not report the POINT flag",i);
|
"does not report the POINT flag",i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_LINE))
|
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_LINE))
|
||||||
{
|
{
|
||||||
ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimtiveTypes "
|
ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimitiveTypes "
|
||||||
"does not report the LINE flag",i);
|
"does not report the LINE flag",i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE))
|
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE))
|
||||||
{
|
{
|
||||||
ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimtiveTypes "
|
ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimitiveTypes "
|
||||||
"does not report the TRIANGLE flag",i);
|
"does not report the TRIANGLE flag",i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON))
|
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON))
|
||||||
{
|
{
|
||||||
this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimtiveTypes "
|
this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimitiveTypes "
|
||||||
"does not report the POLYGON flag",i);
|
"does not report the POLYGON flag",i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -91,7 +91,7 @@ protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Report a validation warning. This won't throw an exception,
|
/** Report a validation warning. This won't throw an exception,
|
||||||
* control will return to the callera.
|
* control will return to the caller.
|
||||||
* @param msg Format string for sprintf().*/
|
* @param msg Format string for sprintf().*/
|
||||||
void ReportWarning(const char* msg,...);
|
void ReportWarning(const char* msg,...);
|
||||||
|
|
||||||
|
|
|
@ -240,8 +240,12 @@ list<SAttribute> attr_list;
|
||||||
if((rotate_angle != 0) && (rotate_axis.Length() > 0))
|
if((rotate_angle != 0) && (rotate_axis.Length() > 0))
|
||||||
attr_list.push_back({"rotation", Rotation2String(rotate_axis, rotate_angle)});
|
attr_list.push_back({"rotation", Rotation2String(rotate_axis, rotate_angle)});
|
||||||
|
|
||||||
if(!scale.Equal({1, 1, 1})) attr_list.push_back({"scale", Vector2String(scale)});
|
if(!scale.Equal({1.0,1.0,1.0})) {
|
||||||
if(translate.Length() > 0) attr_list.push_back({"translation", Vector2String(translate)});
|
attr_list.push_back({"scale", Vector2String(scale)});
|
||||||
|
}
|
||||||
|
if(translate.Length() > 0) {
|
||||||
|
attr_list.push_back({"translation", Vector2String(translate)});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin node if need.
|
// Begin node if need.
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace Assimp
|
||||||
///
|
///
|
||||||
/// Pay attention that X3D is format for interactive graphic and simulations for web browsers. aiScene can not contain all features of the X3D format.
|
/// Pay attention that X3D is format for interactive graphic and simulations for web browsers. aiScene can not contain all features of the X3D format.
|
||||||
/// Also, aiScene contain rasterized-like data. For example, X3D can describe circle all cylinder with one tag, but aiScene contain result of tesselation:
|
/// Also, aiScene contain rasterized-like data. For example, X3D can describe circle all cylinder with one tag, but aiScene contain result of tesselation:
|
||||||
/// vertices, faces etc. Yes, you can use algorithm for detecting figures or shapes, but thats not good idea at all.
|
/// vertices, faces etc. Yes, you can use algorithm for detecting figures or shapes, but that's not a good idea at all.
|
||||||
///
|
///
|
||||||
/// Supported nodes:
|
/// Supported nodes:
|
||||||
/// Core component:
|
/// Core component:
|
||||||
|
@ -96,7 +96,7 @@ private:
|
||||||
aiMatrix4x4 Matrix_GlobalToCurrent(const aiNode& pNode) const;
|
aiMatrix4x4 Matrix_GlobalToCurrent(const aiNode& pNode) const;
|
||||||
|
|
||||||
/// \fn void AttrHelper_CommaToPoint(std::string& pStringWithComma)
|
/// \fn void AttrHelper_CommaToPoint(std::string& pStringWithComma)
|
||||||
/// Convert commas in string to points. Thats need because "std::to_string" result depend on locale (regional settings).
|
/// Convert commas in string to points. That's needed because "std::to_string" result depends on locale (regional settings).
|
||||||
/// \param [in, out] pStringWithComma - reference to string, which must be modified.
|
/// \param [in, out] pStringWithComma - reference to string, which must be modified.
|
||||||
void AttrHelper_CommaToPoint(std::string& pStringWithComma) { for(char& c: pStringWithComma) { if(c == ',') c = '.'; } }
|
void AttrHelper_CommaToPoint(std::string& pStringWithComma) { for(char& c: pStringWithComma) { if(c == ',') c = '.'; } }
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@ namespace Assimp {
|
||||||
/// Ignored attributes: "creaseAngle", "convex", "solid".
|
/// Ignored attributes: "creaseAngle", "convex", "solid".
|
||||||
///
|
///
|
||||||
/// Texture coordinates generating: only for Sphere, Cone, Cylinder. In all other case used PLANE mapping.
|
/// Texture coordinates generating: only for Sphere, Cone, Cylinder. In all other case used PLANE mapping.
|
||||||
/// It's better that Assimp main code has powerfull texture coordinates generator. Then is not needed to
|
/// It's better that Assimp main code has powerful texture coordinates generator. Then is not needed to
|
||||||
/// duplicate this code in every importer.
|
/// duplicate this code in every importer.
|
||||||
///
|
///
|
||||||
/// Lighting limitations.
|
/// Lighting limitations.
|
||||||
|
@ -401,10 +401,10 @@ private:
|
||||||
/************** Functions: XML set *************/
|
/************** Functions: XML set *************/
|
||||||
/***********************************************/
|
/***********************************************/
|
||||||
|
|
||||||
/// Chek if current node is empty: <node />. If not then exception will throwed.
|
/// Check if current node is empty: <node />. If not then exception will throwed.
|
||||||
void XML_CheckNode_MustBeEmpty();
|
void XML_CheckNode_MustBeEmpty();
|
||||||
|
|
||||||
/// Chek if current node name is equal to pNodeName.
|
/// Check if current node name is equal to pNodeName.
|
||||||
/// \param [in] pNodeName - name for checking.
|
/// \param [in] pNodeName - name for checking.
|
||||||
/// return true if current node name is equal to pNodeName, else - false.
|
/// return true if current node name is equal to pNodeName, else - false.
|
||||||
bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
|
bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
|
||||||
|
|
|
@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "X3DImporter.hpp"
|
#include "X3DImporter.hpp"
|
||||||
|
|
||||||
// Header files, Assimp.
|
// Header files, Assimp.
|
||||||
|
#include <assimp/ai_assert.h>
|
||||||
#include "StandardShapes.h"
|
#include "StandardShapes.h"
|
||||||
#include "StringUtils.h"
|
#include "StringUtils.h"
|
||||||
|
|
||||||
|
@ -357,6 +358,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
// copy additional information from children
|
// copy additional information from children
|
||||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||||
{
|
{
|
||||||
|
ai_assert(*pMesh);
|
||||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||||
MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
|
MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
|
||||||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
|
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
|
||||||
|
@ -389,6 +391,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
// copy additional information from children
|
// copy additional information from children
|
||||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||||
{
|
{
|
||||||
|
ai_assert(*pMesh);
|
||||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||||
MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
|
MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
|
||||||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
|
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
|
||||||
|
@ -446,6 +449,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
// copy additional information from children
|
// copy additional information from children
|
||||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||||
{
|
{
|
||||||
|
ai_assert(*pMesh);
|
||||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||||
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, true);
|
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, true);
|
||||||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
|
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
|
||||||
|
@ -475,6 +479,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
// copy additional information from children
|
// copy additional information from children
|
||||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||||
{
|
{
|
||||||
|
ai_assert(*pMesh);
|
||||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||||
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, true);
|
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, true);
|
||||||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
|
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
|
||||||
|
@ -550,6 +555,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
// copy additional information from children
|
// copy additional information from children
|
||||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||||
{
|
{
|
||||||
|
ai_assert(*pMesh);
|
||||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||||
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
|
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
|
||||||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
|
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
|
||||||
|
@ -584,6 +590,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
||||||
// copy additional information from children
|
// copy additional information from children
|
||||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||||
{
|
{
|
||||||
|
ai_assert(*pMesh);
|
||||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||||
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
|
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
|
||||||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
|
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
|
||||||
|
|
|
@ -65,14 +65,11 @@ struct Node;
|
||||||
/** The XFileImporter is a worker class capable of importing a scene from a
|
/** The XFileImporter is a worker class capable of importing a scene from a
|
||||||
* DirectX file .x
|
* DirectX file .x
|
||||||
*/
|
*/
|
||||||
class XFileImporter : public BaseImporter
|
class XFileImporter : public BaseImporter {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
XFileImporter();
|
XFileImporter();
|
||||||
~XFileImporter();
|
~XFileImporter();
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
* See BaseImporter::CanRead() for details. */
|
* See BaseImporter::CanRead() for details. */
|
||||||
|
|
|
@ -360,7 +360,7 @@ inline const char* fast_atoreal_move(const char* c, Real& out, bool check_comma
|
||||||
// The same but more human.
|
// The same but more human.
|
||||||
inline ai_real fast_atof(const char* c)
|
inline ai_real fast_atof(const char* c)
|
||||||
{
|
{
|
||||||
ai_real ret;
|
ai_real ret(0.0);
|
||||||
fast_atoreal_move<ai_real>(c, ret);
|
fast_atoreal_move<ai_real>(c, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ inline ai_real fast_atof(const char* c)
|
||||||
|
|
||||||
inline ai_real fast_atof( const char* c, const char** cout)
|
inline ai_real fast_atof( const char* c, const char** cout)
|
||||||
{
|
{
|
||||||
ai_real ret;
|
ai_real ret(0.0);
|
||||||
*cout = fast_atoreal_move<ai_real>(c, ret);
|
*cout = fast_atoreal_move<ai_real>(c, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -376,7 +376,7 @@ inline ai_real fast_atof( const char* c, const char** cout)
|
||||||
|
|
||||||
inline ai_real fast_atof( const char** inout)
|
inline ai_real fast_atof( const char** inout)
|
||||||
{
|
{
|
||||||
ai_real ret;
|
ai_real ret(0.0);
|
||||||
*inout = fast_atoreal_move<ai_real>(*inout, ret);
|
*inout = fast_atoreal_move<ai_real>(*inout, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -88,6 +88,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "StringUtils.h"
|
||||||
|
|
||||||
namespace glTF2
|
namespace glTF2
|
||||||
{
|
{
|
||||||
#ifdef ASSIMP_API
|
#ifdef ASSIMP_API
|
||||||
|
@ -190,15 +192,31 @@ namespace glTF2
|
||||||
#include "./../include/assimp/Compiler/pushpack1.h"
|
#include "./../include/assimp/Compiler/pushpack1.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//! For binary .glb files
|
||||||
|
//! 12-byte header (+ the JSON + a "body" data section)
|
||||||
|
struct GLB_Header
|
||||||
|
{
|
||||||
|
uint8_t magic[4]; //!< Magic number: "glTF"
|
||||||
|
uint32_t version; //!< Version number (always 2 as of the last update)
|
||||||
|
uint32_t length; //!< Total length of the Binary glTF, including header, scene, and body, in bytes
|
||||||
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
struct GLB_Chunk
|
||||||
|
{
|
||||||
|
uint32_t chunkLength;
|
||||||
|
uint32_t chunkType;
|
||||||
|
} PACK_STRUCT;
|
||||||
|
|
||||||
#ifdef ASSIMP_API
|
#ifdef ASSIMP_API
|
||||||
#include "./../include/assimp/Compiler/poppack1.h"
|
#include "./../include/assimp/Compiler/poppack1.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//! Values for the GLB_Header::sceneFormat field
|
//! Values for the GLB_Chunk::chunkType field
|
||||||
enum SceneFormat
|
enum ChunkType
|
||||||
{
|
{
|
||||||
SceneFormat_JSON = 0
|
ChunkType_JSON = 0x4E4F534A,
|
||||||
|
ChunkType_BIN = 0x004E4942
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Values for the mesh primitive modes
|
//! Values for the mesh primitive modes
|
||||||
|
@ -239,7 +257,7 @@ namespace glTF2
|
||||||
case ComponentType_UNSIGNED_BYTE:
|
case ComponentType_UNSIGNED_BYTE:
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
throw DeadlyImportError("GLTF: Unsupported Component Type " + std::to_string(t));
|
throw DeadlyImportError("GLTF: Unsupported Component Type " + to_string(t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,7 +436,6 @@ namespace glTF2
|
||||||
{
|
{
|
||||||
Ref<BufferView> bufferView; //!< The ID of the bufferView. (required)
|
Ref<BufferView> bufferView; //!< The ID of the bufferView. (required)
|
||||||
unsigned int byteOffset; //!< The offset relative to the start of the bufferView in bytes. (required)
|
unsigned int byteOffset; //!< The offset relative to the start of the bufferView in bytes. (required)
|
||||||
unsigned int byteStride; //!< The stride, in bytes, between attributes referenced by this accessor. (default: 0)
|
|
||||||
ComponentType componentType; //!< The datatype of components in the attribute. (required)
|
ComponentType componentType; //!< The datatype of components in the attribute. (required)
|
||||||
unsigned int count; //!< The number of attributes referenced by this accessor. (required)
|
unsigned int count; //!< The number of attributes referenced by this accessor. (required)
|
||||||
AttribType::Value type; //!< Specifies if the attribute is a scalar, vector, or matrix. (required)
|
AttribType::Value type; //!< Specifies if the attribute is a scalar, vector, or matrix. (required)
|
||||||
|
@ -609,6 +626,7 @@ namespace glTF2
|
||||||
Ref<Buffer> buffer; //! The ID of the buffer. (required)
|
Ref<Buffer> buffer; //! The ID of the buffer. (required)
|
||||||
size_t byteOffset; //! The offset into the buffer in bytes. (required)
|
size_t byteOffset; //! The offset into the buffer in bytes. (required)
|
||||||
size_t byteLength; //! The length of the bufferView in bytes. (default: 0)
|
size_t byteLength; //! The length of the bufferView in bytes. (default: 0)
|
||||||
|
unsigned int byteStride; //!< The stride, in bytes, between attributes referenced by this accessor. (default: 0)
|
||||||
|
|
||||||
BufferViewTarget target; //! The target that the WebGL buffer should be bound to.
|
BufferViewTarget target; //! The target that the WebGL buffer should be bound to.
|
||||||
|
|
||||||
|
@ -971,6 +989,8 @@ namespace glTF2
|
||||||
Ref<T> Create(const std::string& id)
|
Ref<T> Create(const std::string& id)
|
||||||
{ return Create(id.c_str()); }
|
{ return Create(id.c_str()); }
|
||||||
|
|
||||||
|
unsigned int Remove(const char* id);
|
||||||
|
|
||||||
inline unsigned int Size() const
|
inline unsigned int Size() const
|
||||||
{ return unsigned(mObjs.size()); }
|
{ return unsigned(mObjs.size()); }
|
||||||
|
|
||||||
|
@ -1082,7 +1102,10 @@ namespace glTF2
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Main function
|
//! Main function
|
||||||
void Load(const std::string& file);
|
void Load(const std::string& file, bool isBinary = false);
|
||||||
|
|
||||||
|
//! Enables binary encoding on the asset
|
||||||
|
void SetAsBinary();
|
||||||
|
|
||||||
//! Search for an available name, starting from the given strings
|
//! Search for an available name, starting from the given strings
|
||||||
std::string FindUniqueID(const std::string& str, const char* suffix);
|
std::string FindUniqueID(const std::string& str, const char* suffix);
|
||||||
|
@ -1091,6 +1114,8 @@ namespace glTF2
|
||||||
{ return mBodyBuffer; }
|
{ return mBodyBuffer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void ReadBinaryHeader(IOStream& stream, std::vector<char>& sceneData);
|
||||||
|
|
||||||
void ReadExtensionsUsed(Document& doc);
|
void ReadExtensionsUsed(Document& doc);
|
||||||
|
|
||||||
IOStream* OpenFile(std::string path, const char* mode, bool absolute = false);
|
IOStream* OpenFile(std::string path, const char* mode, bool absolute = false);
|
||||||
|
|
|
@ -193,6 +193,50 @@ inline void LazyDict<T>::DetachFromDocument()
|
||||||
mDict = 0;
|
mDict = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
unsigned int LazyDict<T>::Remove(const char* id)
|
||||||
|
{
|
||||||
|
id = T::TranslateId(mAsset, id);
|
||||||
|
|
||||||
|
typename IdDict::iterator it = mObjsById.find(id);
|
||||||
|
|
||||||
|
if (it == mObjsById.end()) {
|
||||||
|
throw DeadlyExportError("GLTF: Object with id \"" + std::string(id) + "\" is not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned int index = it->second;
|
||||||
|
|
||||||
|
mAsset.mUsedIds[id] = false;
|
||||||
|
mObjsById.erase(id);
|
||||||
|
mObjsByOIndex.erase(index);
|
||||||
|
mObjs.erase(mObjs.begin() + index);
|
||||||
|
|
||||||
|
//update index of object in mObjs;
|
||||||
|
for (size_t i = index; i < mObjs.size(); ++i) {
|
||||||
|
T *obj = mObjs[i];
|
||||||
|
|
||||||
|
obj->index = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IdDict::iterator it = mObjsById.begin(); it != mObjsById.end(); ++it) {
|
||||||
|
if (it->second <= index) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mObjsById[it->first] = it->second - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Dict::iterator it = mObjsByOIndex.begin(); it != mObjsByOIndex.end(); ++it) {
|
||||||
|
if (it->second <= index) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mObjsByOIndex[it->first] = it->second - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Ref<T> LazyDict<T>::Retrieve(unsigned int i)
|
Ref<T> LazyDict<T>::Retrieve(unsigned int i)
|
||||||
{
|
{
|
||||||
|
@ -214,11 +258,11 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i)
|
||||||
Value &obj = (*mDict)[i];
|
Value &obj = (*mDict)[i];
|
||||||
|
|
||||||
if (!obj.IsObject()) {
|
if (!obj.IsObject()) {
|
||||||
throw DeadlyImportError("GLTF: Object at index \"" + std::to_string(i) + "\" is not a JSON object");
|
throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" is not a JSON object");
|
||||||
}
|
}
|
||||||
|
|
||||||
T* inst = new T();
|
T* inst = new T();
|
||||||
inst->id = std::string(mDictId) + "_" + std::to_string(i);
|
inst->id = std::string(mDictId) + "_" + to_string(i);
|
||||||
inst->oIndex = i;
|
inst->oIndex = i;
|
||||||
ReadMember(obj, "name", inst->name);
|
ReadMember(obj, "name", inst->name);
|
||||||
inst->Read(obj, mAsset);
|
inst->Read(obj, mAsset);
|
||||||
|
@ -468,6 +512,7 @@ inline void BufferView::Read(Value& obj, Asset& r)
|
||||||
|
|
||||||
byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
|
byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
|
||||||
byteLength = MemberOrDefault(obj, "byteLength", 0u);
|
byteLength = MemberOrDefault(obj, "byteLength", 0u);
|
||||||
|
byteStride = MemberOrDefault(obj, "byteStride", 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -482,7 +527,6 @@ inline void Accessor::Read(Value& obj, Asset& r)
|
||||||
}
|
}
|
||||||
|
|
||||||
byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
|
byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
|
||||||
byteStride = MemberOrDefault(obj, "byteStride", 0u);
|
|
||||||
componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
|
componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
|
||||||
count = MemberOrDefault(obj, "count", 0u);
|
count = MemberOrDefault(obj, "count", 0u);
|
||||||
|
|
||||||
|
@ -557,7 +601,7 @@ bool Accessor::ExtractData(T*& outData)
|
||||||
const size_t elemSize = GetElementSize();
|
const size_t elemSize = GetElementSize();
|
||||||
const size_t totalSize = elemSize * count;
|
const size_t totalSize = elemSize * count;
|
||||||
|
|
||||||
const size_t stride = byteStride ? byteStride : elemSize;
|
const size_t stride = bufferView && bufferView->byteStride ? bufferView->byteStride : elemSize;
|
||||||
|
|
||||||
const size_t targetElemSize = sizeof(T);
|
const size_t targetElemSize = sizeof(T);
|
||||||
ai_assert(elemSize <= targetElemSize);
|
ai_assert(elemSize <= targetElemSize);
|
||||||
|
@ -597,7 +641,7 @@ inline Accessor::Indexer::Indexer(Accessor& acc)
|
||||||
: accessor(acc)
|
: accessor(acc)
|
||||||
, data(acc.GetPointer())
|
, data(acc.GetPointer())
|
||||||
, elemSize(acc.GetElementSize())
|
, elemSize(acc.GetElementSize())
|
||||||
, stride(acc.byteStride ? acc.byteStride : elemSize)
|
, stride(acc.bufferView && acc.bufferView->byteStride ? acc.bufferView->byteStride : elemSize)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -993,7 +1037,72 @@ inline void AssetMetadata::Read(Document& doc)
|
||||||
// Asset methods implementation
|
// Asset methods implementation
|
||||||
//
|
//
|
||||||
|
|
||||||
inline void Asset::Load(const std::string& pFile)
|
inline void Asset::ReadBinaryHeader(IOStream& stream, std::vector<char>& sceneData)
|
||||||
|
{
|
||||||
|
GLB_Header header;
|
||||||
|
if (stream.Read(&header, sizeof(header), 1) != 1) {
|
||||||
|
throw DeadlyImportError("GLTF: Unable to read the file header");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp((char*)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) {
|
||||||
|
throw DeadlyImportError("GLTF: Invalid binary glTF file");
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_SWAP4(header.version);
|
||||||
|
asset.version = to_string(header.version);
|
||||||
|
if (header.version != 2) {
|
||||||
|
throw DeadlyImportError("GLTF: Unsupported binary glTF version");
|
||||||
|
}
|
||||||
|
|
||||||
|
GLB_Chunk chunk;
|
||||||
|
if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
|
||||||
|
throw DeadlyImportError("GLTF: Unable to read JSON chunk");
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_SWAP4(chunk.chunkLength);
|
||||||
|
AI_SWAP4(chunk.chunkType);
|
||||||
|
|
||||||
|
if (chunk.chunkType != ChunkType_JSON) {
|
||||||
|
throw DeadlyImportError("GLTF: JSON chunk missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the scene data
|
||||||
|
|
||||||
|
mSceneLength = chunk.chunkLength;
|
||||||
|
sceneData.resize(mSceneLength + 1);
|
||||||
|
sceneData[mSceneLength] = '\0';
|
||||||
|
|
||||||
|
if (stream.Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
|
||||||
|
throw DeadlyImportError("GLTF: Could not read the file contents");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t padding = ((chunk.chunkLength + 3) & ~3) - chunk.chunkLength;
|
||||||
|
if (padding > 0) {
|
||||||
|
stream.Seek(padding, aiOrigin_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_SWAP4(header.length);
|
||||||
|
mBodyOffset = 12 + 8 + chunk.chunkLength + padding + 8;
|
||||||
|
if (header.length >= mBodyOffset) {
|
||||||
|
if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
|
||||||
|
throw DeadlyImportError("GLTF: Unable to read BIN chunk");
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_SWAP4(chunk.chunkLength);
|
||||||
|
AI_SWAP4(chunk.chunkType);
|
||||||
|
|
||||||
|
if (chunk.chunkType != ChunkType_BIN) {
|
||||||
|
throw DeadlyImportError("GLTF: BIN chunk missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
mBodyLength = chunk.chunkLength;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mBodyOffset = mBodyLength = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Asset::Load(const std::string& pFile, bool isBinary)
|
||||||
{
|
{
|
||||||
mCurrentAssetDir.clear();
|
mCurrentAssetDir.clear();
|
||||||
int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
|
int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
|
||||||
|
@ -1004,16 +1113,25 @@ inline void Asset::Load(const std::string& pFile)
|
||||||
throw DeadlyImportError("GLTF: Could not open file for reading");
|
throw DeadlyImportError("GLTF: Could not open file for reading");
|
||||||
}
|
}
|
||||||
|
|
||||||
mSceneLength = stream->FileSize();
|
// is binary? then read the header
|
||||||
mBodyLength = 0;
|
std::vector<char> sceneData;
|
||||||
|
if (isBinary) {
|
||||||
|
SetAsBinary(); // also creates the body buffer
|
||||||
|
ReadBinaryHeader(*stream, sceneData);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mSceneLength = stream->FileSize();
|
||||||
|
mBodyLength = 0;
|
||||||
|
|
||||||
// read the scene data
|
|
||||||
|
|
||||||
std::vector<char> sceneData(mSceneLength + 1);
|
// read the scene data
|
||||||
sceneData[mSceneLength] = '\0';
|
|
||||||
|
|
||||||
if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
|
sceneData.resize(mSceneLength + 1);
|
||||||
throw DeadlyImportError("GLTF: Could not read the file contents");
|
sceneData[mSceneLength] = '\0';
|
||||||
|
|
||||||
|
if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
|
||||||
|
throw DeadlyImportError("GLTF: Could not read the file contents");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1066,6 +1184,15 @@ inline void Asset::Load(const std::string& pFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Asset::SetAsBinary()
|
||||||
|
{
|
||||||
|
if (!mBodyBuffer) {
|
||||||
|
mBodyBuffer = buffers.Create("binary_glTF");
|
||||||
|
mBodyBuffer->MarkAsSpecial();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Asset::ReadExtensionsUsed(Document& doc)
|
inline void Asset::ReadExtensionsUsed(Document& doc)
|
||||||
{
|
{
|
||||||
Value* extsUsed = FindArray(doc, "extensionsUsed");
|
Value* extsUsed = FindArray(doc, "extensionsUsed");
|
||||||
|
|
|
@ -98,10 +98,6 @@ namespace glTF2 {
|
||||||
obj.AddMember("bufferView", a.bufferView->index, w.mAl);
|
obj.AddMember("bufferView", a.bufferView->index, w.mAl);
|
||||||
obj.AddMember("byteOffset", a.byteOffset, w.mAl);
|
obj.AddMember("byteOffset", a.byteOffset, w.mAl);
|
||||||
|
|
||||||
if (a.byteStride != 0) {
|
|
||||||
obj.AddMember("byteStride", a.byteStride, w.mAl);
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.AddMember("componentType", int(a.componentType), w.mAl);
|
obj.AddMember("componentType", int(a.componentType), w.mAl);
|
||||||
obj.AddMember("count", a.count, w.mAl);
|
obj.AddMember("count", a.count, w.mAl);
|
||||||
obj.AddMember("type", StringRef(AttribType::ToString(a.type)), w.mAl);
|
obj.AddMember("type", StringRef(AttribType::ToString(a.type)), w.mAl);
|
||||||
|
@ -168,6 +164,9 @@ namespace glTF2 {
|
||||||
obj.AddMember("buffer", bv.buffer->index, w.mAl);
|
obj.AddMember("buffer", bv.buffer->index, w.mAl);
|
||||||
obj.AddMember("byteOffset", static_cast<uint64_t>(bv.byteOffset), w.mAl);
|
obj.AddMember("byteOffset", static_cast<uint64_t>(bv.byteOffset), w.mAl);
|
||||||
obj.AddMember("byteLength", static_cast<uint64_t>(bv.byteLength), w.mAl);
|
obj.AddMember("byteLength", static_cast<uint64_t>(bv.byteLength), w.mAl);
|
||||||
|
if (bv.byteStride != 0) {
|
||||||
|
obj.AddMember("byteStride", bv.byteStride, w.mAl);
|
||||||
|
}
|
||||||
obj.AddMember("target", int(bv.target), w.mAl);
|
obj.AddMember("target", int(bv.target), w.mAl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/material.h>
|
#include <assimp/material.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
// Header files, standart library.
|
// Header files, standard library.
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
@ -170,13 +170,13 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
|
||||||
bv->buffer = buffer;
|
bv->buffer = buffer;
|
||||||
bv->byteOffset = unsigned(offset);
|
bv->byteOffset = unsigned(offset);
|
||||||
bv->byteLength = length; //! The target that the WebGL buffer should be bound to.
|
bv->byteLength = length; //! The target that the WebGL buffer should be bound to.
|
||||||
|
bv->byteStride = 0;
|
||||||
bv->target = isIndices ? BufferViewTarget_ELEMENT_ARRAY_BUFFER : BufferViewTarget_ARRAY_BUFFER;
|
bv->target = isIndices ? BufferViewTarget_ELEMENT_ARRAY_BUFFER : BufferViewTarget_ARRAY_BUFFER;
|
||||||
|
|
||||||
// accessor
|
// accessor
|
||||||
Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor"));
|
Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor"));
|
||||||
acc->bufferView = bv;
|
acc->bufferView = bv;
|
||||||
acc->byteOffset = 0;
|
acc->byteOffset = 0;
|
||||||
acc->byteStride = 0;
|
|
||||||
acc->componentType = compType;
|
acc->componentType = compType;
|
||||||
acc->count = count;
|
acc->count = count;
|
||||||
acc->type = typeOut;
|
acc->type = typeOut;
|
||||||
|
@ -402,7 +402,7 @@ void glTF2Exporter::ExportMaterials()
|
||||||
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
|
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
|
||||||
const aiMaterial* mat = mScene->mMaterials[i];
|
const aiMaterial* mat = mScene->mMaterials[i];
|
||||||
|
|
||||||
std::string id = "material_" + std::to_string(i);
|
std::string id = "material_" + to_string(i);
|
||||||
|
|
||||||
Ref<Material> m = mAsset->materials.Create(id);
|
Ref<Material> m = mAsset->materials.Create(id);
|
||||||
|
|
||||||
|
@ -800,9 +800,33 @@ void glTF2Exporter::MergeMeshes()
|
||||||
for (unsigned int m = nMeshes - 1; m >= 1; --m) {
|
for (unsigned int m = nMeshes - 1; m >= 1; --m) {
|
||||||
Ref<Mesh> mesh = node->meshes.at(m);
|
Ref<Mesh> mesh = node->meshes.at(m);
|
||||||
|
|
||||||
firstMesh->primitives.insert(firstMesh->primitives.end(), mesh->primitives.begin(), mesh->primitives.end());
|
//append this mesh's primitives to the first mesh's primitives
|
||||||
|
firstMesh->primitives.insert(
|
||||||
|
firstMesh->primitives.end(),
|
||||||
|
mesh->primitives.begin(),
|
||||||
|
mesh->primitives.end()
|
||||||
|
);
|
||||||
|
|
||||||
node->meshes.erase(node->meshes.begin() + m);
|
//remove the mesh from the list of meshes
|
||||||
|
unsigned int removedIndex = mAsset->meshes.Remove(mesh->id.c_str());
|
||||||
|
|
||||||
|
//find the presence of the removed mesh in other nodes
|
||||||
|
for (unsigned int nn = 0; nn < mAsset->nodes.Size(); ++nn) {
|
||||||
|
Ref<Node> node = mAsset->nodes.Get(nn);
|
||||||
|
|
||||||
|
for (unsigned int mm = 0; mm < node->meshes.size(); ++mm) {
|
||||||
|
Ref<Mesh>& meshRef = node->meshes.at(mm);
|
||||||
|
unsigned int meshIndex = meshRef.GetIndex();
|
||||||
|
|
||||||
|
if (meshIndex == removedIndex) {
|
||||||
|
node->meshes.erase(node->meshes.begin() + mm);
|
||||||
|
} else if (meshIndex > removedIndex) {
|
||||||
|
Ref<Mesh> newMeshRef = mAsset->meshes.Get(meshIndex - 1);
|
||||||
|
|
||||||
|
meshRef = newMeshRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//since we were looping backwards, reverse the order of merged primitives to their original order
|
//since we were looping backwards, reverse the order of merged primitives to their original order
|
||||||
|
|
|
@ -74,7 +74,7 @@ static const aiImporterDesc desc = {
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
|
aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -103,13 +103,13 @@ bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
|
||||||
{
|
{
|
||||||
const std::string &extension = GetExtension(pFile);
|
const std::string &extension = GetExtension(pFile);
|
||||||
|
|
||||||
if (extension != "gltf") // We currently can't read glTF2 binary files (.glb), yet
|
if (extension != "gltf" && extension != "glb")
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (checkSig && pIOHandler) {
|
if (checkSig && pIOHandler) {
|
||||||
glTF2::Asset asset(pIOHandler);
|
glTF2::Asset asset(pIOHandler);
|
||||||
try {
|
try {
|
||||||
asset.Load(pFile);
|
asset.Load(pFile, extension == "glb");
|
||||||
std::string version = asset.asset.version;
|
std::string version = asset.asset.version;
|
||||||
return !version.empty() && version[0] == '2';
|
return !version.empty() && version[0] == '2';
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
@ -639,7 +639,7 @@ void glTF2Importer::InternReadFile(const std::string& pFile, aiScene* pScene, IO
|
||||||
|
|
||||||
// read the asset file
|
// read the asset file
|
||||||
glTF2::Asset asset(pIOHandler);
|
glTF2::Asset asset(pIOHandler);
|
||||||
asset.Load(pFile);
|
asset.Load(pFile, GetExtension(pFile) == "glb");
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copy the data out
|
// Copy the data out
|
||||||
|
|
|
@ -1282,7 +1282,7 @@ inline void Asset::ReadBinaryHeader(IOStream& stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
AI_SWAP4(header.version);
|
AI_SWAP4(header.version);
|
||||||
asset.version = std::to_string(header.version);
|
asset.version = to_string(header.version);
|
||||||
if (header.version != 1) {
|
if (header.version != 1) {
|
||||||
throw DeadlyImportError("GLTF: Unsupported binary glTF version");
|
throw DeadlyImportError("GLTF: Unsupported binary glTF version");
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/material.h>
|
#include <assimp/material.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
// Header files, standart library.
|
// Header files, standard library.
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
|
|
@ -820,6 +820,7 @@ namespace o3dgc
|
||||||
for (unsigned n = 0; n < data_symbols; n++)
|
for (unsigned n = 0; n < data_symbols; n++)
|
||||||
total_count += (symbol_count[n] = (symbol_count[n] + 1) >> 1);
|
total_count += (symbol_count[n] = (symbol_count[n] + 1) >> 1);
|
||||||
}
|
}
|
||||||
|
assert(total_count > 0);
|
||||||
// compute cumulative distribution, decoder table
|
// compute cumulative distribution, decoder table
|
||||||
unsigned k, sum = 0, s = 0;
|
unsigned k, sum = 0, s = 0;
|
||||||
unsigned scale = 0x80000000U / total_count;
|
unsigned scale = 0x80000000U / total_count;
|
||||||
|
@ -830,6 +831,7 @@ namespace o3dgc
|
||||||
sum += symbol_count[k];
|
sum += symbol_count[k];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
assert(decoder_table);
|
||||||
for (k = 0; k < data_symbols; k++) {
|
for (k = 0; k < data_symbols; k++) {
|
||||||
distribution[k] = (scale * sum) >> (31 - DM__LengthShift);
|
distribution[k] = (scale * sum) >> (31 - DM__LengthShift);
|
||||||
sum += symbol_count[k];
|
sum += symbol_count[k];
|
||||||
|
|
|
@ -231,7 +231,8 @@ namespace o3dgc
|
||||||
float ReadFloat32Bin(unsigned long & position) const
|
float ReadFloat32Bin(unsigned long & position) const
|
||||||
{
|
{
|
||||||
unsigned long value = ReadUInt32Bin(position);
|
unsigned long value = ReadUInt32Bin(position);
|
||||||
float fvalue = *((float *)(&value));
|
float fvalue;
|
||||||
|
memcpy(&fvalue, &value, 4);
|
||||||
return fvalue;
|
return fvalue;
|
||||||
}
|
}
|
||||||
unsigned long ReadUInt32Bin(unsigned long & position) const
|
unsigned long ReadUInt32Bin(unsigned long & position) const
|
||||||
|
@ -261,7 +262,8 @@ namespace o3dgc
|
||||||
|
|
||||||
void WriteFloat32ASCII(float value)
|
void WriteFloat32ASCII(float value)
|
||||||
{
|
{
|
||||||
unsigned long uiValue = *((unsigned long *)(&value));
|
unsigned long uiValue;
|
||||||
|
memcpy(&uiValue, &value, 4);
|
||||||
WriteUInt32ASCII(uiValue);
|
WriteUInt32ASCII(uiValue);
|
||||||
}
|
}
|
||||||
void WriteUInt32ASCII(unsigned long position, unsigned long value)
|
void WriteUInt32ASCII(unsigned long position, unsigned long value)
|
||||||
|
@ -314,7 +316,8 @@ namespace o3dgc
|
||||||
float ReadFloat32ASCII(unsigned long & position) const
|
float ReadFloat32ASCII(unsigned long & position) const
|
||||||
{
|
{
|
||||||
unsigned long value = ReadUInt32ASCII(position);
|
unsigned long value = ReadUInt32ASCII(position);
|
||||||
float fvalue = *((float *)(&value));
|
float fvalue;
|
||||||
|
memcpy(&fvalue, &value, 4);
|
||||||
return fvalue;
|
return fvalue;
|
||||||
}
|
}
|
||||||
unsigned long ReadUInt32ASCII(unsigned long & position) const
|
unsigned long ReadUInt32ASCII(unsigned long & position) const
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
# Copyright (c) 2014, Pavel Rojtberg
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# 2. 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.
|
||||||
|
#
|
||||||
|
# 3. Neither the name of the copyright holder nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from this
|
||||||
|
# software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# 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 HOLDER 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.
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Usage:
|
||||||
|
# 1. place AndroidNdkGdb.cmake somewhere inside ${CMAKE_MODULE_PATH}
|
||||||
|
# 2. inside your project add
|
||||||
|
#
|
||||||
|
# include(AndroidNdkGdb)
|
||||||
|
# android_ndk_gdb_enable()
|
||||||
|
# # for each target
|
||||||
|
# add_library(MyLibrary ...)
|
||||||
|
# android_ndk_gdb_debuggable(MyLibrary)
|
||||||
|
|
||||||
|
|
||||||
|
# add gdbserver and general gdb configuration to project
|
||||||
|
# also create a mininal NDK skeleton so ndk-gdb finds the paths
|
||||||
|
#
|
||||||
|
# the optional parameter defines the path to the android project.
|
||||||
|
# uses PROJECT_SOURCE_DIR by default.
|
||||||
|
macro(android_ndk_gdb_enable)
|
||||||
|
if(ANDROID)
|
||||||
|
# create custom target that depends on the real target so it gets executed afterwards
|
||||||
|
add_custom_target(NDK_GDB ALL)
|
||||||
|
|
||||||
|
if(${ARGC})
|
||||||
|
set(ANDROID_PROJECT_DIR ${ARGV0})
|
||||||
|
else()
|
||||||
|
set(ANDROID_PROJECT_DIR ${PROJECT_SOURCE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(NDK_GDB_SOLIB_PATH ${ANDROID_PROJECT_DIR}/obj/local/${ANDROID_NDK_ABI_NAME}/)
|
||||||
|
file(MAKE_DIRECTORY ${NDK_GDB_SOLIB_PATH})
|
||||||
|
|
||||||
|
# 1. generate essential Android Makefiles
|
||||||
|
file(MAKE_DIRECTORY ${ANDROID_PROJECT_DIR}/jni)
|
||||||
|
if(NOT EXISTS ${ANDROID_PROJECT_DIR}/jni/Android.mk)
|
||||||
|
file(WRITE ${ANDROID_PROJECT_DIR}/jni/Android.mk "APP_ABI := ${ANDROID_NDK_ABI_NAME}\n")
|
||||||
|
endif()
|
||||||
|
if(NOT EXISTS ${ANDROID_PROJECT_DIR}/jni/Application.mk)
|
||||||
|
file(WRITE ${ANDROID_PROJECT_DIR}/jni/Application.mk "APP_ABI := ${ANDROID_NDK_ABI_NAME}\n")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# 2. generate gdb.setup
|
||||||
|
get_directory_property(PROJECT_INCLUDES DIRECTORY ${PROJECT_SOURCE_DIR} INCLUDE_DIRECTORIES)
|
||||||
|
string(REGEX REPLACE ";" " " PROJECT_INCLUDES "${PROJECT_INCLUDES}")
|
||||||
|
file(WRITE ${LIBRARY_OUTPUT_PATH}/gdb.setup "set solib-search-path ${NDK_GDB_SOLIB_PATH}\n")
|
||||||
|
file(APPEND ${LIBRARY_OUTPUT_PATH}/gdb.setup "directory ${PROJECT_INCLUDES}\n")
|
||||||
|
|
||||||
|
# 3. copy gdbserver executable
|
||||||
|
file(COPY ${ANDROID_NDK}/prebuilt/android-${ANDROID_ARCH_NAME}/gdbserver/gdbserver DESTINATION ${LIBRARY_OUTPUT_PATH})
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# register a target for remote debugging
|
||||||
|
# copies the debug version to NDK_GDB_SOLIB_PATH then strips symbols of original
|
||||||
|
macro(android_ndk_gdb_debuggable TARGET_NAME)
|
||||||
|
if(ANDROID)
|
||||||
|
get_property(TARGET_LOCATION TARGET ${TARGET_NAME} PROPERTY LOCATION)
|
||||||
|
|
||||||
|
# create custom target that depends on the real target so it gets executed afterwards
|
||||||
|
add_dependencies(NDK_GDB ${TARGET_NAME})
|
||||||
|
|
||||||
|
# 4. copy lib to obj
|
||||||
|
add_custom_command(TARGET NDK_GDB POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${TARGET_LOCATION} ${NDK_GDB_SOLIB_PATH})
|
||||||
|
|
||||||
|
# 5. strip symbols
|
||||||
|
add_custom_command(TARGET NDK_GDB POST_BUILD COMMAND ${CMAKE_STRIP} ${TARGET_LOCATION})
|
||||||
|
endif()
|
||||||
|
endmacro()
|
|
@ -0,0 +1,58 @@
|
||||||
|
# Copyright (c) 2014, Pavel Rojtberg
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# 2. 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.
|
||||||
|
#
|
||||||
|
# 3. Neither the name of the copyright holder nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from this
|
||||||
|
# software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# 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 HOLDER 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.
|
||||||
|
|
||||||
|
macro(android_ndk_import_module_cpufeatures)
|
||||||
|
if(ANDROID)
|
||||||
|
include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
|
||||||
|
add_library(cpufeatures ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
|
||||||
|
target_link_libraries(cpufeatures dl)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(android_ndk_import_module_native_app_glue)
|
||||||
|
if(ANDROID)
|
||||||
|
include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
|
||||||
|
add_library(native_app_glue ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
|
||||||
|
target_link_libraries(native_app_glue log)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(android_ndk_import_module_ndk_helper)
|
||||||
|
if(ANDROID)
|
||||||
|
android_ndk_import_module_cpufeatures()
|
||||||
|
android_ndk_import_module_native_app_glue()
|
||||||
|
|
||||||
|
include_directories(${ANDROID_NDK}/sources/android/ndk_helper)
|
||||||
|
file(GLOB _NDK_HELPER_SRCS ${ANDROID_NDK}/sources/android/ndk_helper/*.cpp ${ANDROID_NDK}/sources/android/ndk_helper/gl3stub.c)
|
||||||
|
add_library(ndk_helper ${_NDK_HELPER_SRCS})
|
||||||
|
target_link_libraries(ndk_helper log android EGL GLESv2 cpufeatures native_app_glue)
|
||||||
|
|
||||||
|
unset(_NDK_HELPER_SRCS)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
|
@ -0,0 +1,240 @@
|
||||||
|
# android-cmake
|
||||||
|
|
||||||
|
CMake is great, and so is Android. This is a collection of CMake scripts that may be useful to the Android NDK community. It is based on experience from porting OpenCV library to Android: http://opencv.org/platforms/android.html
|
||||||
|
|
||||||
|
Main goal is to share these scripts so that devs that use CMake as their build system may easily compile native code for Android.
|
||||||
|
|
||||||
|
## TL;DR
|
||||||
|
|
||||||
|
cmake -DCMAKE_TOOLCHAIN_FILE=android.toolchain.cmake \
|
||||||
|
-DANDROID_NDK=<ndk_path> \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DANDROID_ABI="armeabi-v7a with NEON" \
|
||||||
|
<source_path>
|
||||||
|
cmake --build .
|
||||||
|
|
||||||
|
One-liner:
|
||||||
|
|
||||||
|
cmake -DCMAKE_TOOLCHAIN_FILE=android.toolchain.cmake -DANDROID_NDK=<ndk_path> -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="armeabi-v7a with NEON" <source_path> && cmake --build .
|
||||||
|
|
||||||
|
_android-cmake_ will search for your NDK install in the following order:
|
||||||
|
|
||||||
|
1. Value of `ANDROID_NDK` CMake variable;
|
||||||
|
1. Value of `ANDROID_NDK` environment variable;
|
||||||
|
1. Search under paths from `ANDROID_NDK_SEARCH_PATHS` CMake variable;
|
||||||
|
1. Search platform specific locations (home folder, Windows "Program Files", etc).
|
||||||
|
|
||||||
|
So if you have installed the NDK as `~/android-ndk-r10d` then _android-cmake_ will locate it automatically.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
To build a cmake-based C/C++ project for Android you need:
|
||||||
|
|
||||||
|
* Android NDK (>= r5) http://developer.android.com/tools/sdk/ndk/index.html
|
||||||
|
* CMake (>= v2.6.3, >= v2.8.9 recommended) http://www.cmake.org/download
|
||||||
|
|
||||||
|
The _android-cmake_ is also capable to build with NDK from AOSP or Linaro Android source tree, but you may be required to manually specify path to `libm` binary to link with.
|
||||||
|
|
||||||
|
## Difference from traditional CMake
|
||||||
|
|
||||||
|
Folowing the _ndk-build_ the _android-cmake_ supports **only two build targets**:
|
||||||
|
|
||||||
|
* `-DCMAKE_BUILD_TYPE=Release`
|
||||||
|
* `-DCMAKE_BUILD_TYPE=Debug`
|
||||||
|
|
||||||
|
So don't even try other targets that can be found in CMake documentation and don't forget to explicitly specify `Release` or `Debug` because CMake builds without a build configuration by default.
|
||||||
|
|
||||||
|
## Difference from _ndk-build_
|
||||||
|
|
||||||
|
* Latest GCC available in NDK is used as the default compiler;
|
||||||
|
* `Release` builds with `-O3` instead of `-Os`;
|
||||||
|
* `Release` builds without debug info (without `-g`) (because _ndk-build_ always creates a stripped version but cmake delays this for `install/strip` target);
|
||||||
|
* `-fsigned-char` is added to compiler flags to make `char` signed by default as it is on x86/x86_64;
|
||||||
|
* GCC's stack protector is not used neither in `Debug` nor `Release` configurations;
|
||||||
|
* No builds for multiple platforms (e.g. building for both arm and x86 require to run cmake twice with different parameters);
|
||||||
|
* No file level Neon via `.neon` suffix;
|
||||||
|
|
||||||
|
The following features of _ndk-build_ are not supported by the _android-cmake_ yet:
|
||||||
|
|
||||||
|
* `armeabi-v7a-hard` ABI
|
||||||
|
* `libc++_static`/`libc++_shared` STL runtime
|
||||||
|
|
||||||
|
## Basic options
|
||||||
|
|
||||||
|
Similarly to the NDK build system _android-cmake_ allows to select between several compiler toolchains and target platforms. Most of the options can be set either as cmake arguments: `-D<NAME>=<VALUE>` or as environment variables:
|
||||||
|
|
||||||
|
* **ANDROID_NDK** - path to the Android NDK. If not set then _android-cmake_ will search for the most recent version of supported NDK in commonly used locations;
|
||||||
|
* **ANDROID_ABI** - specifies the target Application Binary Interface (ABI). This option nearly matches to the APP_ABI variable used by ndk-build tool from Android NDK. If not specified then set to `armeabi-v7a`. Possible target names are:
|
||||||
|
* `armeabi` - ARMv5TE based CPU with software floating point operations;
|
||||||
|
* **`armeabi-v7a`** - ARMv7 based devices with hardware FPU instructions (VFPv3_D16);
|
||||||
|
* `armeabi-v7a with NEON` - same as armeabi-v7a, but sets NEON as floating-point unit;
|
||||||
|
* `armeabi-v7a with VFPV3` - same as armeabi-v7a, but sets VFPv3_D32 as floating-point unit;
|
||||||
|
* `armeabi-v6 with VFP` - tuned for ARMv6 processors having VFP;
|
||||||
|
* `x86` - IA-32 instruction set
|
||||||
|
* `mips` - MIPS32 instruction set
|
||||||
|
* `arm64-v8a` - ARMv8 AArch64 instruction set - only for NDK r10 and newer
|
||||||
|
* `x86_64` - Intel64 instruction set (r1) - only for NDK r10 and newer
|
||||||
|
* `mips64` - MIPS64 instruction set (r6) - only for NDK r10 and newer
|
||||||
|
* **ANDROID_NATIVE_API_LEVEL** - level of android API to build for. Can be set either to full name (example: `android-8`) or a numeric value (example: `17`). The default API level depends on the target ABI:
|
||||||
|
* `android-8` for ARM;
|
||||||
|
* `android-9` for x86 and MIPS;
|
||||||
|
* `android-21` for 64-bit ABIs.
|
||||||
|
|
||||||
|
Building for `android-L` is possible only when it is explicitly selected.
|
||||||
|
* **ANDROID_TOOLCHAIN_NAME** - the name of compiler toolchain to be used. This option allows to select between different GCC and Clang versions. The list of possible values depends on the NDK version and will be printed by toolchain file if an invalid value is set. By default _android-cmake_ selects the most recent version of GCC which can build for specified `ANDROID_ABI`.
|
||||||
|
|
||||||
|
Example values are:
|
||||||
|
* `aarch64-linux-android-4.9`
|
||||||
|
* `aarch64-linux-android-clang3.5`
|
||||||
|
* `arm-linux-androideabi-4.8`
|
||||||
|
* `arm-linux-androideabi-4.9`
|
||||||
|
* `arm-linux-androideabi-clang3.5`
|
||||||
|
* `mips64el-linux-android-4.9`
|
||||||
|
* `mipsel-linux-android-4.8`
|
||||||
|
* `x86-4.9`
|
||||||
|
* `x86_64-4.9`
|
||||||
|
* etc.
|
||||||
|
* **ANDROID_STL** - the name of C++ runtime to use. The default is `gnustl_static`.
|
||||||
|
* `none` - do not configure the runtime.
|
||||||
|
* `system` - use the default minimal system C++ runtime library.
|
||||||
|
* Implies `-fno-rtti -fno-exceptions`.
|
||||||
|
* `system_re` - use the default minimal system C++ runtime library.
|
||||||
|
* Implies `-frtti -fexceptions`.
|
||||||
|
* `gabi++_static` - use the GAbi++ runtime as a static library.
|
||||||
|
* Implies `-frtti -fno-exceptions`.
|
||||||
|
* Available for NDK r7 and newer.
|
||||||
|
* `gabi++_shared` - use the GAbi++ runtime as a shared library.
|
||||||
|
* Implies `-frtti -fno-exceptions`.
|
||||||
|
* Available for NDK r7 and newer.
|
||||||
|
* `stlport_static` - use the STLport runtime as a static library.
|
||||||
|
* Implies `-fno-rtti -fno-exceptions` for NDK before r7.
|
||||||
|
* Implies `-frtti -fno-exceptions` for NDK r7 and newer.
|
||||||
|
* `stlport_shared` - use the STLport runtime as a shared library.
|
||||||
|
* Implies `-fno-rtti -fno-exceptions` for NDK before r7.
|
||||||
|
* Implies `-frtti -fno-exceptions` for NDK r7 and newer.
|
||||||
|
* **`gnustl_static`** - use the GNU STL as a static library.
|
||||||
|
* Implies `-frtti -fexceptions`.
|
||||||
|
* `gnustl_shared` - use the GNU STL as a shared library.
|
||||||
|
* Implies `-frtti -fno-exceptions`.
|
||||||
|
* Available for NDK r7b and newer.
|
||||||
|
* Silently degrades to `gnustl_static` if not available.
|
||||||
|
* **NDK_CCACHE** - path to `ccache` executable. If not set then initialized from `NDK_CCACHE` environment variable.
|
||||||
|
|
||||||
|
## Advanced _android-cmake_ options
|
||||||
|
|
||||||
|
Normally _android-cmake_ users are not supposed to touch these variables but they might be useful to workaround some build issues:
|
||||||
|
|
||||||
|
* **ANDROID_FORCE_ARM_BUILD** = `OFF` - generate 32-bit ARM instructions instead of Thumb. Applicable only for arm ABIs and is forced to be `ON` for `armeabi-v6 with VFP`;
|
||||||
|
* **ANDROID_NO_UNDEFINED** = `ON` - show all undefined symbols as linker errors;
|
||||||
|
* **ANDROID_SO_UNDEFINED** = `OFF` - allow undefined symbols in shared libraries;
|
||||||
|
* actually it is turned `ON` by default for NDK older than `r7`
|
||||||
|
* **ANDROID_STL_FORCE_FEATURES** = `ON` - automatically configure rtti and exceptions support based on C++ runtime;
|
||||||
|
* **ANDROID_NDK_LAYOUT** = `RELEASE` - inner layout of Android NDK, should be detected automatically. Possible values are:
|
||||||
|
* `RELEASE` - public releases from Google;
|
||||||
|
* `LINARO` - NDK from Linaro project;
|
||||||
|
* `ANDROID` - NDK from AOSP.
|
||||||
|
* **ANDROID_FUNCTION_LEVEL_LINKING** = `ON` - enables saparate putting each function and data items into separate sections and enable garbage collection of unused input sections at link time (`-fdata-sections -ffunction-sections -Wl,--gc-sections`);
|
||||||
|
* **ANDROID_GOLD_LINKER** = `ON` - use gold linker with GCC 4.6 for NDK r8b and newer (only for ARM and x86);
|
||||||
|
* **ANDROID_NOEXECSTACK** = `ON` - enables or disables stack execution protection code (`-Wl,-z,noexecstack`);
|
||||||
|
* **ANDROID_RELRO** = `ON` - Enables RELRO - a memory corruption mitigation technique (`-Wl,-z,relro -Wl,-z,now`);
|
||||||
|
* **ANDROID_LIBM_PATH** - path to `libm.so` (set to something like `$(TOP)/out/target/product/<product_name>/obj/lib/libm.so`) to workaround unresolved `sincos`.
|
||||||
|
|
||||||
|
## Fine-tuning `CMakeLists.txt` for _android-cmake_
|
||||||
|
|
||||||
|
### Recognizing Android build
|
||||||
|
|
||||||
|
_android-cmake_ defines `ANDROID` CMake variable which can be used to add Android-specific stuff:
|
||||||
|
|
||||||
|
if (ANDROID)
|
||||||
|
message(STATUS "Hello from Android build!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
The recommended way to identify ARM/MIPS/x86 architecture is examining `CMAKE_SYSTEM_PROCESSOR` which is set to the appropriate value:
|
||||||
|
|
||||||
|
* `armv5te` - for `armeabi` ABI
|
||||||
|
* `armv6` - for `armeabi-v6 with VFP` ABI
|
||||||
|
* `armv7-a` - for `armeabi-v7a`, `armeabi-v7a with VFPV3` and `armeabi-v7a with NEON` ABIs
|
||||||
|
* `aarch64` - for `arm64-v8a` ABI
|
||||||
|
* `i686` - for `x86` ABI
|
||||||
|
* `x86_64` - for `x86_64` ABI
|
||||||
|
* `mips` - for `mips` ABI
|
||||||
|
* `mips64` - for `mips64` ABI
|
||||||
|
|
||||||
|
Other variables that are set by _android-cmake_ and can be used for the fine-grained build configuration are:
|
||||||
|
|
||||||
|
* `NEON` - set if target ABI supports Neon;
|
||||||
|
* `ANDROID_NATIVE_API_LEVEL` - native Android API level we are building for (note: Java part of Andoid application can be built for another API level)
|
||||||
|
* `ANDROID_NDK_RELEASE` - version of the Android NDK
|
||||||
|
* `ANDROID_NDK_HOST_SYSTEM_NAME` - "windows", "linux-x86" or "darwin-x86" depending on the host platform
|
||||||
|
* `ANDROID_RTTI` - set if rtti is enabled by the runtime
|
||||||
|
* `ANDROID_EXCEPTIONS` - set if exceptions are enabled by the runtime
|
||||||
|
|
||||||
|
### Finding packages
|
||||||
|
|
||||||
|
When crosscompiling CMake `find_*` commands are normally expected to find libraries and packages belonging to the same build target. So _android-cmake_ configures CMake to search in Android-specific paths only and ignore your host system locations. So
|
||||||
|
|
||||||
|
find_package(ZLIB)
|
||||||
|
|
||||||
|
will surely find libz.so within the Android NDK.
|
||||||
|
|
||||||
|
However sometimes you need to locate a host package even when cross-compiling. For example you can be searching for your documentation generator. The _android-cmake_ recommends you to use `find_host_package` and `find_host_program` macro defined in the `android.toolchain.cmake`:
|
||||||
|
|
||||||
|
find_host_package(Doxygen)
|
||||||
|
find_host_program(PDFLATEX pdflatex)
|
||||||
|
|
||||||
|
However this will break regular builds so instead of wrapping package search into platform-specific logic you can copy the following snippet into your project (put it after your top-level `project()` command):
|
||||||
|
|
||||||
|
# Search packages for host system instead of packages for target system
|
||||||
|
# in case of cross compilation these macro should be defined by toolchain file
|
||||||
|
if(NOT COMMAND find_host_package)
|
||||||
|
macro(find_host_package)
|
||||||
|
find_package(${ARGN})
|
||||||
|
endmacro()
|
||||||
|
endif()
|
||||||
|
if(NOT COMMAND find_host_program)
|
||||||
|
macro(find_host_program)
|
||||||
|
find_program(${ARGN})
|
||||||
|
endmacro()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
### Compiler flags recycling
|
||||||
|
|
||||||
|
Make sure to do the following in your scripts:
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${my_cxx_flags}")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${my_cxx_flags}")
|
||||||
|
|
||||||
|
The flags will be prepopulated with critical flags, so don't loose them. Also be aware that _android-cmake_ also sets configuration-specific compiler and linker flags.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Building on Windows
|
||||||
|
|
||||||
|
First of all `cygwin` builds are **NOT supported** and will not be supported by _android-cmake_. To build natively on Windows you need a port of make but I recommend http://martine.github.io/ninja/ instead.
|
||||||
|
|
||||||
|
To build with Ninja you need:
|
||||||
|
|
||||||
|
* Ensure you are using CMake newer than 2.8.9;
|
||||||
|
* Download the latest Ninja from https://github.com/martine/ninja/releases;
|
||||||
|
* Put the `ninja.exe` into your PATH (or add path to `ninja.exe` to your PATH environment variable);
|
||||||
|
* Pass `-GNinja` to `cmake` alongside with other arguments (or choose Ninja generator in `cmake-gui`).
|
||||||
|
* Enjoy the fast native multithreaded build :)
|
||||||
|
|
||||||
|
But if you still want to stick to old make then:
|
||||||
|
|
||||||
|
* Get a Windows port of GNU Make:
|
||||||
|
* Android NDK r7 (and newer) already has `make.exe` on board;
|
||||||
|
* `mingw-make` should work as fine;
|
||||||
|
* Download some other port. For example, this one: http://gnuwin32.sourceforge.net/packages/make.htm.
|
||||||
|
* Add path to your `make.exe` to system PATH or always use full path;
|
||||||
|
* Pass `-G"MinGW Makefiles"` and `-DCMAKE_MAKE_PROGRAM="<full/path/to/>make.exe"`
|
||||||
|
* It must be `MinGW Makefiles` and not `Unix Makefiles` even if your `make.exe` is not a MinGW's make.
|
||||||
|
* Run `make.exe` or `cmake --build .` for single-threaded build.
|
||||||
|
|
||||||
|
### Projects with assembler files
|
||||||
|
|
||||||
|
The _android-cmake_ should correctly handle projects with assembler sources (`*.s` or `*.S`). But if you still facing problems with assembler then try to upgrade your CMake to version newer than 2.8.5
|
||||||
|
|
||||||
|
## Copying
|
||||||
|
|
||||||
|
_android-cmake_ is distributed under the terms of [BSD 3-Clause License](http://opensource.org/licenses/BSD-3-Clause)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,211 @@
|
||||||
|
|
||||||
|
============== r1 ============== (dead links)
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-1.5_r1-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-1.5_r1-darwin-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-1.5_r1-linux-x86.zip
|
||||||
|
|
||||||
|
============== r2 ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-1.6_r1-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-1.6_r1-darwin-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-1.6_r1-linux-x86.zip
|
||||||
|
|
||||||
|
============== r3 ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r3-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r3-darwin-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r3-linux-x86.zip
|
||||||
|
|
||||||
|
============== r4 ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r4-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r4-darwin-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r4-linux-x86.zip
|
||||||
|
|
||||||
|
============== r4b ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r4b-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r4b-darwin-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r4b-linux-x86.zip
|
||||||
|
|
||||||
|
============== r5 ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r5-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r5-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r5-linux-x86.tar.bz2
|
||||||
|
|
||||||
|
============== r5b ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r5b-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r5b-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r5b-linux-x86.tar.bz2
|
||||||
|
|
||||||
|
============== r5c ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r5c-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r5c-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r5c-linux-x86.tar.bz2
|
||||||
|
|
||||||
|
============== r6 ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r6-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r6-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r6-linux-x86.tar.bz2
|
||||||
|
|
||||||
|
============== r6b ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r6b-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r6b-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r6b-linux-x86.tar.bz2
|
||||||
|
|
||||||
|
============== r7 ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r7-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r7-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r7-linux-x86.tar.bz2
|
||||||
|
|
||||||
|
============== r7b ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r7b-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r7b-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r7b-linux-x86.tar.bz2
|
||||||
|
|
||||||
|
============== r7c ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r7c-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r7c-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r7c-linux-x86.tar.bz2
|
||||||
|
|
||||||
|
============== r8 ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8-linux-x86.tar.bz2
|
||||||
|
|
||||||
|
============== r8b ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8b-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8b-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8b-linux-x86.tar.bz2
|
||||||
|
|
||||||
|
============== r8c ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8c-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8c-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8c-linux-x86.tar.bz2
|
||||||
|
|
||||||
|
============== r8d ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8d-windows.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8d-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8d-linux-x86.tar.bz2
|
||||||
|
|
||||||
|
============== r8e ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8e-windows-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8e-windows-x86_64.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8e-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8e-darwin-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8e-linux-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r8e-linux-x86_64.tar.bz2
|
||||||
|
|
||||||
|
============== r9 ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9-windows-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9-windows-x86-legacy-toolchains.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9-windows-x86_64.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9-windows-x86_64-legacy-toolchains.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9-darwin-x86-legacy-toolchains.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9-darwin-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9-darwin-x86_64-legacy-toolchains.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9-linux-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9-linux-x86-legacy-toolchains.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9-linux-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9-linux-x86_64-legacy-toolchains.tar.bz2
|
||||||
|
|
||||||
|
============== r9b ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9b-windows-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9b-windows-x86-legacy-toolchains.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9b-windows-x86_64.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9b-windows-x86_64-legacy-toolchains.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9b-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9b-darwin-x86-legacy-toolchains.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9b-darwin-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9b-darwin-x86_64-legacy-toolchains.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9b-linux-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9b-linux-x86-legacy-toolchains.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9b-linux-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9b-linux-x86_64-legacy-toolchains.tar.bz2
|
||||||
|
|
||||||
|
============== r9c ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9c-windows-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9c-windows-x86_64.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9c-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9c-darwin-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9c-linux-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9c-linux-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9c-cxx-stl-libs-with-debugging-info.zip
|
||||||
|
|
||||||
|
============== r9d ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9d-windows-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9d-windows-x86_64.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9d-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9d-darwin-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9d-linux-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9d-linux-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r9d-cxx-stl-libs-with-debug-info.zip
|
||||||
|
|
||||||
|
============== r10 ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk32-r10-windows-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk32-r10-windows-x86_64.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk32-r10-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk32-r10-darwin-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk32-r10-linux-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk32-r10-linux-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk64-r10-windows-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk64-r10-windows-x86_64.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk64-r10-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk64-r10-darwin-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk64-r10-linux-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk64-r10-linux-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10-cxx-stl-libs-with-debug-info.zip
|
||||||
|
|
||||||
|
============== r10b ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk32-r10b-windows-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk32-r10b-windows-x86_64.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk32-r10b-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk32-r10b-darwin-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk32-r10b-linux-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk32-r10b-linux-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk64-r10b-windows-x86.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk64-r10b-windows-x86_64.zip
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk64-r10b-darwin-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk64-r10b-darwin-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk64-r10b-linux-x86.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk64-r10b-linux-x86_64.tar.bz2
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10b-cxx-stl-libs-with-debug-info.zip
|
||||||
|
|
||||||
|
============== r10c ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10c-windows-x86.exe
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10c-windows-x86_64.exe
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10c-darwin-x86.bin
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10c-darwin-x86_64.bin
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10c-linux-x86.bin
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10c-linux-x86_64.bin
|
||||||
|
|
||||||
|
============== r10d ==============
|
||||||
|
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10d-windows-x86.exe
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10d-windows-x86_64.exe
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10d-darwin-x86.bin
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10d-darwin-x86_64.bin
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10d-linux-x86.bin
|
||||||
|
* http://dl.google.com/android/ndk/android-ndk-r10d-linux-x86_64.bin
|
|
@ -43,6 +43,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
@ -2365,6 +2366,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
|
||||||
//ok, so far it looks like we're still in range of the horizontal edge
|
//ok, so far it looks like we're still in range of the horizontal edge
|
||||||
if ( e->xcurr == horzEdge->xtop && !eMaxPair )
|
if ( e->xcurr == horzEdge->xtop && !eMaxPair )
|
||||||
{
|
{
|
||||||
|
assert(horzEdge->nextInLML);
|
||||||
if (SlopesEqual(*e, *horzEdge->nextInLML, m_UseFullRange))
|
if (SlopesEqual(*e, *horzEdge->nextInLML, m_UseFullRange))
|
||||||
{
|
{
|
||||||
//if output polygons share an edge, they'll need joining later ...
|
//if output polygons share an edge, they'll need joining later ...
|
||||||
|
@ -2429,6 +2431,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
|
||||||
if ( horzEdge->outIdx >= 0 )
|
if ( horzEdge->outIdx >= 0 )
|
||||||
IntersectEdges( horzEdge, eMaxPair,
|
IntersectEdges( horzEdge, eMaxPair,
|
||||||
IntPoint(horzEdge->xtop, horzEdge->ycurr), ipBoth);
|
IntPoint(horzEdge->xtop, horzEdge->ycurr), ipBoth);
|
||||||
|
assert(eMaxPair);
|
||||||
if (eMaxPair->outIdx >= 0) throw clipperException("ProcessHorizontal error");
|
if (eMaxPair->outIdx >= 0) throw clipperException("ProcessHorizontal error");
|
||||||
DeleteFromAEL(eMaxPair);
|
DeleteFromAEL(eMaxPair);
|
||||||
DeleteFromAEL(horzEdge);
|
DeleteFromAEL(horzEdge);
|
||||||
|
|
|
@ -135,10 +135,9 @@ bool OpenDDLExport::writeToStream( const std::string &statement ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenDDLExport::writeNode( DDLNode *node, std::string &statement ) {
|
bool OpenDDLExport::writeNode( DDLNode *node, std::string &statement ) {
|
||||||
bool success( true );
|
|
||||||
writeNodeHeader( node, statement );
|
writeNodeHeader( node, statement );
|
||||||
if (node->hasProperties()) {
|
if (node->hasProperties()) {
|
||||||
success |= writeProperties( node, statement );
|
writeProperties( node, statement );
|
||||||
}
|
}
|
||||||
writeLineEnd( statement );
|
writeLineEnd( statement );
|
||||||
|
|
||||||
|
@ -360,11 +359,10 @@ bool OpenDDLExport::writeValueArray( DataArrayList *al, std::string &statement )
|
||||||
}
|
}
|
||||||
|
|
||||||
DataArrayList *nextDataArrayList = al ;
|
DataArrayList *nextDataArrayList = al ;
|
||||||
Value *nextValue( nextDataArrayList->m_dataList );
|
|
||||||
while (ddl_nullptr != nextDataArrayList) {
|
while (ddl_nullptr != nextDataArrayList) {
|
||||||
if (ddl_nullptr != nextDataArrayList) {
|
if (ddl_nullptr != nextDataArrayList) {
|
||||||
statement += "{ ";
|
statement += "{ ";
|
||||||
nextValue = nextDataArrayList->m_dataList;
|
Value *nextValue( nextDataArrayList->m_dataList );
|
||||||
size_t idx( 0 );
|
size_t idx( 0 );
|
||||||
while (ddl_nullptr != nextValue) {
|
while (ddl_nullptr != nextValue) {
|
||||||
if (idx > 0) {
|
if (idx > 0) {
|
||||||
|
|
|
@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -275,22 +276,24 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
|
||||||
}
|
}
|
||||||
delete id;
|
delete id;
|
||||||
|
|
||||||
Name *name(ddl_nullptr);
|
Name *name_(ddl_nullptr);
|
||||||
in = OpenDDLParser::parseName(in, end, &name);
|
in = OpenDDLParser::parseName(in, end, &name_);
|
||||||
|
std::unique_ptr<Name> name(name_);
|
||||||
if( ddl_nullptr != name && ddl_nullptr != node ) {
|
if( ddl_nullptr != name && ddl_nullptr != node ) {
|
||||||
const std::string nodeName( name->m_id->m_buffer );
|
const std::string nodeName( name->m_id->m_buffer );
|
||||||
node->setName( nodeName );
|
node->setName( nodeName );
|
||||||
delete name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Property *first(ddl_nullptr);
|
std::unique_ptr<Property> first;
|
||||||
in = lookForNextToken(in, end);
|
in = lookForNextToken(in, end);
|
||||||
if (*in == Grammar::OpenPropertyToken[0]) {
|
if (*in == Grammar::OpenPropertyToken[0]) {
|
||||||
in++;
|
in++;
|
||||||
Property *prop(ddl_nullptr), *prev(ddl_nullptr);
|
std::unique_ptr<Property> prop, prev;
|
||||||
while (*in != Grammar::ClosePropertyToken[0] && in != end) {
|
while (*in != Grammar::ClosePropertyToken[0] && in != end) {
|
||||||
in = OpenDDLParser::parseProperty(in, end, &prop);
|
Property *prop_(ddl_nullptr);
|
||||||
|
in = OpenDDLParser::parseProperty(in, end, &prop_);
|
||||||
|
prop.reset(prop_);
|
||||||
in = lookForNextToken(in, end);
|
in = lookForNextToken(in, end);
|
||||||
|
|
||||||
if (*in != Grammar::CommaSeparator[0] && *in != Grammar::ClosePropertyToken[0]) {
|
if (*in != Grammar::CommaSeparator[0] && *in != Grammar::ClosePropertyToken[0]) {
|
||||||
|
@ -300,20 +303,20 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
|
||||||
|
|
||||||
if (ddl_nullptr != prop && *in != Grammar::CommaSeparator[0]) {
|
if (ddl_nullptr != prop && *in != Grammar::CommaSeparator[0]) {
|
||||||
if (ddl_nullptr == first) {
|
if (ddl_nullptr == first) {
|
||||||
first = prop;
|
first = std::move(prop);
|
||||||
}
|
}
|
||||||
if (ddl_nullptr != prev) {
|
if (ddl_nullptr != prev) {
|
||||||
prev->m_next = prop;
|
prev->m_next = prop.release();
|
||||||
}
|
}
|
||||||
prev = prop;
|
prev = std::move(prop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++in;
|
++in;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the properties
|
// set the properties
|
||||||
if (ddl_nullptr != first && ddl_nullptr != node) {
|
if (first && ddl_nullptr != node) {
|
||||||
node->setProperties(first);
|
node->setProperties(first.release());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +342,6 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
|
||||||
} else {
|
} else {
|
||||||
++in;
|
++in;
|
||||||
logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
|
logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
|
||||||
error = true;
|
|
||||||
return ddl_nullptr;
|
return ddl_nullptr;
|
||||||
}
|
}
|
||||||
in = lookForNextToken( in, end );
|
in = lookForNextToken( in, end );
|
||||||
|
|
|
@ -204,7 +204,7 @@ local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
|
||||||
uLong *pX;
|
uLong *pX;
|
||||||
{
|
{
|
||||||
uLong x ;
|
uLong x ;
|
||||||
int i;
|
int i = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
|
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
|
||||||
|
@ -232,7 +232,7 @@ local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
|
||||||
uLong *pX;
|
uLong *pX;
|
||||||
{
|
{
|
||||||
uLong x ;
|
uLong x ;
|
||||||
int i;
|
int i = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
|
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
|
||||||
|
@ -725,19 +725,15 @@ local int unzlocal_GetCurrentFileInfoInternal (file,
|
||||||
|
|
||||||
if (lSeek!=0)
|
if (lSeek!=0)
|
||||||
{
|
{
|
||||||
if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
|
if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)!=0)
|
||||||
lSeek=0;
|
|
||||||
else
|
|
||||||
err=UNZ_ERRNO;
|
err=UNZ_ERRNO;
|
||||||
}
|
}
|
||||||
if ((file_info.size_file_comment>0) && (commentBufferSize>0))
|
if ((file_info.size_file_comment>0) && (commentBufferSize>0))
|
||||||
if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
|
if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
|
||||||
err=UNZ_ERRNO;
|
err=UNZ_ERRNO;
|
||||||
lSeek+=file_info.size_file_comment - uSizeRead;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lSeek+=file_info.size_file_comment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err==UNZ_OK) && (pfile_info!=NULL))
|
if ((err==UNZ_OK) && (pfile_info!=NULL))
|
||||||
|
@ -1129,7 +1125,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
|
||||||
|
|
||||||
if ((s->cur_file_info.compression_method!=0) &&
|
if ((s->cur_file_info.compression_method!=0) &&
|
||||||
(s->cur_file_info.compression_method!=Z_DEFLATED))
|
(s->cur_file_info.compression_method!=Z_DEFLATED))
|
||||||
err=UNZ_BADZIPFILE;
|
return UNZ_BADZIPFILE;
|
||||||
|
|
||||||
pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
|
pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
|
||||||
pfile_in_zip_read_info->crc32=0;
|
pfile_in_zip_read_info->crc32=0;
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#ifndef ZCONF_H
|
#ifndef ZCONF_H
|
||||||
#define ZCONF_H
|
#define ZCONF_H
|
||||||
|
/* #undef Z_PREFIX */
|
||||||
|
/* #undef Z_HAVE_UNISTD_H */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If you *really* need a unique prefix for all types and library functions,
|
* If you *really* need a unique prefix for all types and library functions,
|
||||||
|
|
|
@ -1742,7 +1742,7 @@ UML_LOOK = NO
|
||||||
# the class node. If there are many fields or methods and many nodes the
|
# the class node. If there are many fields or methods and many nodes the
|
||||||
# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
|
# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
|
||||||
# threshold limits the number of items for each type to make the size more
|
# threshold limits the number of items for each type to make the size more
|
||||||
# managable. Set this to 0 for no limit. Note that the threshold may be
|
# manageable. Set this to 0 for no limit. Note that the threshold may be
|
||||||
# exceeded by 50% before the limit is enforced.
|
# exceeded by 50% before the limit is enforced.
|
||||||
|
|
||||||
UML_LIMIT_NUM_FIELDS = 10
|
UML_LIMIT_NUM_FIELDS = 10
|
||||||
|
|
10
doc/dox.h
10
doc/dox.h
|
@ -60,7 +60,7 @@ that it has not been implemented yet and some (most ...) formats lack proper spe
|
||||||
<b>Stanford Ply</b> ( <i>*.ply</i> )<br>
|
<b>Stanford Ply</b> ( <i>*.ply</i> )<br>
|
||||||
<b>TrueSpace</b> ( <i>*.cob, *.scn</i> )<sup>2</sup><br><br>
|
<b>TrueSpace</b> ( <i>*.cob, *.scn</i> )<sup>2</sup><br><br>
|
||||||
</tt>
|
</tt>
|
||||||
See the @link importer_notes Importer Notes Page @endlink for informations, what a specific importer can do and what not.
|
See the @link importer_notes Importer Notes Page @endlink for information, what a specific importer can do and what not.
|
||||||
Note that although this paper claims to be the official documentation,
|
Note that although this paper claims to be the official documentation,
|
||||||
http://assimp.sourceforge.net/main_features_formats.html
|
http://assimp.sourceforge.net/main_features_formats.html
|
||||||
<br>is usually the most up-to-date list of file formats supported by the library. <br>
|
<br>is usually the most up-to-date list of file formats supported by the library. <br>
|
||||||
|
@ -81,7 +81,7 @@ formats handle the required endian conversion correctly, so large parts of the l
|
||||||
|
|
||||||
The assimp linker library and viewer application are provided under the BSD 3-clause license. This basically means
|
The assimp linker library and viewer application are provided under the BSD 3-clause license. This basically means
|
||||||
that you are free to use it in open- or closed-source projects, for commercial or non-commercial purposes as you like
|
that you are free to use it in open- or closed-source projects, for commercial or non-commercial purposes as you like
|
||||||
as long as you retain the license informations and take own responsibility for what you do with it. For details see
|
as long as you retain the license information and take own responsibility for what you do with it. For details see
|
||||||
the LICENSE file.
|
the LICENSE file.
|
||||||
|
|
||||||
You can find test models for almost all formats in the <assimp_root>/test/models directory. Beware, they're *free*,
|
You can find test models for almost all formats in the <assimp_root>/test/models directory. Beware, they're *free*,
|
||||||
|
@ -1420,7 +1420,7 @@ IFC file properties (IfcPropertySet) are kept as per-node metadata, see aiNode::
|
||||||
|
|
||||||
This section contains implementations notes for the OgreXML importer.
|
This section contains implementations notes for the OgreXML importer.
|
||||||
@subsection overview Overview
|
@subsection overview Overview
|
||||||
Ogre importer is currently optimized for the Blender Ogre exporter, because thats the only one that I use. You can find the Blender Ogre exporter at: http://www.ogre3d.org/forums/viewtopic.php?f=8&t=45922
|
Ogre importer is currently optimized for the Blender Ogre exporter, because that's the only one that I use. You can find the Blender Ogre exporter at: http://www.ogre3d.org/forums/viewtopic.php?f=8&t=45922
|
||||||
|
|
||||||
@subsection what What will be loaded?
|
@subsection what What will be loaded?
|
||||||
|
|
||||||
|
@ -1434,7 +1434,7 @@ Skeleton: Skeleton with Bone hierarchy (Position and Rotation, but no Scaling in
|
||||||
animations with rotation, translation and scaling keys.
|
animations with rotation, translation and scaling keys.
|
||||||
|
|
||||||
@subsection export_Blender How to export Files from Blender
|
@subsection export_Blender How to export Files from Blender
|
||||||
You can find informations about how to use the Ogreexporter by your own, so here are just some options that you need, so the assimp
|
You can find information about how to use the Ogreexporter by your own, so here are just some options that you need, so the assimp
|
||||||
importer will load everything correctly:
|
importer will load everything correctly:
|
||||||
- Use either "Rendering Material" or "Custom Material" see @ref material
|
- Use either "Rendering Material" or "Custom Material" see @ref material
|
||||||
- do not use "Flip Up Axies to Y"
|
- do not use "Flip Up Axies to Y"
|
||||||
|
@ -1543,7 +1543,7 @@ Done! Please, share your loader that everyone can profit from it!
|
||||||
|
|
||||||
@section properties Properties
|
@section properties Properties
|
||||||
|
|
||||||
You can use properties to chance the behavior of you importer. In order to do so, you have to overide BaseImporter::SetupProperties, and specify
|
You can use properties to chance the behavior of you importer. In order to do so, you have to override BaseImporter::SetupProperties, and specify
|
||||||
you custom properties in config.h. Just have a look to the other AI_CONFIG_IMPORT_* defines and you will understand, how it works.
|
you custom properties in config.h. Just have a look to the other AI_CONFIG_IMPORT_* defines and you will understand, how it works.
|
||||||
|
|
||||||
The properties can be set with Importer::SetProperty***() and can be accessed in your SetupProperties function with Importer::GetProperty***(). You can
|
The properties can be set with Importer::SetProperty***() and can be accessed in your SetupProperties function with Importer::GetProperty***(). You can
|
||||||
|
|
|
@ -266,6 +266,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_CONFIG_PP_FD_REMOVE \
|
#define AI_CONFIG_PP_FD_REMOVE \
|
||||||
"PP_FD_REMOVE"
|
"PP_FD_REMOVE"
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief Configures the #aiProcess_FindDegenerates to check the area of a
|
||||||
|
* trinagle to be greates than e-6. If this is not the case the triangle will
|
||||||
|
* be removed if #AI_CONFIG_PP_FD_REMOVE is set to true.
|
||||||
|
*/
|
||||||
|
#define AI_CONFIG_PP_FD_CHECKAREA \
|
||||||
|
"PP_FD_CHECKAREA"
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @brief Configures the #aiProcess_OptimizeGraph step to preserve nodes
|
/** @brief Configures the #aiProcess_OptimizeGraph step to preserve nodes
|
||||||
* matching a name in a given list.
|
* matching a name in a given list.
|
||||||
|
@ -903,7 +912,7 @@ enum aiComponent
|
||||||
/** @brief Set the tessellation for IFC cylindrical shapes.
|
/** @brief Set the tessellation for IFC cylindrical shapes.
|
||||||
*
|
*
|
||||||
* This is used by the IFC importer to determine the tessellation parameter
|
* This is used by the IFC importer to determine the tessellation parameter
|
||||||
* for cylindrical shapes, i.e. the number of segments used to aproximate a circle.
|
* for cylindrical shapes, i.e. the number of segments used to approximate a circle.
|
||||||
* @note The default value is AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION and the
|
* @note The default value is AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION and the
|
||||||
* accepted values are in range [3, 180].
|
* accepted values are in range [3, 180].
|
||||||
* Property type: Integer.
|
* Property type: Integer.
|
||||||
|
|
|
@ -65,11 +65,10 @@ template <typename TReal>
|
||||||
class aiVector3t
|
class aiVector3t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
aiVector3t() : x(), y(), z() {}
|
||||||
aiVector3t () : x(), y(), z() {}
|
aiVector3t(TReal _x, TReal _y, TReal _z) : x(_x), y(_y), z(_z) {}
|
||||||
aiVector3t (TReal _x, TReal _y, TReal _z) : x(_x), y(_y), z(_z) {}
|
explicit aiVector3t (TReal _xyz ) : x(_xyz), y(_xyz), z(_xyz) {}
|
||||||
explicit aiVector3t (TReal _xyz) : x(_xyz), y(_xyz), z(_xyz) {}
|
aiVector3t( const aiVector3t& o ) : x(o.x), y(o.y), z(o.z) {}
|
||||||
aiVector3t (const aiVector3t& o) : x(o.x), y(o.y), z(o.z) {}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ class MeshKey(Structure):
|
||||||
("mTime", c_double),
|
("mTime", c_double),
|
||||||
|
|
||||||
# Index into the aiMesh::mAnimMeshes array of the
|
# Index into the aiMesh::mAnimMeshes array of the
|
||||||
# mesh coresponding to the
|
# mesh corresponding to the
|
||||||
#aiMeshAnim hosting this
|
#aiMeshAnim hosting this
|
||||||
# key frame. The referenced anim mesh is evaluated
|
# key frame. The referenced anim mesh is evaluated
|
||||||
# according to the rules defined in the docs for
|
# according to the rules defined in the docs for
|
||||||
|
|
|
@ -895,7 +895,7 @@ class PyAssimp3DViewer:
|
||||||
aspect = camera.aspect
|
aspect = camera.aspect
|
||||||
|
|
||||||
u = 0.1 # unit size (in m)
|
u = 0.1 # unit size (in m)
|
||||||
l = 3 * u # lenght of the camera cone
|
l = 3 * u # length of the camera cone
|
||||||
f = 3 * u # aperture of the camera cone
|
f = 3 * u # aperture of the camera cone
|
||||||
|
|
||||||
glPushMatrix()
|
glPushMatrix()
|
||||||
|
|
|
@ -897,7 +897,7 @@ class PyAssimp3DViewer:
|
||||||
aspect = camera.aspect
|
aspect = camera.aspect
|
||||||
|
|
||||||
u = 0.1 # unit size (in m)
|
u = 0.1 # unit size (in m)
|
||||||
l = 3 * u # lenght of the camera cone
|
l = 3 * u # length of the camera cone
|
||||||
f = 3 * u # aperture of the camera cone
|
f = 3 * u # aperture of the camera cone
|
||||||
|
|
||||||
glPushMatrix()
|
glPushMatrix()
|
||||||
|
|
|
@ -583,7 +583,7 @@ def clip_matrix(left, right, bottom, top, near, far, perspective=False):
|
||||||
orthographic canonical view volume (a box).
|
orthographic canonical view volume (a box).
|
||||||
|
|
||||||
Homogeneous coordinates transformed by the perspective clip matrix
|
Homogeneous coordinates transformed by the perspective clip matrix
|
||||||
need to be dehomogenized (devided by w coordinate).
|
need to be dehomogenized (divided by w coordinate).
|
||||||
|
|
||||||
>>> frustrum = numpy.random.rand(6)
|
>>> frustrum = numpy.random.rand(6)
|
||||||
>>> frustrum[1] += frustrum[0]
|
>>> frustrum[1] += frustrum[0]
|
||||||
|
|
|
@ -51,7 +51,7 @@ import assimp.types;
|
||||||
extern ( C ) {
|
extern ( C ) {
|
||||||
/*
|
/*
|
||||||
* These limits are required to match the settings Assimp was compiled
|
* These limits are required to match the settings Assimp was compiled
|
||||||
* against. Therfore, do not redefine them unless you build the library
|
* against. Therefore, do not redefine them unless you build the library
|
||||||
* from source using the same definitions.
|
* from source using the same definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -1951,7 +1951,7 @@ error:
|
||||||
|
|
||||||
if (NULL == exception)
|
if (NULL == exception)
|
||||||
{
|
{
|
||||||
/* thats really a problem because we cannot throw in this case */
|
/* that's really a problem because we cannot throw in this case */
|
||||||
env->FatalError("could not throw java.io.IOException");
|
env->FatalError("could not throw java.io.IOException");
|
||||||
}
|
}
|
||||||
gLastErrorString = imp.GetErrorString();
|
gLastErrorString = imp.GetErrorString();
|
||||||
|
|
|
@ -114,7 +114,7 @@
|
||||||
%include "interface/IOSystem.i"
|
%include "interface/IOSystem.i"
|
||||||
|
|
||||||
|
|
||||||
// We have to "instanciate" the templates used by the ASSSIMP_*_ARRAY macros
|
// We have to "instantiate" the templates used by the ASSSIMP_*_ARRAY macros
|
||||||
// here at the end to avoid running into forward reference issues (SWIG would
|
// here at the end to avoid running into forward reference issues (SWIG would
|
||||||
// spit out the helper functions before the header includes for the element
|
// spit out the helper functions before the header includes for the element
|
||||||
// types otherwise).
|
// types otherwise).
|
||||||
|
|
|
@ -641,7 +641,7 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink,const CVTimeS
|
||||||
{
|
{
|
||||||
for(MeshHelper* helper in modelMeshes)
|
for(MeshHelper* helper in modelMeshes)
|
||||||
{
|
{
|
||||||
// Set up meterial state.
|
// Set up material state.
|
||||||
glCallList(helper.displayList);
|
glCallList(helper.displayList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,7 @@ extern void exit(int);
|
||||||
glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat,
|
glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat,
|
||||||
glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!).
|
glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!).
|
||||||
**/
|
**/
|
||||||
#ifndef GLUT_API_VERSION /* allow this to be overriden */
|
#ifndef GLUT_API_VERSION /* allow this to be overridden */
|
||||||
#define GLUT_API_VERSION 3
|
#define GLUT_API_VERSION 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ extern void exit(int);
|
||||||
|
|
||||||
GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa <GL/glut.h>
|
GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa <GL/glut.h>
|
||||||
**/
|
**/
|
||||||
#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */
|
#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overridden. */
|
||||||
#define GLUT_XLIB_IMPLEMENTATION 15
|
#define GLUT_XLIB_IMPLEMENTATION 15
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
@echo off
|
||||||
|
|
||||||
|
set ASSIMP_PATH=D:\projects\asset-importer-lib\assimp
|
||||||
|
set CMAKE_PATH="C:\Program Files\CMake\bin\cmake.exe"
|
||||||
|
set ANDROID_NDK_PATH=C:\Users\kimkulling\AppData\Local\Android\Sdk\ndk-bundle
|
||||||
|
set ANDROID_CMAKE_PATH=contrib\android-cmake
|
||||||
|
|
||||||
|
pushd %ASSIMP_PATH%
|
||||||
|
|
||||||
|
rmdir /s /q build
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
%CMAKE_PATH% .. ^
|
||||||
|
-G"MinGW Makefiles" ^
|
||||||
|
-DCMAKE_BUILD_TYPE=Release ^
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=%ANDROID_CMAKE_PATH%\android.toolchain.cmake ^
|
||||||
|
-DCMAKE_MAKE_PROGRAM=%ANDROID_NDK_PATH%\prebuilt\windows-x86_64\bin\make.exe ^
|
||||||
|
-DANDROID_NDK=%ANDROID_NDK_PATH% ^
|
||||||
|
-DANDROID_NATIVE_API_LEVEL=android-9 ^
|
||||||
|
-DASSIMP_ANDROID_JNIIOSYSTEM=ON ^
|
||||||
|
-DANDROID_ABI=arm64-v8a ^
|
||||||
|
-DASSIMP_BUILD_ZLIB=ON ^
|
||||||
|
-DASSIMP_BUILD_TESTS=OFF
|
||||||
|
|
||||||
|
%CMAKE_PATH% --build .
|
||||||
|
|
||||||
|
popd
|
|
@ -52,24 +52,55 @@ INCLUDE_DIRECTORIES(
|
||||||
# Assimp library can be found, even if it is not installed system-wide yet.
|
# Assimp library can be found, even if it is not installed system-wide yet.
|
||||||
LINK_DIRECTORIES( ${Assimp_BINARY_DIR} ${AssetImporter_BINARY_DIR}/lib )
|
LINK_DIRECTORIES( ${Assimp_BINARY_DIR} ${AssetImporter_BINARY_DIR}/lib )
|
||||||
|
|
||||||
SOURCE_GROUP( unit FILES
|
SET( COMMON
|
||||||
unit/CCompilerTest.c
|
unit/utIOSystem.cpp
|
||||||
)
|
unit/utIOStreamBuffer.cpp
|
||||||
|
unit/utIssues.cpp
|
||||||
SET( TEST_SRCS
|
unit/utAnim.cpp
|
||||||
|
unit/AssimpAPITest.cpp
|
||||||
|
unit/utBatchLoader.cpp
|
||||||
|
unit/utDefaultIOStream.cpp
|
||||||
|
unit/utFastAtof.cpp
|
||||||
|
unit/utMetadata.cpp
|
||||||
|
unit/SceneDiffer.h
|
||||||
|
unit/SceneDiffer.cpp
|
||||||
unit/UTLogStream.h
|
unit/UTLogStream.h
|
||||||
unit/AbstractImportExportBase.cpp
|
unit/AbstractImportExportBase.cpp
|
||||||
unit/TestIOSystem.h
|
unit/TestIOSystem.h
|
||||||
unit/TestModelFactory.h
|
unit/TestModelFactory.h
|
||||||
|
unit/utTypes.cpp
|
||||||
|
unit/utVersion.cpp
|
||||||
|
unit/utProfiler.cpp
|
||||||
|
unit/utSharedPPData.cpp
|
||||||
|
unit/utStringUtils.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
SET( IMPORTERS
|
||||||
|
unit/utLWSImportExport.cpp
|
||||||
|
unit/utSMDImportExport.cpp
|
||||||
|
unit/utglTFImportExport.cpp
|
||||||
|
unit/utglTF2ImportExport.cpp
|
||||||
|
unit/utHMPImportExport.cpp
|
||||||
|
unit/utIFCImportExport.cpp
|
||||||
|
unit/utFBXImporterExporter.cpp
|
||||||
|
unit/utImporter.cpp
|
||||||
unit/ut3DImportExport.cpp
|
unit/ut3DImportExport.cpp
|
||||||
unit/ut3DSImportExport.cpp
|
unit/ut3DSImportExport.cpp
|
||||||
unit/utACImportExport.cpp
|
unit/utACImportExport.cpp
|
||||||
unit/utAMFImportExport.cpp
|
unit/utAMFImportExport.cpp
|
||||||
unit/utASEImportExport.cpp
|
unit/utASEImportExport.cpp
|
||||||
unit/utAnim.cpp
|
unit/utD3MFImportExport.cpp
|
||||||
unit/AssimpAPITest.cpp
|
unit/utQ3DImportExport.cpp
|
||||||
unit/utB3DImportExport.cpp
|
unit/utSTLImportExport.cpp
|
||||||
unit/utBatchLoader.cpp
|
unit/utXImporterExporter.cpp
|
||||||
|
unit/utX3DImportExport.cpp
|
||||||
|
unit/utDXFImporterExporter.cpp
|
||||||
|
unit/utPMXImporter.cpp
|
||||||
|
unit/utPLYImportExport.cpp
|
||||||
|
unit/utObjImportExport.cpp
|
||||||
|
unit/utObjTools.cpp
|
||||||
|
unit/utOpenGEXImportExport.cpp
|
||||||
|
unit/utSIBImporter.cpp
|
||||||
unit/utBlenderIntermediate.cpp
|
unit/utBlenderIntermediate.cpp
|
||||||
unit/utBlendImportAreaLight.cpp
|
unit/utBlendImportAreaLight.cpp
|
||||||
unit/utBlenderImportExport.cpp
|
unit/utBlenderImportExport.cpp
|
||||||
|
@ -79,77 +110,60 @@ SET( TEST_SRCS
|
||||||
unit/utColladaExportLight.cpp
|
unit/utColladaExportLight.cpp
|
||||||
unit/utColladaImportExport.cpp
|
unit/utColladaImportExport.cpp
|
||||||
unit/utCSMImportExport.cpp
|
unit/utCSMImportExport.cpp
|
||||||
unit/utDefaultIOStream.cpp
|
unit/utB3DImportExport.cpp
|
||||||
unit/utDXFImporterExporter.cpp
|
)
|
||||||
unit/utFastAtof.cpp
|
|
||||||
unit/utFBXImporterExporter.cpp
|
SET( MATERIAL
|
||||||
unit/utFindDegenerates.cpp
|
|
||||||
unit/utFindInvalidData.cpp
|
|
||||||
unit/utFixInfacingNormals.cpp
|
|
||||||
unit/utGenNormals.cpp
|
|
||||||
unit/utglTFImportExport.cpp
|
|
||||||
unit/utglTF2ImportExport.cpp
|
|
||||||
unit/utHMPImportExport.cpp
|
|
||||||
unit/utIFCImportExport.cpp
|
|
||||||
unit/utImporter.cpp
|
|
||||||
unit/utImproveCacheLocality.cpp
|
|
||||||
unit/utIOSystem.cpp
|
|
||||||
unit/utIOStreamBuffer.cpp
|
|
||||||
unit/utIssues.cpp
|
|
||||||
unit/utJoinVertices.cpp
|
|
||||||
unit/utLimitBoneWeights.cpp
|
|
||||||
unit/utLWSImportExport.cpp
|
|
||||||
unit/utMaterialSystem.cpp
|
unit/utMaterialSystem.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
SET( MATH
|
||||||
unit/utMatrix3x3.cpp
|
unit/utMatrix3x3.cpp
|
||||||
unit/utMatrix4x4.cpp
|
unit/utMatrix4x4.cpp
|
||||||
unit/utMetadata.cpp
|
|
||||||
unit/SceneDiffer.h
|
|
||||||
unit/SceneDiffer.cpp
|
|
||||||
unit/utSIBImporter.cpp
|
|
||||||
unit/utObjImportExport.cpp
|
|
||||||
unit/utObjTools.cpp
|
|
||||||
unit/utOpenGEXImportExport.cpp
|
|
||||||
unit/utPretransformVertices.cpp
|
|
||||||
unit/utPLYImportExport.cpp
|
|
||||||
unit/utPMXImporter.cpp
|
|
||||||
unit/utRemoveComments.cpp
|
|
||||||
unit/utRemoveComponent.cpp
|
|
||||||
unit/utScenePreprocessor.cpp
|
|
||||||
unit/utSceneCombiner.cpp
|
|
||||||
unit/utSharedPPData.cpp
|
|
||||||
unit/utStringUtils.cpp
|
|
||||||
unit/utSMDImportExport.cpp
|
|
||||||
unit/utSortByPType.cpp
|
|
||||||
unit/utSplitLargeMeshes.cpp
|
|
||||||
unit/utTargetAnimation.cpp
|
|
||||||
unit/utTextureTransform.cpp
|
|
||||||
unit/utTriangulate.cpp
|
|
||||||
unit/utTypes.cpp
|
|
||||||
unit/utVertexTriangleAdjacency.cpp
|
|
||||||
unit/utVersion.cpp
|
|
||||||
unit/utVector3.cpp
|
unit/utVector3.cpp
|
||||||
unit/utXImporterExporter.cpp
|
|
||||||
unit/utX3DImportExport.cpp
|
|
||||||
unit/utD3MFImportExport.cpp
|
|
||||||
unit/utQ3DImportExport.cpp
|
|
||||||
unit/utProfiler.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SET( POST_PROCESSES
|
SET( POST_PROCESSES
|
||||||
|
unit/utImproveCacheLocality.cpp
|
||||||
|
unit/utFixInfacingNormals.cpp
|
||||||
|
unit/utGenNormals.cpp
|
||||||
|
unit/utTriangulate.cpp
|
||||||
|
unit/utTextureTransform.cpp
|
||||||
unit/utRemoveRedundantMaterials.cpp
|
unit/utRemoveRedundantMaterials.cpp
|
||||||
unit/utRemoveVCProcess.cpp
|
unit/utRemoveVCProcess.cpp
|
||||||
unit/utScaleProcess.cpp
|
unit/utScaleProcess.cpp
|
||||||
unit/utJoinVertices.cpp
|
unit/utJoinVertices.cpp
|
||||||
|
unit/utRemoveComments.cpp
|
||||||
|
unit/utRemoveComponent.cpp
|
||||||
|
unit/utVertexTriangleAdjacency.cpp
|
||||||
|
unit/utJoinVertices.cpp
|
||||||
|
unit/utSplitLargeMeshes.cpp
|
||||||
|
unit/utFindDegenerates.cpp
|
||||||
|
unit/utFindInvalidData.cpp
|
||||||
|
unit/utLimitBoneWeights.cpp
|
||||||
|
unit/utPretransformVertices.cpp
|
||||||
|
unit/utScenePreprocessor.cpp
|
||||||
|
unit/utTargetAnimation.cpp
|
||||||
|
unit/utSortByPType.cpp
|
||||||
|
unit/utSceneCombiner.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP( tests FILES ${TEST_SRCS} )
|
SOURCE_GROUP( UnitTests\\Compiler FILES unit/CCompilerTest.c )
|
||||||
SOURCE_GROUP( tests/PostProcess FILES ${POST_PROCESSES})
|
SOURCE_GROUP( UnitTests\\Common FILES ${COMMON} )
|
||||||
|
SOURCE_GROUP( UnitTests\\Importers FILES ${IMPORTERS} )
|
||||||
|
SOURCE_GROUP( UnitTests\\Material FILES ${MATERIAL} )
|
||||||
|
SOURCE_GROUP( UnitTests\\Math FILES ${MATH} )
|
||||||
|
SOURCE_GROUP( UnitTests\\PostProcess FILES ${POST_PROCESSES})
|
||||||
|
|
||||||
add_executable( unit
|
add_executable( unit
|
||||||
../contrib/gtest/src/gtest-all.cc
|
../contrib/gtest/src/gtest-all.cc
|
||||||
unit/CCompilerTest.c
|
unit/CCompilerTest.c
|
||||||
unit/Main.cpp
|
unit/Main.cpp
|
||||||
../code/Version.cpp
|
../code/Version.cpp
|
||||||
${TEST_SRCS}
|
${COMMON}
|
||||||
|
${IMPORTERS}
|
||||||
|
${MATERIAL}
|
||||||
|
${MATH}
|
||||||
${POST_PROCESSES}
|
${POST_PROCESSES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ L'utilizzo della Creative Commons non influisce su questo diritto.
|
||||||
************************************************
|
************************************************
|
||||||
|
|
||||||
This model is released under Creative Commons Licence, Attribution 2.0
|
This model is released under Creative Commons Licence, Attribution 2.0
|
||||||
for informations see:
|
for information see:
|
||||||
http://creativecommons.org
|
http://creativecommons.org
|
||||||
http://creativecommons.org/licenses/by/2.0/
|
http://creativecommons.org/licenses/by/2.0/
|
||||||
feel free to use and improve it.
|
feel free to use and improve it.
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Simple models for testing importer. No desription because models are simple and created by hands.
|
Simple models for testing importer. No description because models are simple and created by hand.
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
solid testTriangle_1
|
||||||
|
facet normal 0.0 0.0 1.0
|
||||||
|
outer loop
|
||||||
|
vertex 1.0 1.0 0.0
|
||||||
|
vertex -1.0 1.0 0.0
|
||||||
|
vertex 0.0 -1.0 0.0
|
||||||
|
endloop
|
||||||
|
endfacet
|
||||||
|
endsolid
|
||||||
|
solid testTriangle_2
|
||||||
|
facet normal 0.0 0.0 1.0
|
||||||
|
outer loop
|
||||||
|
vertex 3.0 3.0 0.0
|
||||||
|
vertex 2.0 3.0 0.0
|
||||||
|
vertex 0.0 2.0 0.0
|
||||||
|
endloop
|
||||||
|
endfacet
|
||||||
|
endsolid
|
|
@ -58,8 +58,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void FindDegeneratesProcessTest::SetUp()
|
void FindDegeneratesProcessTest::SetUp() {
|
||||||
{
|
|
||||||
mesh = new aiMesh();
|
mesh = new aiMesh();
|
||||||
process = new FindDegeneratesProcess();
|
process = new FindDegeneratesProcess();
|
||||||
|
|
||||||
|
@ -107,16 +106,12 @@ void FindDegeneratesProcessTest::SetUp()
|
||||||
mesh->mNumUVComponents[1] = numFaces;
|
mesh->mNumUVComponents[1] = numFaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
void FindDegeneratesProcessTest::TearDown() {
|
||||||
void FindDegeneratesProcessTest::TearDown()
|
|
||||||
{
|
|
||||||
delete mesh;
|
delete mesh;
|
||||||
delete process;
|
delete process;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
TEST_F(FindDegeneratesProcessTest, testDegeneratesDetection) {
|
||||||
TEST_F(FindDegeneratesProcessTest, testDegeneratesDetection)
|
|
||||||
{
|
|
||||||
process->EnableInstantRemoval(false);
|
process->EnableInstantRemoval(false);
|
||||||
process->ExecuteOnMesh(mesh);
|
process->ExecuteOnMesh(mesh);
|
||||||
|
|
||||||
|
@ -135,12 +130,18 @@ TEST_F(FindDegeneratesProcessTest, testDegeneratesDetection)
|
||||||
mesh->mPrimitiveTypes);
|
mesh->mPrimitiveTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
TEST_F(FindDegeneratesProcessTest, testDegeneratesRemoval) {
|
||||||
TEST_F(FindDegeneratesProcessTest, testDegeneratesRemoval)
|
process->EnableAreaCheck(false);
|
||||||
{
|
|
||||||
process->EnableInstantRemoval(true);
|
process->EnableInstantRemoval(true);
|
||||||
process->ExecuteOnMesh(mesh);
|
process->ExecuteOnMesh(mesh);
|
||||||
|
|
||||||
EXPECT_EQ(mesh->mNumUVComponents[1], mesh->mNumFaces);
|
EXPECT_EQ(mesh->mNumUVComponents[1], mesh->mNumFaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(FindDegeneratesProcessTest, testDegeneratesRemovalWithAreaCheck) {
|
||||||
|
process->EnableAreaCheck(true);
|
||||||
|
process->EnableInstantRemoval(true);
|
||||||
|
process->ExecuteOnMesh(mesh);
|
||||||
|
|
||||||
|
EXPECT_EQ(mesh->mNumUVComponents[1]-100, mesh->mNumFaces);
|
||||||
|
}
|
||||||
|
|
|
@ -294,12 +294,12 @@ TEST_F(utObjImportExport, relative_indices_Test) {
|
||||||
const aiScene *scene = myimporter.ReadFileFromMemory(ObjModel.c_str(), ObjModel.size(), aiProcess_ValidateDataStructure);
|
const aiScene *scene = myimporter.ReadFileFromMemory(ObjModel.c_str(), ObjModel.size(), aiProcess_ValidateDataStructure);
|
||||||
EXPECT_NE(nullptr, scene);
|
EXPECT_NE(nullptr, scene);
|
||||||
|
|
||||||
EXPECT_EQ(scene->mNumMeshes, 1);
|
EXPECT_EQ(scene->mNumMeshes, 1U);
|
||||||
const aiMesh *mesh = scene->mMeshes[0];
|
const aiMesh *mesh = scene->mMeshes[0];
|
||||||
EXPECT_EQ(mesh->mNumVertices, 4);
|
EXPECT_EQ(mesh->mNumVertices, 4U);
|
||||||
EXPECT_EQ(mesh->mNumFaces, 1);
|
EXPECT_EQ(mesh->mNumFaces, 1U);
|
||||||
const aiFace face = mesh->mFaces[0];
|
const aiFace face = mesh->mFaces[0];
|
||||||
EXPECT_EQ(face.mNumIndices, 4);
|
EXPECT_EQ(face.mNumIndices, 4U);
|
||||||
for (unsigned int i = 0; i < face.mNumIndices; ++i)
|
for (unsigned int i = 0; i < face.mNumIndices; ++i)
|
||||||
{
|
{
|
||||||
EXPECT_EQ(face.mIndices[i], i);
|
EXPECT_EQ(face.mIndices[i], i);
|
||||||
|
@ -318,12 +318,12 @@ TEST_F(utObjImportExport, homogeneous_coordinates_Test) {
|
||||||
const aiScene *scene = myimporter.ReadFileFromMemory(ObjModel.c_str(), ObjModel.size(), aiProcess_ValidateDataStructure);
|
const aiScene *scene = myimporter.ReadFileFromMemory(ObjModel.c_str(), ObjModel.size(), aiProcess_ValidateDataStructure);
|
||||||
EXPECT_NE(nullptr, scene);
|
EXPECT_NE(nullptr, scene);
|
||||||
|
|
||||||
EXPECT_EQ(scene->mNumMeshes, 1);
|
EXPECT_EQ(scene->mNumMeshes, 1U);
|
||||||
const aiMesh *mesh = scene->mMeshes[0];
|
const aiMesh *mesh = scene->mMeshes[0];
|
||||||
EXPECT_EQ(mesh->mNumVertices, 3);
|
EXPECT_EQ(mesh->mNumVertices, 3U);
|
||||||
EXPECT_EQ(mesh->mNumFaces, 1);
|
EXPECT_EQ(mesh->mNumFaces, 1U);
|
||||||
const aiFace face = mesh->mFaces[0];
|
const aiFace face = mesh->mFaces[0];
|
||||||
EXPECT_EQ(face.mNumIndices, 3);
|
EXPECT_EQ(face.mNumIndices, 3U);
|
||||||
const aiVector3D vertice = mesh->mVertices[0];
|
const aiVector3D vertice = mesh->mVertices[0];
|
||||||
EXPECT_EQ(vertice.x, -1.0f);
|
EXPECT_EQ(vertice.x, -1.0f);
|
||||||
EXPECT_EQ(vertice.y, 0.0f);
|
EXPECT_EQ(vertice.y, 0.0f);
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2017, 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 "SceneDiffer.h"
|
||||||
|
#include "AbstractImportExportBase.h"
|
||||||
|
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class utSTLImporterExporter : public AbstractImportExportBase {
|
||||||
|
public:
|
||||||
|
virtual bool importerTest() {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/Spider_ascii.stl", 0 );
|
||||||
|
return nullptr != scene;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F( utSTLImporterExporter, importXFromFileTest ) {
|
||||||
|
EXPECT_TRUE( importerTest() );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F( utSTLImporterExporter, test_with_two_solids ) {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/triangle_with_two_solids.stl", 0 );
|
||||||
|
EXPECT_NE( nullptr, scene );
|
||||||
|
}
|
|
@ -177,6 +177,17 @@ inline uint32_t Write<aiVector3D>(const aiVector3D& v)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
|
// Serialize a color value
|
||||||
|
template <>
|
||||||
|
inline uint32_t Write<aiColor3D>(const aiColor3D& v)
|
||||||
|
{
|
||||||
|
uint32_t t = Write<float>(v.r);
|
||||||
|
t += Write<float>(v.g);
|
||||||
|
t += Write<float>(v.b);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize a color value
|
// Serialize a color value
|
||||||
template <>
|
template <>
|
||||||
|
@ -198,6 +209,7 @@ inline uint32_t Write<aiQuaternion>(const aiQuaternion& v)
|
||||||
t += Write<float>(v.x);
|
t += Write<float>(v.x);
|
||||||
t += Write<float>(v.y);
|
t += Write<float>(v.y);
|
||||||
t += Write<float>(v.z);
|
t += Write<float>(v.z);
|
||||||
|
ai_assert(t == 16);
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,9 +577,9 @@ uint32_t WriteBinaryLight(const aiLight* l)
|
||||||
len += Write<float>(l->mAttenuationQuadratic);
|
len += Write<float>(l->mAttenuationQuadratic);
|
||||||
}
|
}
|
||||||
|
|
||||||
len += Write<aiVector3D>((const aiVector3D&)l->mColorDiffuse);
|
len += Write<aiColor3D>(l->mColorDiffuse);
|
||||||
len += Write<aiVector3D>((const aiVector3D&)l->mColorSpecular);
|
len += Write<aiColor3D>(l->mColorSpecular);
|
||||||
len += Write<aiVector3D>((const aiVector3D&)l->mColorAmbient);
|
len += Write<aiColor3D>(l->mColorAmbient);
|
||||||
|
|
||||||
if (l->mType == aiLightSource_SPOT) {
|
if (l->mType == aiLightSource_SPOT) {
|
||||||
len += Write<float>(l->mAngleInnerCone);
|
len += Write<float>(l->mAngleInnerCone);
|
||||||
|
|
|
@ -561,7 +561,7 @@ void CGLView::Enable_Textures(const bool pEnable)
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
/*********************** Overrided functions ************************/
|
/*********************** Override functions ************************/
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
void CGLView::initializeGL()
|
void CGLView::initializeGL()
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue