Fixes
parent
791cb195be
commit
8ed18621db
|
@ -75,7 +75,7 @@ bool X3DImporter::isNodeEmpty(XmlNode &node) {
|
|||
}
|
||||
|
||||
void X3DImporter::checkNodeMustBeEmpty(XmlNode &node) {
|
||||
if (isNodeEmpty(node)) throw DeadlyImportError(std::string("Node <") + node.name() + "> must be empty.");
|
||||
if (!isNodeEmpty(node)) throw DeadlyImportError(std::string("Node <") + node.name() + "> must be empty.");
|
||||
}
|
||||
|
||||
void X3DImporter::skipUnsupportedNode(const std::string &pParentNodeName, XmlNode &node) {
|
||||
|
@ -321,7 +321,7 @@ void X3DImporter::readHead(XmlNode &node) {
|
|||
for (auto currentNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "meta") {
|
||||
checkNodeMustBeEmpty(node);
|
||||
//checkNodeMustBeEmpty(node);
|
||||
meta_entry entry;
|
||||
if (XmlParser::getStdStrAttribute(currentNode, "name", entry.name)) {
|
||||
XmlParser::getStdStrAttribute(currentNode, "content", entry.value);
|
||||
|
@ -339,6 +339,9 @@ void X3DImporter::readHead(XmlNode &node) {
|
|||
}
|
||||
|
||||
void X3DImporter::readChildNodes(XmlNode &node, const std::string &pParentNodeName) {
|
||||
if (node.empty()) {
|
||||
return;
|
||||
}
|
||||
for (auto currentNode : node.children()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == "Shape")
|
||||
|
@ -463,6 +466,8 @@ void X3DImporter::ParseHelper_Group_Begin(const bool pStatic) {
|
|||
}
|
||||
|
||||
void X3DImporter::ParseHelper_Node_Enter(X3DNodeElementBase *pNode) {
|
||||
ai_assert(nullptr != pNode);
|
||||
|
||||
mNodeElementCur->Children.push_back(pNode); // add new element to current element child list.
|
||||
mNodeElementCur = pNode; // switch current element to new one.
|
||||
}
|
||||
|
@ -471,6 +476,9 @@ void X3DImporter::ParseHelper_Node_Exit() {
|
|||
// check if we can walk up.
|
||||
if (mNodeElementCur != nullptr) {
|
||||
mNodeElementCur = mNodeElementCur->Parent;
|
||||
} else {
|
||||
int i = 0;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -270,6 +270,7 @@ public:
|
|||
void Clear();
|
||||
|
||||
private:
|
||||
X3DNodeElementBase *MACRO_USE_CHECKANDAPPLY(XmlNode &node, std::string pDEF, std::string pUSE, X3DElemType pType, X3DNodeElementBase *pNE);
|
||||
bool isNodeEmpty(XmlNode &node);
|
||||
void checkNodeMustBeEmpty(XmlNode &node);
|
||||
void skipUnsupportedNode(const std::string &pParentNodeName, XmlNode &node);
|
||||
|
|
|
@ -78,7 +78,7 @@ void X3DImporter::readArc2D(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Arc2D, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Arc2D, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Arc2D, mNodeElementCur);
|
||||
|
@ -138,7 +138,7 @@ void X3DImporter::readArcClose2D(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ArcClose2D, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ArcClose2D, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_ArcClose2D, mNodeElementCur);
|
||||
|
@ -185,7 +185,7 @@ void X3DImporter::readCircle2D(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Circle2D, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Circle2D, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Circle2D, mNodeElementCur);
|
||||
|
@ -234,7 +234,7 @@ void X3DImporter::readDisk2D(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Disk2D, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Disk2D, ne);
|
||||
} else {
|
||||
std::list<aiVector3D> tlist_o, tlist_i;
|
||||
|
||||
|
@ -308,7 +308,7 @@ void X3DImporter::readPolyline2D(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Polyline2D, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Polyline2D, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Polyline2D, mNodeElementCur);
|
||||
|
@ -351,7 +351,7 @@ void X3DImporter::readPolypoint2D(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Polypoint2D, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Polypoint2D, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Polypoint2D, mNodeElementCur);
|
||||
|
@ -391,7 +391,7 @@ void X3DImporter::readRectangle2D(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Rectangle2D, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Rectangle2D, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementGeometry2D(X3DElemType::ENET_Rectangle2D, mNodeElementCur);
|
||||
|
@ -437,7 +437,7 @@ void X3DImporter::readTriangleSet2D(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleSet2D, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleSet2D, ne);
|
||||
} else {
|
||||
if (vertices.size() % 3) throw DeadlyImportError("TriangleSet2D. Not enough points for defining triangle.");
|
||||
|
||||
|
|
|
@ -46,16 +46,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||
|
||||
#include "X3DGeoHelper.h"
|
||||
#include "X3DImporter.hpp"
|
||||
#include "X3DImporter_Macro.hpp"
|
||||
#include "X3DXmlHelper.h"
|
||||
#include "X3DGeoHelper.h"
|
||||
|
||||
// Header files, Assimp.
|
||||
#include <assimp/StandardShapes.h>
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace Assimp {
|
||||
|
||||
// <Box
|
||||
// DEF="" ID
|
||||
|
@ -70,34 +69,31 @@ void X3DImporter::readBox(XmlNode &node) {
|
|||
std::string def, use;
|
||||
bool solid = true;
|
||||
aiVector3D size(2, 2, 2);
|
||||
X3DNodeElementBase* ne( nullptr );
|
||||
X3DNodeElementBase *ne(nullptr);
|
||||
|
||||
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
|
||||
X3DXmlHelper::getVector3DAttribute(node, "size", size);
|
||||
XmlParser::getBoolAttribute(node, "solid", solid);
|
||||
|
||||
// if "USE" defined then find already defined element.
|
||||
if(!use.empty())
|
||||
{
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Box, ne);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!use.empty()) {
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Box, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementGeometry3D(X3DElemType::ENET_Box, mNodeElementCur);
|
||||
if(!def.empty()) ne->ID = def;
|
||||
if (!def.empty()) ne->ID = def;
|
||||
|
||||
X3DGeoHelper::rect_parallel_epiped(size, ((X3DNodeElementGeometry3D *)ne)->Vertices); // get quad list
|
||||
((X3DNodeElementGeometry3D *)ne)->Solid = solid;
|
||||
((X3DNodeElementGeometry3D *)ne)->NumIndices = 4;
|
||||
// check for X3DMetadataObject childs.
|
||||
if(!isNodeEmpty(node))
|
||||
if (!isNodeEmpty(node))
|
||||
childrenReadMetadata(node, ne, "Box");
|
||||
else
|
||||
mNodeElementCur->Children.push_back(ne);// add made object as child to current element
|
||||
mNodeElementCur->Children.push_back(ne); // add made object as child to current element
|
||||
|
||||
NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
|
||||
}// if(!use.empty()) else
|
||||
NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
|
||||
} // if(!use.empty()) else
|
||||
}
|
||||
|
||||
// <Cone
|
||||
|
@ -116,7 +112,7 @@ void X3DImporter::readCone(XmlNode &node) {
|
|||
float height = 2;
|
||||
bool side = true;
|
||||
bool solid = true;
|
||||
X3DNodeElementBase* ne( nullptr );
|
||||
X3DNodeElementBase *ne(nullptr);
|
||||
|
||||
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
|
||||
XmlParser::getBoolAttribute(node, "solid", solid);
|
||||
|
@ -126,46 +122,41 @@ void X3DImporter::readCone(XmlNode &node) {
|
|||
XmlParser::getFloatAttribute(node, "bottomRadius", bottomRadius);
|
||||
|
||||
// if "USE" defined then find already defined element.
|
||||
if(!use.empty())
|
||||
{
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Cone, ne);
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned int tess = 30;///TODO: IME tessellation factor through ai_property
|
||||
if (!use.empty()) {
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Cone, ne);
|
||||
} else {
|
||||
const unsigned int tess = 30; ///TODO: IME tessellation factor through ai_property
|
||||
|
||||
std::vector<aiVector3D> tvec;// temp array for vertices.
|
||||
std::vector<aiVector3D> tvec; // temp array for vertices.
|
||||
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementGeometry3D(X3DElemType::ENET_Cone, mNodeElementCur);
|
||||
if(!def.empty()) ne->ID = def;
|
||||
if (!def.empty()) ne->ID = def;
|
||||
|
||||
// make cone or parts according to flags.
|
||||
if(side)
|
||||
{
|
||||
if (side) {
|
||||
StandardShapes::MakeCone(height, 0, bottomRadius, tess, tvec, !bottom);
|
||||
}
|
||||
else if(bottom)
|
||||
{
|
||||
} else if (bottom) {
|
||||
StandardShapes::MakeCircle(bottomRadius, tess, tvec);
|
||||
height = -(height / 2);
|
||||
for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); ++it) it->y = height;// y - because circle made in oXZ.
|
||||
for (std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); ++it)
|
||||
it->y = height; // y - because circle made in oXZ.
|
||||
}
|
||||
|
||||
// copy data from temp array
|
||||
for (std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); ++it)
|
||||
((X3DNodeElementGeometry3D*)ne)->Vertices.push_back(*it);
|
||||
((X3DNodeElementGeometry3D *)ne)->Vertices.push_back(*it);
|
||||
|
||||
((X3DNodeElementGeometry3D *)ne)->Solid = solid;
|
||||
((X3DNodeElementGeometry3D *)ne)->NumIndices = 3;
|
||||
// check for X3DMetadataObject childs.
|
||||
if(!isNodeEmpty(node))
|
||||
if (!isNodeEmpty(node))
|
||||
childrenReadMetadata(node, ne, "Cone");
|
||||
else
|
||||
mNodeElementCur->Children.push_back(ne);// add made object as child to current element
|
||||
mNodeElementCur->Children.push_back(ne); // add made object as child to current element
|
||||
|
||||
NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
|
||||
}// if(!use.empty()) else
|
||||
NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
|
||||
} // if(!use.empty()) else
|
||||
}
|
||||
|
||||
// <Cylinder
|
||||
|
@ -186,7 +177,7 @@ void X3DImporter::readCylinder(XmlNode &node) {
|
|||
bool side = true;
|
||||
bool solid = true;
|
||||
bool top = true;
|
||||
X3DNodeElementBase* ne( nullptr );
|
||||
X3DNodeElementBase *ne(nullptr);
|
||||
|
||||
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
|
||||
XmlParser::getFloatAttribute(node, "radius", radius);
|
||||
|
@ -197,59 +188,53 @@ void X3DImporter::readCylinder(XmlNode &node) {
|
|||
XmlParser::getFloatAttribute(node, "height", height);
|
||||
|
||||
// if "USE" defined then find already defined element.
|
||||
if(!use.empty())
|
||||
{
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Cylinder, ne);
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned int tess = 30;///TODO: IME tessellation factor through ai_property
|
||||
if (!use.empty()) {
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Cylinder, ne);
|
||||
} else {
|
||||
const unsigned int tess = 30; ///TODO: IME tessellation factor through ai_property
|
||||
|
||||
std::vector<aiVector3D> tside;// temp array for vertices of side.
|
||||
std::vector<aiVector3D> tcir;// temp array for vertices of circle.
|
||||
std::vector<aiVector3D> tside; // temp array for vertices of side.
|
||||
std::vector<aiVector3D> tcir; // temp array for vertices of circle.
|
||||
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementGeometry3D(X3DElemType::ENET_Cylinder, mNodeElementCur);
|
||||
if(!def.empty()) ne->ID = def;
|
||||
if (!def.empty()) ne->ID = def;
|
||||
|
||||
// make cilynder or parts according to flags.
|
||||
if(side) StandardShapes::MakeCone(height, radius, radius, tess, tside, true);
|
||||
if (side) StandardShapes::MakeCone(height, radius, radius, tess, tside, true);
|
||||
|
||||
height /= 2;// height defined for whole cylinder, when creating top and bottom circle we are using just half of height.
|
||||
if(top || bottom) StandardShapes::MakeCircle(radius, tess, tcir);
|
||||
height /= 2; // height defined for whole cylinder, when creating top and bottom circle we are using just half of height.
|
||||
if (top || bottom) StandardShapes::MakeCircle(radius, tess, tcir);
|
||||
// copy data from temp arrays
|
||||
std::list<aiVector3D> &vlist = ((X3DNodeElementGeometry3D *)ne)->Vertices; // just short alias.
|
||||
|
||||
for(std::vector<aiVector3D>::iterator it = tside.begin(); it != tside.end(); ++it) vlist.push_back(*it);
|
||||
for (std::vector<aiVector3D>::iterator it = tside.begin(); it != tside.end(); ++it)
|
||||
vlist.push_back(*it);
|
||||
|
||||
if(top)
|
||||
{
|
||||
for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); ++it)
|
||||
{
|
||||
(*it).y = height;// y - because circle made in oXZ.
|
||||
if (top) {
|
||||
for (std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); ++it) {
|
||||
(*it).y = height; // y - because circle made in oXZ.
|
||||
vlist.push_back(*it);
|
||||
}
|
||||
}// if(top)
|
||||
} // if(top)
|
||||
|
||||
if(bottom)
|
||||
{
|
||||
for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); ++it)
|
||||
{
|
||||
(*it).y = -height;// y - because circle made in oXZ.
|
||||
if (bottom) {
|
||||
for (std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); ++it) {
|
||||
(*it).y = -height; // y - because circle made in oXZ.
|
||||
vlist.push_back(*it);
|
||||
}
|
||||
}// if(top)
|
||||
} // if(top)
|
||||
|
||||
((X3DNodeElementGeometry3D *)ne)->Solid = solid;
|
||||
((X3DNodeElementGeometry3D *)ne)->NumIndices = 3;
|
||||
// check for X3DMetadataObject childs.
|
||||
if(!isNodeEmpty(node))
|
||||
if (!isNodeEmpty(node))
|
||||
childrenReadMetadata(node, ne, "Cylinder");
|
||||
else
|
||||
mNodeElementCur->Children.push_back(ne);// add made object as child to current element
|
||||
mNodeElementCur->Children.push_back(ne); // add made object as child to current element
|
||||
|
||||
NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
|
||||
}// if(!use.empty()) else
|
||||
NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
|
||||
} // if(!use.empty()) else
|
||||
}
|
||||
|
||||
// <ElevationGrid
|
||||
|
@ -286,7 +271,7 @@ void X3DImporter::readElevationGrid(XmlNode &node) {
|
|||
float xSpacing = 1;
|
||||
int32_t zDimension = 0;
|
||||
float zSpacing = 1;
|
||||
X3DNodeElementBase* ne( nullptr );
|
||||
X3DNodeElementBase *ne(nullptr);
|
||||
|
||||
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
|
||||
XmlParser::getBoolAttribute(node, "solid", solid);
|
||||
|
@ -301,28 +286,25 @@ void X3DImporter::readElevationGrid(XmlNode &node) {
|
|||
XmlParser::getFloatAttribute(node, "zSpacing", zSpacing);
|
||||
|
||||
// if "USE" defined then find already defined element.
|
||||
if(!use.empty())
|
||||
{
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ElevationGrid, ne);
|
||||
}
|
||||
else
|
||||
{
|
||||
if((xSpacing == 0.0f) || (zSpacing == 0.0f)) throw DeadlyImportError("Spacing in <ElevationGrid> must be grater than zero.");
|
||||
if((xDimension <= 0) || (zDimension <= 0)) throw DeadlyImportError("Dimension in <ElevationGrid> must be grater than zero.");
|
||||
if (!use.empty()) {
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ElevationGrid, ne);
|
||||
} else {
|
||||
if ((xSpacing == 0.0f) || (zSpacing == 0.0f)) throw DeadlyImportError("Spacing in <ElevationGrid> must be grater than zero.");
|
||||
if ((xDimension <= 0) || (zDimension <= 0)) throw DeadlyImportError("Dimension in <ElevationGrid> must be grater than zero.");
|
||||
if ((size_t)(xDimension * zDimension) != height.size()) DeadlyImportError("Heights count must be equal to \"xDimension * zDimension\" in <ElevationGrid>");
|
||||
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementElevationGrid(X3DElemType::ENET_ElevationGrid, mNodeElementCur);
|
||||
if(!def.empty()) ne->ID = def;
|
||||
if (!def.empty()) ne->ID = def;
|
||||
|
||||
X3DNodeElementElevationGrid &grid_alias = *((X3DNodeElementElevationGrid *)ne); // create alias for conveience
|
||||
|
||||
{// create grid vertices list
|
||||
{ // create grid vertices list
|
||||
std::vector<float>::const_iterator he_it = height.begin();
|
||||
|
||||
for(int32_t zi = 0; zi < zDimension; zi++)// rows
|
||||
for (int32_t zi = 0; zi < zDimension; zi++) // rows
|
||||
{
|
||||
for(int32_t xi = 0; xi < xDimension; xi++)// columns
|
||||
for (int32_t xi = 0; xi < xDimension; xi++) // columns
|
||||
{
|
||||
aiVector3D tvec(xSpacing * xi, *he_it, zSpacing * zi);
|
||||
|
||||
|
@ -330,31 +312,28 @@ void X3DImporter::readElevationGrid(XmlNode &node) {
|
|||
++he_it;
|
||||
}
|
||||
}
|
||||
}// END: create grid vertices list
|
||||
} // END: create grid vertices list
|
||||
//
|
||||
// create faces list. In "coordIdx" format
|
||||
//
|
||||
// check if we have quads
|
||||
if((xDimension < 2) || (zDimension < 2))// only one element in dimension is set, create line set.
|
||||
if ((xDimension < 2) || (zDimension < 2)) // only one element in dimension is set, create line set.
|
||||
{
|
||||
((X3DNodeElementElevationGrid *)ne)->NumIndices = 2; // will be holded as line set.
|
||||
for(size_t i = 0, i_e = (grid_alias.Vertices.size() - 1); i < i_e; i++)
|
||||
{
|
||||
for (size_t i = 0, i_e = (grid_alias.Vertices.size() - 1); i < i_e; i++) {
|
||||
grid_alias.CoordIdx.push_back(static_cast<int32_t>(i));
|
||||
grid_alias.CoordIdx.push_back(static_cast<int32_t>(i + 1));
|
||||
grid_alias.CoordIdx.push_back(-1);
|
||||
}
|
||||
}
|
||||
else// two or more elements in every dimension is set. create quad set.
|
||||
} else // two or more elements in every dimension is set. create quad set.
|
||||
{
|
||||
((X3DNodeElementElevationGrid *)ne)->NumIndices = 4;
|
||||
for(int32_t fzi = 0, fzi_e = (zDimension - 1); fzi < fzi_e; fzi++)// rows
|
||||
for (int32_t fzi = 0, fzi_e = (zDimension - 1); fzi < fzi_e; fzi++) // rows
|
||||
{
|
||||
for(int32_t fxi = 0, fxi_e = (xDimension - 1); fxi < fxi_e; fxi++)// columns
|
||||
for (int32_t fxi = 0, fxi_e = (xDimension - 1); fxi < fxi_e; fxi++) // columns
|
||||
{
|
||||
// points direction in face.
|
||||
if(ccw)
|
||||
{
|
||||
if (ccw) {
|
||||
// CCW:
|
||||
// 3 2
|
||||
// 0 1
|
||||
|
@ -362,9 +341,7 @@ void X3DImporter::readElevationGrid(XmlNode &node) {
|
|||
grid_alias.CoordIdx.push_back((fzi + 1) * xDimension + (fxi + 1));
|
||||
grid_alias.CoordIdx.push_back(fzi * xDimension + (fxi + 1));
|
||||
grid_alias.CoordIdx.push_back(fzi * xDimension + fxi);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// CW:
|
||||
// 0 1
|
||||
// 3 2
|
||||
|
@ -372,178 +349,159 @@ void X3DImporter::readElevationGrid(XmlNode &node) {
|
|||
grid_alias.CoordIdx.push_back(fzi * xDimension + (fxi + 1));
|
||||
grid_alias.CoordIdx.push_back((fzi + 1) * xDimension + (fxi + 1));
|
||||
grid_alias.CoordIdx.push_back((fzi + 1) * xDimension + fxi);
|
||||
}// if(ccw) else
|
||||
} // if(ccw) else
|
||||
|
||||
grid_alias.CoordIdx.push_back(-1);
|
||||
}// for(int32_t fxi = 0, fxi_e = (xDimension - 1); fxi < fxi_e; fxi++)
|
||||
}// for(int32_t fzi = 0, fzi_e = (zDimension - 1); fzi < fzi_e; fzi++)
|
||||
}// if((xDimension < 2) || (zDimension < 2)) else
|
||||
} // for(int32_t fxi = 0, fxi_e = (xDimension - 1); fxi < fxi_e; fxi++)
|
||||
} // for(int32_t fzi = 0, fzi_e = (zDimension - 1); fzi < fzi_e; fzi++)
|
||||
} // if((xDimension < 2) || (zDimension < 2)) else
|
||||
|
||||
grid_alias.ColorPerVertex = colorPerVertex;
|
||||
grid_alias.NormalPerVertex = normalPerVertex;
|
||||
grid_alias.CreaseAngle = creaseAngle;
|
||||
grid_alias.Solid = solid;
|
||||
// check for child nodes
|
||||
if(!isNodeEmpty(node))
|
||||
{
|
||||
if (!isNodeEmpty(node)) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
for (auto currentChildNode : node.children()) {
|
||||
const std::string ¤tChildName = currentChildNode.name();
|
||||
// check for X3DComposedGeometryNodes
|
||||
if (currentChildName == "Color") readColor(currentChildNode);
|
||||
else if (currentChildName == "ColorRGBA") readColorRGBA(currentChildNode);
|
||||
else if (currentChildName == "Normal") readNormal(currentChildNode);
|
||||
else if (currentChildName == "TextureCoordinate") readTextureCoordinate(currentChildNode);
|
||||
if (currentChildName == "Color")
|
||||
readColor(currentChildNode);
|
||||
else if (currentChildName == "ColorRGBA")
|
||||
readColorRGBA(currentChildNode);
|
||||
else if (currentChildName == "Normal")
|
||||
readNormal(currentChildNode);
|
||||
else if (currentChildName == "TextureCoordinate")
|
||||
readTextureCoordinate(currentChildNode);
|
||||
// check for X3DMetadataObject
|
||||
else if (!checkForMetadataNode(currentChildNode)) skipUnsupportedNode("ElevationGrid", currentChildNode);
|
||||
else if (!checkForMetadataNode(currentChildNode))
|
||||
skipUnsupportedNode("ElevationGrid", currentChildNode);
|
||||
}
|
||||
ParseHelper_Node_Exit();
|
||||
}// if(!mReader->isEmptyElement())
|
||||
else
|
||||
{
|
||||
mNodeElementCur->Children.push_back(ne);// add made object as child to current element
|
||||
}// if(!mReader->isEmptyElement()) else
|
||||
} // if(!mReader->isEmptyElement())
|
||||
else {
|
||||
mNodeElementCur->Children.push_back(ne); // add made object as child to current element
|
||||
} // if(!mReader->isEmptyElement()) else
|
||||
|
||||
NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
|
||||
}// if(!use.empty()) else
|
||||
NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
|
||||
} // if(!use.empty()) else
|
||||
}
|
||||
|
||||
template<typename TVector>
|
||||
static void GeometryHelper_Extrusion_CurveIsClosed(std::vector<TVector>& pCurve, const bool pDropTail, const bool pRemoveLastPoint, bool& pCurveIsClosed)
|
||||
{
|
||||
template <typename TVector>
|
||||
static void GeometryHelper_Extrusion_CurveIsClosed(std::vector<TVector> &pCurve, const bool pDropTail, const bool pRemoveLastPoint, bool &pCurveIsClosed) {
|
||||
size_t cur_sz = pCurve.size();
|
||||
|
||||
pCurveIsClosed = false;
|
||||
// for curve with less than four points checking is have no sense,
|
||||
if(cur_sz < 4) return;
|
||||
if (cur_sz < 4) return;
|
||||
|
||||
for(size_t s = 3, s_e = cur_sz; s < s_e; s++)
|
||||
{
|
||||
for (size_t s = 3, s_e = cur_sz; s < s_e; s++) {
|
||||
// search for first point of duplicated part.
|
||||
if(pCurve[0] == pCurve[s])
|
||||
{
|
||||
if (pCurve[0] == pCurve[s]) {
|
||||
bool found = true;
|
||||
|
||||
// check if tail(indexed by b2) is duplicate of head(indexed by b1).
|
||||
for(size_t b1 = 1, b2 = (s + 1); b2 < cur_sz; b1++, b2++)
|
||||
{
|
||||
if(pCurve[b1] != pCurve[b2])
|
||||
{// points not match: clear flag and break loop.
|
||||
for (size_t b1 = 1, b2 = (s + 1); b2 < cur_sz; b1++, b2++) {
|
||||
if (pCurve[b1] != pCurve[b2]) { // points not match: clear flag and break loop.
|
||||
found = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}// for(size_t b1 = 1, b2 = (s + 1); b2 < cur_sz; b1++, b2++)
|
||||
} // for(size_t b1 = 1, b2 = (s + 1); b2 < cur_sz; b1++, b2++)
|
||||
|
||||
// if duplicate tail is found then drop or not it depending on flags.
|
||||
if(found)
|
||||
{
|
||||
if (found) {
|
||||
pCurveIsClosed = true;
|
||||
if(pDropTail)
|
||||
{
|
||||
if(!pRemoveLastPoint) s++;// prepare value for iterator's arithmetics.
|
||||
if (pDropTail) {
|
||||
if (!pRemoveLastPoint) s++; // prepare value for iterator's arithmetics.
|
||||
|
||||
pCurve.erase(pCurve.begin() + s, pCurve.end());// remove tail
|
||||
pCurve.erase(pCurve.begin() + s, pCurve.end()); // remove tail
|
||||
}
|
||||
|
||||
break;
|
||||
}// if(found)
|
||||
}// if(pCurve[0] == pCurve[s])
|
||||
}// for(size_t s = 3, s_e = (cur_sz - 1); s < s_e; s++)
|
||||
} // if(found)
|
||||
} // if(pCurve[0] == pCurve[s])
|
||||
} // for(size_t s = 3, s_e = (cur_sz - 1); s < s_e; s++)
|
||||
}
|
||||
|
||||
static aiVector3D GeometryHelper_Extrusion_GetNextY(const size_t pSpine_PointIdx, const std::vector<aiVector3D>& pSpine, const bool pSpine_Closed)
|
||||
{
|
||||
static aiVector3D GeometryHelper_Extrusion_GetNextY(const size_t pSpine_PointIdx, const std::vector<aiVector3D> &pSpine, const bool pSpine_Closed) {
|
||||
const size_t spine_idx_last = pSpine.size() - 1;
|
||||
aiVector3D tvec;
|
||||
|
||||
if((pSpine_PointIdx == 0) || (pSpine_PointIdx == spine_idx_last))// at first special cases
|
||||
if ((pSpine_PointIdx == 0) || (pSpine_PointIdx == spine_idx_last)) // at first special cases
|
||||
{
|
||||
if(pSpine_Closed)
|
||||
{// If the spine curve is closed: The SCP for the first and last points is the same and is found using (spine[1] - spine[n - 2]) to compute the Y-axis.
|
||||
if (pSpine_Closed) { // If the spine curve is closed: The SCP for the first and last points is the same and is found using (spine[1] - spine[n - 2]) to compute the Y-axis.
|
||||
// As we even for closed spine curve last and first point in pSpine are not the same: duplicates(spine[n - 1] which are equivalent to spine[0])
|
||||
// in tail are removed.
|
||||
// So, last point in pSpine is a spine[n - 2]
|
||||
tvec = pSpine[1] - pSpine[spine_idx_last];
|
||||
}
|
||||
else if(pSpine_PointIdx == 0)
|
||||
{// The Y-axis used for the first point is the vector from spine[0] to spine[1]
|
||||
} else if (pSpine_PointIdx == 0) { // The Y-axis used for the first point is the vector from spine[0] to spine[1]
|
||||
tvec = pSpine[1] - pSpine[0];
|
||||
}
|
||||
else
|
||||
{// The Y-axis used for the last point it is the vector from spine[n-2] to spine[n-1]. In our case(see above about dropping tail) spine[n - 1] is
|
||||
} else { // The Y-axis used for the last point it is the vector from spine[n-2] to spine[n-1]. In our case(see above about dropping tail) spine[n - 1] is
|
||||
// the spine[0].
|
||||
tvec = pSpine[spine_idx_last] - pSpine[spine_idx_last - 1];
|
||||
}
|
||||
}// if((pSpine_PointIdx == 0) || (pSpine_PointIdx == spine_idx_last))
|
||||
else
|
||||
{// For all points other than the first or last: The Y-axis for spine[i] is found by normalizing the vector defined by (spine[i+1] - spine[i-1]).
|
||||
} // if((pSpine_PointIdx == 0) || (pSpine_PointIdx == spine_idx_last))
|
||||
else { // For all points other than the first or last: The Y-axis for spine[i] is found by normalizing the vector defined by (spine[i+1] - spine[i-1]).
|
||||
tvec = pSpine[pSpine_PointIdx + 1] - pSpine[pSpine_PointIdx - 1];
|
||||
}// if((pSpine_PointIdx == 0) || (pSpine_PointIdx == spine_idx_last)) else
|
||||
} // if((pSpine_PointIdx == 0) || (pSpine_PointIdx == spine_idx_last)) else
|
||||
|
||||
return tvec.Normalize();
|
||||
}
|
||||
|
||||
static aiVector3D GeometryHelper_Extrusion_GetNextZ(const size_t pSpine_PointIdx, const std::vector<aiVector3D>& pSpine, const bool pSpine_Closed,
|
||||
const aiVector3D pVecZ_Prev)
|
||||
{
|
||||
static aiVector3D GeometryHelper_Extrusion_GetNextZ(const size_t pSpine_PointIdx, const std::vector<aiVector3D> &pSpine, const bool pSpine_Closed,
|
||||
const aiVector3D pVecZ_Prev) {
|
||||
const aiVector3D zero_vec(0);
|
||||
const size_t spine_idx_last = pSpine.size() - 1;
|
||||
|
||||
aiVector3D tvec;
|
||||
|
||||
// at first special cases
|
||||
if(pSpine.size() < 3)// spine have not enough points for vector calculations.
|
||||
if (pSpine.size() < 3) // spine have not enough points for vector calculations.
|
||||
{
|
||||
tvec.Set(0, 0, 1);
|
||||
}
|
||||
else if(pSpine_PointIdx == 0)// special case: first point
|
||||
} else if (pSpine_PointIdx == 0) // special case: first point
|
||||
{
|
||||
if(pSpine_Closed)// for calculating use previous point in curve s[n - 2]. In list it's a last point, because point s[n - 1] was removed as duplicate.
|
||||
if (pSpine_Closed) // for calculating use previous point in curve s[n - 2]. In list it's a last point, because point s[n - 1] was removed as duplicate.
|
||||
{
|
||||
tvec = (pSpine[1] - pSpine[0]) ^ (pSpine[spine_idx_last] - pSpine[0]);
|
||||
}
|
||||
else // for not closed curve first and next point(s[0] and s[1]) has the same vector Z.
|
||||
} else // for not closed curve first and next point(s[0] and s[1]) has the same vector Z.
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
// As said: "If the Z-axis of the first point is undefined (because the spine is not closed and the first two spine segments are collinear)
|
||||
// then the Z-axis for the first spine point with a defined Z-axis is used."
|
||||
// Walk through spine and find Z.
|
||||
for(size_t next_point = 2; (next_point <= spine_idx_last) && !found; next_point++)
|
||||
{
|
||||
for (size_t next_point = 2; (next_point <= spine_idx_last) && !found; next_point++) {
|
||||
// (pSpine[2] - pSpine[1]) ^ (pSpine[0] - pSpine[1])
|
||||
tvec = (pSpine[next_point] - pSpine[next_point - 1]) ^ (pSpine[next_point - 2] - pSpine[next_point - 1]);
|
||||
found = !tvec.Equal(zero_vec);
|
||||
}
|
||||
|
||||
// if entire spine are collinear then use OZ axis.
|
||||
if(!found) tvec.Set(0, 0, 1);
|
||||
}// if(pSpine_Closed) else
|
||||
}// else if(pSpine_PointIdx == 0)
|
||||
else if(pSpine_PointIdx == spine_idx_last)// special case: last point
|
||||
if (!found) tvec.Set(0, 0, 1);
|
||||
} // if(pSpine_Closed) else
|
||||
} // else if(pSpine_PointIdx == 0)
|
||||
else if (pSpine_PointIdx == spine_idx_last) // special case: last point
|
||||
{
|
||||
if(pSpine_Closed)
|
||||
{// do not forget that real last point s[n - 1] is removed as duplicated. And in this case we are calculating vector Z for point s[n - 2].
|
||||
if (pSpine_Closed) { // do not forget that real last point s[n - 1] is removed as duplicated. And in this case we are calculating vector Z for point s[n - 2].
|
||||
tvec = (pSpine[0] - pSpine[pSpine_PointIdx]) ^ (pSpine[pSpine_PointIdx - 1] - pSpine[pSpine_PointIdx]);
|
||||
// if taken spine vectors are collinear then use previous vector Z.
|
||||
if(tvec.Equal(zero_vec)) tvec = pVecZ_Prev;
|
||||
}
|
||||
else
|
||||
{// vector Z for last point of not closed curve is previous vector Z.
|
||||
if (tvec.Equal(zero_vec)) tvec = pVecZ_Prev;
|
||||
} else { // vector Z for last point of not closed curve is previous vector Z.
|
||||
tvec = pVecZ_Prev;
|
||||
}
|
||||
}
|
||||
else// regular point
|
||||
} else // regular point
|
||||
{
|
||||
tvec = (pSpine[pSpine_PointIdx + 1] - pSpine[pSpine_PointIdx]) ^ (pSpine[pSpine_PointIdx - 1] - pSpine[pSpine_PointIdx]);
|
||||
// if taken spine vectors are collinear then use previous vector Z.
|
||||
if(tvec.Equal(zero_vec)) tvec = pVecZ_Prev;
|
||||
if (tvec.Equal(zero_vec)) tvec = pVecZ_Prev;
|
||||
}
|
||||
|
||||
// After determining the Z-axis, its dot product with the Z-axis of the previous spine point is computed. If this value is negative, the Z-axis
|
||||
// is flipped (multiplied by -1).
|
||||
if((tvec * pVecZ_Prev) < 0) tvec = -tvec;
|
||||
if ((tvec * pVecZ_Prev) < 0) tvec = -tvec;
|
||||
|
||||
return tvec.Normalize();
|
||||
}
|
||||
|
@ -574,7 +532,7 @@ void X3DImporter::readExtrusion(XmlNode &node) {
|
|||
std::vector<aiVector2D> scale;
|
||||
bool solid = true;
|
||||
std::vector<aiVector3D> spine;
|
||||
X3DNodeElementBase* ne( nullptr );
|
||||
X3DNodeElementBase *ne(nullptr);
|
||||
|
||||
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
|
||||
XmlParser::getBoolAttribute(node, "beginCap", beginCap);
|
||||
|
@ -589,74 +547,65 @@ void X3DImporter::readExtrusion(XmlNode &node) {
|
|||
X3DXmlHelper::getVector3DArrayAttribute(node, "spine", spine);
|
||||
|
||||
// if "USE" defined then find already defined element.
|
||||
if(!use.empty())
|
||||
{
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Extrusion, ne);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!use.empty()) {
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Extrusion, ne);
|
||||
} else {
|
||||
//
|
||||
// check if default values must be assigned
|
||||
//
|
||||
if(spine.size() == 0)
|
||||
{
|
||||
if (spine.size() == 0) {
|
||||
spine.resize(2);
|
||||
spine[0].Set(0, 0, 0), spine[1].Set(0, 1, 0);
|
||||
}
|
||||
else if(spine.size() == 1)
|
||||
{
|
||||
} else if (spine.size() == 1) {
|
||||
throw DeadlyImportError("ParseNode_Geometry3D_Extrusion. Spine must have at least two points.");
|
||||
}
|
||||
|
||||
if(crossSection.size() == 0)
|
||||
{
|
||||
if (crossSection.size() == 0) {
|
||||
crossSection.resize(5);
|
||||
crossSection[0].Set(1, 1), crossSection[1].Set(1, -1), crossSection[2].Set(-1, -1), crossSection[3].Set(-1, 1), crossSection[4].Set(1, 1);
|
||||
}
|
||||
|
||||
{// orientation
|
||||
{ // orientation
|
||||
size_t ori_size = orientation.size() / 4;
|
||||
|
||||
if(ori_size < spine.size())
|
||||
{
|
||||
float add_ori[4];// values that will be added
|
||||
if (ori_size < spine.size()) {
|
||||
float add_ori[4]; // values that will be added
|
||||
|
||||
if(ori_size == 1)// if "orientation" has one element(means one MFRotation with four components) then use it value for all spine points.
|
||||
if (ori_size == 1) // if "orientation" has one element(means one MFRotation with four components) then use it value for all spine points.
|
||||
{
|
||||
add_ori[0] = orientation[0], add_ori[1] = orientation[1], add_ori[2] = orientation[2], add_ori[3] = orientation[3];
|
||||
}
|
||||
else// else - use default values
|
||||
} else // else - use default values
|
||||
{
|
||||
add_ori[0] = 0, add_ori[1] = 0, add_ori[2] = 1, add_ori[3] = 0;
|
||||
}
|
||||
|
||||
orientation.reserve(spine.size() * 4);
|
||||
for(size_t i = 0, i_e = (spine.size() - ori_size); i < i_e; i++)
|
||||
for (size_t i = 0, i_e = (spine.size() - ori_size); i < i_e; i++)
|
||||
orientation.push_back(add_ori[0]), orientation.push_back(add_ori[1]), orientation.push_back(add_ori[2]), orientation.push_back(add_ori[3]);
|
||||
}
|
||||
|
||||
if(orientation.size() % 4) throw DeadlyImportError("Attribute \"orientation\" in <Extrusion> must has multiple four quantity of numbers.");
|
||||
}// END: orientation
|
||||
if (orientation.size() % 4) throw DeadlyImportError("Attribute \"orientation\" in <Extrusion> must has multiple four quantity of numbers.");
|
||||
} // END: orientation
|
||||
|
||||
{// scale
|
||||
if(scale.size() < spine.size())
|
||||
{
|
||||
{ // scale
|
||||
if (scale.size() < spine.size()) {
|
||||
aiVector2D add_sc;
|
||||
|
||||
if(scale.size() == 1)// if "scale" has one element then use it value for all spine points.
|
||||
if (scale.size() == 1) // if "scale" has one element then use it value for all spine points.
|
||||
add_sc = scale[0];
|
||||
else// else - use default values
|
||||
else // else - use default values
|
||||
add_sc.Set(1, 1);
|
||||
|
||||
scale.reserve(spine.size());
|
||||
for(size_t i = 0, i_e = (spine.size() - scale.size()); i < i_e; i++) scale.push_back(add_sc);
|
||||
for (size_t i = 0, i_e = (spine.size() - scale.size()); i < i_e; i++)
|
||||
scale.push_back(add_sc);
|
||||
}
|
||||
}// END: scale
|
||||
} // END: scale
|
||||
//
|
||||
// create and if needed - define new geometry object.
|
||||
//
|
||||
ne = new X3DNodeElementIndexedSet(X3DElemType::ENET_Extrusion, mNodeElementCur);
|
||||
if(!def.empty()) ne->ID = def;
|
||||
if (!def.empty()) ne->ID = def;
|
||||
|
||||
X3DNodeElementIndexedSet &ext_alias = *((X3DNodeElementIndexedSet *)ne); // create alias for conveience
|
||||
// assign part of input data
|
||||
|
@ -675,28 +624,26 @@ void X3DImporter::readExtrusion(XmlNode &node) {
|
|||
// needed. While createing CootdIdx is taking in account CCW flag.
|
||||
// 4. The last step: create Vertices list.
|
||||
//
|
||||
bool spine_closed;// flag: true if spine curve is closed.
|
||||
bool cross_closed;// flag: true if cross curve is closed.
|
||||
std::vector<aiMatrix3x3> basis_arr;// array of basises. ROW_a - X, ROW_b - Y, ROW_c - Z.
|
||||
std::vector<std::vector<aiVector3D> > pointset_arr;// array of point sets: cross curves.
|
||||
bool spine_closed; // flag: true if spine curve is closed.
|
||||
bool cross_closed; // flag: true if cross curve is closed.
|
||||
std::vector<aiMatrix3x3> basis_arr; // array of basises. ROW_a - X, ROW_b - Y, ROW_c - Z.
|
||||
std::vector<std::vector<aiVector3D>> pointset_arr; // array of point sets: cross curves.
|
||||
|
||||
// detect closed curves
|
||||
GeometryHelper_Extrusion_CurveIsClosed(crossSection, true, true, cross_closed);// true - drop tail, true - remove duplicate end.
|
||||
GeometryHelper_Extrusion_CurveIsClosed(spine, true, true, spine_closed);// true - drop tail, true - remove duplicate end.
|
||||
GeometryHelper_Extrusion_CurveIsClosed(crossSection, true, true, cross_closed); // true - drop tail, true - remove duplicate end.
|
||||
GeometryHelper_Extrusion_CurveIsClosed(spine, true, true, spine_closed); // true - drop tail, true - remove duplicate end.
|
||||
// If both cap are requested and spine curve is closed then we can make only one cap. Because second cap will be the same surface.
|
||||
if(spine_closed)
|
||||
{
|
||||
if (spine_closed) {
|
||||
beginCap |= endCap;
|
||||
endCap = false;
|
||||
}
|
||||
|
||||
{// 1. Calculate array of basises.
|
||||
{ // 1. Calculate array of basises.
|
||||
aiMatrix4x4 rotmat;
|
||||
aiVector3D vecX(0), vecY(0), vecZ(0);
|
||||
|
||||
basis_arr.resize(spine.size());
|
||||
for(size_t i = 0, i_e = spine.size(); i < i_e; i++)
|
||||
{
|
||||
for (size_t i = 0, i_e = spine.size(); i < i_e; i++) {
|
||||
aiVector3D tvec;
|
||||
|
||||
// get axises of basis.
|
||||
|
@ -708,22 +655,20 @@ void X3DImporter::readExtrusion(XmlNode &node) {
|
|||
tvec = vecX, tvec *= rotmat, basis_arr[i].a1 = tvec.x, basis_arr[i].a2 = tvec.y, basis_arr[i].a3 = tvec.z;
|
||||
tvec = vecY, tvec *= rotmat, basis_arr[i].b1 = tvec.x, basis_arr[i].b2 = tvec.y, basis_arr[i].b3 = tvec.z;
|
||||
tvec = vecZ, tvec *= rotmat, basis_arr[i].c1 = tvec.x, basis_arr[i].c2 = tvec.y, basis_arr[i].c3 = tvec.z;
|
||||
}// for(size_t i = 0, i_e = spine.size(); i < i_e; i++)
|
||||
}// END: 1. Calculate array of basises
|
||||
} // for(size_t i = 0, i_e = spine.size(); i < i_e; i++)
|
||||
} // END: 1. Calculate array of basises
|
||||
|
||||
{// 2. Create array of point sets.
|
||||
{ // 2. Create array of point sets.
|
||||
aiMatrix4x4 scmat;
|
||||
std::vector<aiVector3D> tcross(crossSection.size());
|
||||
|
||||
pointset_arr.resize(spine.size());
|
||||
for(size_t spi = 0, spi_e = spine.size(); spi < spi_e; spi++)
|
||||
{
|
||||
for (size_t spi = 0, spi_e = spine.size(); spi < spi_e; spi++) {
|
||||
aiVector3D tc23vec;
|
||||
|
||||
tc23vec.Set(scale[spi].x, 0, scale[spi].y);
|
||||
aiMatrix4x4::Scaling(tc23vec, scmat);
|
||||
for(size_t cri = 0, cri_e = crossSection.size(); cri < cri_e; cri++)
|
||||
{
|
||||
for (size_t cri = 0, cri_e = crossSection.size(); cri < cri_e; cri++) {
|
||||
aiVector3D tvecX, tvecY, tvecZ;
|
||||
|
||||
tc23vec.Set(crossSection[cri].x, 0, crossSection[cri].y);
|
||||
|
@ -737,53 +682,50 @@ void X3DImporter::readExtrusion(XmlNode &node) {
|
|||
tvecZ.Set(basis_arr[spi].c1, basis_arr[spi].c2, basis_arr[spi].c3), tvecZ *= tcross[cri].z;
|
||||
// apply new coordinates and translate it to spine point.
|
||||
tcross[cri] = tvecX + tvecY + tvecZ + spine[spi];
|
||||
}// for(size_t cri = 0, cri_e = crossSection.size(); cri < cri_e; i++)
|
||||
} // for(size_t cri = 0, cri_e = crossSection.size(); cri < cri_e; i++)
|
||||
|
||||
pointset_arr[spi] = tcross;// store transferred point set
|
||||
}// for(size_t spi = 0, spi_e = spine.size(); spi < spi_e; i++)
|
||||
}// END: 2. Create array of point sets.
|
||||
pointset_arr[spi] = tcross; // store transferred point set
|
||||
} // for(size_t spi = 0, spi_e = spine.size(); spi < spi_e; i++)
|
||||
} // END: 2. Create array of point sets.
|
||||
|
||||
{// 3. Create CoordIdx.
|
||||
{ // 3. Create CoordIdx.
|
||||
// add caps if needed
|
||||
if(beginCap)
|
||||
{
|
||||
if (beginCap) {
|
||||
// add cap as polygon. vertices of cap are places at begin, so just add numbers from zero.
|
||||
for(size_t i = 0, i_e = crossSection.size(); i < i_e; i++) ext_alias.CoordIndex.push_back(static_cast<int32_t>(i));
|
||||
for (size_t i = 0, i_e = crossSection.size(); i < i_e; i++)
|
||||
ext_alias.CoordIndex.push_back(static_cast<int32_t>(i));
|
||||
|
||||
// add delimiter
|
||||
ext_alias.CoordIndex.push_back(-1);
|
||||
}// if(beginCap)
|
||||
} // if(beginCap)
|
||||
|
||||
if(endCap)
|
||||
{
|
||||
if (endCap) {
|
||||
// add cap as polygon. vertices of cap are places at end, as for beginCap use just sequence of numbers but with offset.
|
||||
size_t beg = (pointset_arr.size() - 1) * crossSection.size();
|
||||
|
||||
for(size_t i = beg, i_e = (beg + crossSection.size()); i < i_e; i++) ext_alias.CoordIndex.push_back(static_cast<int32_t>(i));
|
||||
for (size_t i = beg, i_e = (beg + crossSection.size()); i < i_e; i++)
|
||||
ext_alias.CoordIndex.push_back(static_cast<int32_t>(i));
|
||||
|
||||
// add delimiter
|
||||
ext_alias.CoordIndex.push_back(-1);
|
||||
}// if(beginCap)
|
||||
} // if(beginCap)
|
||||
|
||||
// add quads
|
||||
for(size_t spi = 0, spi_e = (spine.size() - 1); spi <= spi_e; spi++)
|
||||
{
|
||||
for (size_t spi = 0, spi_e = (spine.size() - 1); spi <= spi_e; spi++) {
|
||||
const size_t cr_sz = crossSection.size();
|
||||
const size_t cr_last = crossSection.size() - 1;
|
||||
|
||||
size_t right_col;// hold index basis for points of quad placed in right column;
|
||||
size_t right_col; // hold index basis for points of quad placed in right column;
|
||||
|
||||
if(spi != spi_e)
|
||||
if (spi != spi_e)
|
||||
right_col = spi + 1;
|
||||
else if(spine_closed)// if spine curve is closed then one more quad is needed: between first and last points of curve.
|
||||
else if (spine_closed) // if spine curve is closed then one more quad is needed: between first and last points of curve.
|
||||
right_col = 0;
|
||||
else
|
||||
break;// if spine curve is not closed then break the loop, because spi is out of range for that type of spine.
|
||||
break; // if spine curve is not closed then break the loop, because spi is out of range for that type of spine.
|
||||
|
||||
for(size_t cri = 0; cri < cr_sz; cri++)
|
||||
{
|
||||
if(cri != cr_last)
|
||||
{
|
||||
for (size_t cri = 0; cri < cr_sz; cri++) {
|
||||
if (cri != cr_last) {
|
||||
MACRO_FACE_ADD_QUAD(ccw, ext_alias.CoordIndex,
|
||||
static_cast<int32_t>(spi * cr_sz + cri),
|
||||
static_cast<int32_t>(right_col * cr_sz + cri),
|
||||
|
@ -791,8 +733,7 @@ void X3DImporter::readExtrusion(XmlNode &node) {
|
|||
static_cast<int32_t>(spi * cr_sz + cri + 1));
|
||||
// add delimiter
|
||||
ext_alias.CoordIndex.push_back(-1);
|
||||
}
|
||||
else if(cross_closed)// if cross curve is closed then one more quad is needed: between first and last points of curve.
|
||||
} else if (cross_closed) // if cross curve is closed then one more quad is needed: between first and last points of curve.
|
||||
{
|
||||
MACRO_FACE_ADD_QUAD(ccw, ext_alias.CoordIndex,
|
||||
static_cast<int32_t>(spi * cr_sz + cri),
|
||||
|
@ -802,30 +743,28 @@ void X3DImporter::readExtrusion(XmlNode &node) {
|
|||
// add delimiter
|
||||
ext_alias.CoordIndex.push_back(-1);
|
||||
}
|
||||
}// for(size_t cri = 0; cri < cr_sz; cri++)
|
||||
}// for(size_t spi = 0, spi_e = (spine.size() - 2); spi < spi_e; spi++)
|
||||
}// END: 3. Create CoordIdx.
|
||||
} // for(size_t cri = 0; cri < cr_sz; cri++)
|
||||
} // for(size_t spi = 0, spi_e = (spine.size() - 2); spi < spi_e; spi++)
|
||||
} // END: 3. Create CoordIdx.
|
||||
|
||||
{// 4. Create vertices list.
|
||||
{ // 4. Create vertices list.
|
||||
// just copy all vertices
|
||||
for(size_t spi = 0, spi_e = spine.size(); spi < spi_e; spi++)
|
||||
{
|
||||
for(size_t cri = 0, cri_e = crossSection.size(); cri < cri_e; cri++)
|
||||
{
|
||||
for (size_t spi = 0, spi_e = spine.size(); spi < spi_e; spi++) {
|
||||
for (size_t cri = 0, cri_e = crossSection.size(); cri < cri_e; cri++) {
|
||||
ext_alias.Vertices.emplace_back(pointset_arr[spi][cri]);
|
||||
}
|
||||
}
|
||||
}// END: 4. Create vertices list.
|
||||
//PrintVectorSet("Ext. CoordIdx", ext_alias.CoordIndex);
|
||||
//PrintVectorSet("Ext. Vertices", ext_alias.Vertices);
|
||||
} // END: 4. Create vertices list.
|
||||
//PrintVectorSet("Ext. CoordIdx", ext_alias.CoordIndex);
|
||||
//PrintVectorSet("Ext. Vertices", ext_alias.Vertices);
|
||||
// check for child nodes
|
||||
if(!isNodeEmpty(node))
|
||||
if (!isNodeEmpty(node))
|
||||
childrenReadMetadata(node, ne, "Extrusion");
|
||||
else
|
||||
mNodeElementCur->Children.push_back(ne);// add made object as child to current element
|
||||
mNodeElementCur->Children.push_back(ne); // add made object as child to current element
|
||||
|
||||
NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
|
||||
}// if(!use.empty()) else
|
||||
NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
|
||||
} // if(!use.empty()) else
|
||||
}
|
||||
|
||||
// <IndexedFaceSet
|
||||
|
@ -860,7 +799,7 @@ void X3DImporter::readIndexedFaceSet(XmlNode &node) {
|
|||
bool normalPerVertex = true;
|
||||
bool solid = true;
|
||||
std::vector<int32_t> texCoordIndex;
|
||||
X3DNodeElementBase* ne( nullptr );
|
||||
X3DNodeElementBase *ne(nullptr);
|
||||
|
||||
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
|
||||
XmlParser::getBoolAttribute(node, "ccw", ccw);
|
||||
|
@ -875,18 +814,15 @@ void X3DImporter::readIndexedFaceSet(XmlNode &node) {
|
|||
X3DXmlHelper::getInt32ArrayAttribute(node, "texCoordIndex", texCoordIndex);
|
||||
|
||||
// if "USE" defined then find already defined element.
|
||||
if(!use.empty())
|
||||
{
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedFaceSet, ne);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!use.empty()) {
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedFaceSet, ne);
|
||||
} else {
|
||||
// check data
|
||||
if(coordIndex.size() == 0) throw DeadlyImportError("IndexedFaceSet must contain not empty \"coordIndex\" attribute.");
|
||||
if (coordIndex.size() == 0) throw DeadlyImportError("IndexedFaceSet must contain not empty \"coordIndex\" attribute.");
|
||||
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementIndexedSet(X3DElemType::ENET_IndexedFaceSet, mNodeElementCur);
|
||||
if(!def.empty()) ne->ID = def;
|
||||
if (!def.empty()) ne->ID = def;
|
||||
|
||||
X3DNodeElementIndexedSet &ne_alias = *((X3DNodeElementIndexedSet *)ne);
|
||||
|
||||
|
@ -901,29 +837,33 @@ void X3DImporter::readIndexedFaceSet(XmlNode &node) {
|
|||
ne_alias.Solid = solid;
|
||||
ne_alias.TexCoordIndex = texCoordIndex;
|
||||
// check for child nodes
|
||||
if(!isNodeEmpty(node))
|
||||
{
|
||||
if (!isNodeEmpty(node)) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
for (auto currentChildNode : node.children()) {
|
||||
const std::string ¤tChildName = currentChildNode.name();
|
||||
// check for X3DComposedGeometryNodes
|
||||
if (currentChildName == "Color") readColor(currentChildNode);
|
||||
else if (currentChildName == "ColorRGBA") readColorRGBA(currentChildNode);
|
||||
else if (currentChildName == "Coordinate") readCoordinate(currentChildNode);
|
||||
else if (currentChildName == "Normal") readNormal(currentChildNode);
|
||||
else if (currentChildName == "TextureCoordinate") readTextureCoordinate(currentChildNode);
|
||||
if (currentChildName == "Color")
|
||||
readColor(currentChildNode);
|
||||
else if (currentChildName == "ColorRGBA")
|
||||
readColorRGBA(currentChildNode);
|
||||
else if (currentChildName == "Coordinate")
|
||||
readCoordinate(currentChildNode);
|
||||
else if (currentChildName == "Normal")
|
||||
readNormal(currentChildNode);
|
||||
else if (currentChildName == "TextureCoordinate")
|
||||
readTextureCoordinate(currentChildNode);
|
||||
// check for X3DMetadataObject
|
||||
else if (!checkForMetadataNode(currentChildNode)) skipUnsupportedNode("IndexedFaceSet", currentChildNode);
|
||||
else if (!checkForMetadataNode(currentChildNode))
|
||||
skipUnsupportedNode("IndexedFaceSet", currentChildNode);
|
||||
}
|
||||
ParseHelper_Node_Exit();
|
||||
}// if(!isNodeEmpty(node))
|
||||
else
|
||||
{
|
||||
mNodeElementCur->Children.push_back(ne);// add made object as child to current element
|
||||
} // if(!isNodeEmpty(node))
|
||||
else {
|
||||
mNodeElementCur->Children.push_back(ne); // add made object as child to current element
|
||||
}
|
||||
|
||||
NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
|
||||
}// if(!use.empty()) else
|
||||
NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
|
||||
} // if(!use.empty()) else
|
||||
}
|
||||
|
||||
// <Sphere
|
||||
|
@ -936,46 +876,42 @@ void X3DImporter::readSphere(XmlNode &node) {
|
|||
std::string use, def;
|
||||
ai_real radius = 1;
|
||||
bool solid = true;
|
||||
X3DNodeElementBase* ne( nullptr );
|
||||
X3DNodeElementBase *ne(nullptr);
|
||||
|
||||
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
|
||||
XmlParser::getFloatAttribute(node, "radius", radius);
|
||||
XmlParser::getBoolAttribute(node, "solid", solid);
|
||||
|
||||
// if "USE" defined then find already defined element.
|
||||
if(!use.empty())
|
||||
{
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Sphere, ne);
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned int tess = 3;///TODO: IME tessellation factor through ai_property
|
||||
if (!use.empty()) {
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Sphere, ne);
|
||||
} else {
|
||||
const unsigned int tess = 3; ///TODO: IME tessellation factor through ai_property
|
||||
|
||||
std::vector<aiVector3D> tlist;
|
||||
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementGeometry3D(X3DElemType::ENET_Sphere, mNodeElementCur);
|
||||
if(!def.empty()) ne->ID = def;
|
||||
if (!def.empty()) ne->ID = def;
|
||||
|
||||
StandardShapes::MakeSphere(tess, tlist);
|
||||
// copy data from temp array and apply scale
|
||||
for(std::vector<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); ++it)
|
||||
{
|
||||
for (std::vector<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); ++it) {
|
||||
((X3DNodeElementGeometry3D *)ne)->Vertices.push_back(*it * radius);
|
||||
}
|
||||
|
||||
((X3DNodeElementGeometry3D *)ne)->Solid = solid;
|
||||
((X3DNodeElementGeometry3D *)ne)->NumIndices = 3;
|
||||
// check for X3DMetadataObject childs.
|
||||
if(!isNodeEmpty(node))
|
||||
if (!isNodeEmpty(node))
|
||||
childrenReadMetadata(node, ne, "Sphere");
|
||||
else
|
||||
mNodeElementCur->Children.push_back(ne);// add made object as child to current element
|
||||
mNodeElementCur->Children.push_back(ne); // add made object as child to current element
|
||||
|
||||
NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
|
||||
}// if(!use.empty()) else
|
||||
NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
|
||||
} // if(!use.empty()) else
|
||||
}
|
||||
|
||||
}// namespace Assimp
|
||||
} // namespace Assimp
|
||||
|
||||
#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||
|
|
|
@ -72,9 +72,8 @@ void X3DImporter::startReadGroup(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
X3DNodeElementBase *ne;
|
||||
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
|
||||
X3DNodeElementBase *ne = nullptr;
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
|
||||
} else {
|
||||
ParseHelper_Group_Begin(); // create new grouping element and go deeper if node has children.
|
||||
// at this place new group mode created and made current, so we can name it.
|
||||
|
@ -111,9 +110,9 @@ void X3DImporter::startReadStaticGroup(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
X3DNodeElementBase *ne;
|
||||
X3DNodeElementBase *ne = nullptr;
|
||||
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
|
||||
} else {
|
||||
ParseHelper_Group_Begin(true); // create new grouping element and go deeper if node has children.
|
||||
// at this place new group mode created and made current, so we can name it.
|
||||
|
@ -154,9 +153,9 @@ void X3DImporter::startReadSwitch(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
X3DNodeElementBase *ne;
|
||||
X3DNodeElementBase *ne=nullptr;
|
||||
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
|
||||
} else {
|
||||
ParseHelper_Group_Begin(); // create new grouping element and go deeper if node has children.
|
||||
// at this place new group mode created and made current, so we can name it.
|
||||
|
@ -228,7 +227,7 @@ void X3DImporter::startReadTransform(XmlNode &node) {
|
|||
if (!use.empty()) {
|
||||
X3DNodeElementBase *ne(nullptr);
|
||||
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
|
||||
} else {
|
||||
ParseHelper_Group_Begin(); // create new grouping element and go deeper if node has children.
|
||||
// at this place new group mode created and made current, so we can name it.
|
||||
|
|
|
@ -83,7 +83,7 @@ void X3DImporter::readDirectionalLight(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_DirectionalLight, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_DirectionalLight, ne);
|
||||
} else {
|
||||
if (on) {
|
||||
// create and if needed - define new geometry object.
|
||||
|
@ -150,7 +150,7 @@ void X3DImporter::readPointLight(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_PointLight, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_PointLight, ne);
|
||||
} else {
|
||||
if (on) {
|
||||
// create and if needed - define new geometry object.
|
||||
|
@ -227,7 +227,7 @@ void X3DImporter::readSpotLight(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_SpotLight, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_SpotLight, ne);
|
||||
} else {
|
||||
if (on) {
|
||||
// create and if needed - define new geometry object.
|
||||
|
|
|
@ -47,20 +47,36 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef X3DIMPORTER_MACRO_HPP_INCLUDED
|
||||
#define X3DIMPORTER_MACRO_HPP_INCLUDED
|
||||
|
||||
/// \def MACRO_USE_CHECKANDAPPLY(pDEF, pUSE, pNE)
|
||||
#include <assimp/XmlParser.h>
|
||||
#include "X3DImporter.hpp"
|
||||
#include <string>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
/// Used for regular checking while attribute "USE" is defined.
|
||||
/// \param [in] pNode - pugi xml node to read.
|
||||
/// \param [in] pDEF - string holding "DEF" value.
|
||||
/// \param [in] pUSE - string holding "USE" value.
|
||||
/// \param [in] pType - type of element to find.
|
||||
/// \param [out] pNE - pointer to found node element.
|
||||
#define MACRO_USE_CHECKANDAPPLY(pNode, pDEF, pUSE, pType, pNE) \
|
||||
do { \
|
||||
checkNodeMustBeEmpty(pNode); \
|
||||
if (!pDEF.empty()) Throw_DEF_And_USE(pNode.name()); \
|
||||
if (!FindNodeElement(pUSE, X3DElemType::pType, &pNE)) Throw_USE_NotFound(pNode.name(), pUSE); \
|
||||
mNodeElementCur->Children.push_back(pNE); /* add found object as child to current element */ \
|
||||
} while (false)
|
||||
inline X3DNodeElementBase *X3DImporter::MACRO_USE_CHECKANDAPPLY(XmlNode &node, std::string pDEF, std::string pUSE, X3DElemType pType, X3DNodeElementBase *pNE) {
|
||||
if (nullptr == mNodeElementCur) {
|
||||
printf("here\n");
|
||||
}
|
||||
|
||||
//do {
|
||||
checkNodeMustBeEmpty(node);
|
||||
if (!pDEF.empty())
|
||||
Assimp::Throw_DEF_And_USE(node.name());
|
||||
if (!FindNodeElement(pUSE, pType, &pNE))
|
||||
Assimp::Throw_USE_NotFound(node.name(), pUSE);
|
||||
mNodeElementCur->Children.push_back(pNE); /* add found object as child to current element */
|
||||
//} while (false);
|
||||
|
||||
return pNE;
|
||||
}
|
||||
|
||||
} // namespace Assimp
|
||||
|
||||
/// \def MACRO_ATTRREAD_CHECKUSEDEF_RET
|
||||
/// Compact variant for checking "USE" and "DEF".
|
||||
|
|
|
@ -93,7 +93,7 @@ void X3DImporter::childrenReadMetadata(XmlNode &node, X3DNodeElementBase *pParen
|
|||
#define MACRO_METADATA_FINDCREATE(pNode, pDEF_Var, pUSE_Var, pReference, pValue, pNE, pMetaClass, pMetaName, pType) \
|
||||
/* if "USE" defined then find already defined element. */ \
|
||||
if (!pUSE_Var.empty()) { \
|
||||
MACRO_USE_CHECKANDAPPLY(pNode, pDEF_Var, pUSE_Var, pType, pNE); \
|
||||
ne = MACRO_USE_CHECKANDAPPLY(pNode, pDEF_Var, pUSE_Var, pType, pNE); \
|
||||
} else { \
|
||||
pNE = new pMetaClass(mNodeElementCur); \
|
||||
if (!pDEF_Var.empty()) pNE->ID = pDEF_Var; \
|
||||
|
@ -213,13 +213,13 @@ void X3DImporter::readMetadataSet(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_MetaSet, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_MetaSet, ne);
|
||||
} else {
|
||||
ne = new X3DNodeElementMetaSet(mNodeElementCur);
|
||||
if (!def.empty()) ne->ID = def;
|
||||
|
||||
((X3DNodeElementMetaSet *)ne)->Reference = reference;
|
||||
// also metadata node can contain childs
|
||||
// also metadata node can contain children
|
||||
if (!isNodeEmpty(node))
|
||||
childrenReadMetadata(node, ne, "MetadataSet");
|
||||
else
|
||||
|
|
|
@ -78,10 +78,9 @@ void X3DImporter::readInline(XmlNode &node) {
|
|||
X3DXmlHelper::getStringListAttribute(node, "url", url);
|
||||
|
||||
// if "USE" defined then find already defined element.
|
||||
X3DNodeElementBase *ne = nullptr;
|
||||
if (!use.empty()) {
|
||||
X3DNodeElementBase *ne;
|
||||
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne);
|
||||
} else {
|
||||
ParseHelper_Group_Begin(true); // create new grouping element and go deeper if node has children.
|
||||
// at this place new group mode created and made current, so we can name it.
|
||||
|
|
|
@ -67,7 +67,7 @@ void X3DImporter::readColor(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Color, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Color, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementColor(mNodeElementCur);
|
||||
|
@ -99,7 +99,7 @@ void X3DImporter::readColorRGBA(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ColorRGBA, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ColorRGBA, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementColorRGBA(mNodeElementCur);
|
||||
|
@ -131,7 +131,7 @@ void X3DImporter::readCoordinate(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Coordinate, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Coordinate, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementCoordinate(mNodeElementCur);
|
||||
|
@ -174,7 +174,7 @@ void X3DImporter::readIndexedLineSet(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedLineSet, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedLineSet, ne);
|
||||
} else {
|
||||
// check data
|
||||
if ((coordIndex.size() < 2) || ((coordIndex.back() == (-1)) && (coordIndex.size() < 3)))
|
||||
|
@ -248,7 +248,7 @@ void X3DImporter::readIndexedTriangleFanSet(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedTriangleFanSet, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedTriangleFanSet, ne);
|
||||
} else {
|
||||
// check data
|
||||
if (index.size() == 0) throw DeadlyImportError("IndexedTriangleFanSet must contain not empty \"index\" attribute.");
|
||||
|
@ -354,7 +354,7 @@ void X3DImporter::readIndexedTriangleSet(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedTriangleSet, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedTriangleSet, ne);
|
||||
} else {
|
||||
// check data
|
||||
if (index.size() == 0) throw DeadlyImportError("IndexedTriangleSet must contain not empty \"index\" attribute.");
|
||||
|
@ -453,10 +453,12 @@ void X3DImporter::readIndexedTriangleStripSet(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedTriangleStripSet, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_IndexedTriangleStripSet, ne);
|
||||
} else {
|
||||
// check data
|
||||
if (index.size() == 0) throw DeadlyImportError("IndexedTriangleStripSet must contain not empty \"index\" attribute.");
|
||||
if (index.empty()) {
|
||||
throw DeadlyImportError("IndexedTriangleStripSet must contain not empty \"index\" attribute.");
|
||||
}
|
||||
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementIndexedSet(X3DElemType::ENET_IndexedTriangleStripSet, mNodeElementCur);
|
||||
|
@ -544,10 +546,12 @@ void X3DImporter::readLineSet(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_LineSet, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_LineSet, ne);
|
||||
} else {
|
||||
// check data
|
||||
if (vertexCount.size() == 0) throw DeadlyImportError("LineSet must contain not empty \"vertexCount\" attribute.");
|
||||
if (vertexCount.empty()) {
|
||||
throw DeadlyImportError("LineSet must contain not empty \"vertexCount\" attribute.");
|
||||
}
|
||||
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementSet(X3DElemType::ENET_LineSet, mNodeElementCur);
|
||||
|
@ -612,7 +616,7 @@ void X3DImporter::readPointSet(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_PointSet, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_PointSet, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementIndexedSet(X3DElemType::ENET_PointSet, mNodeElementCur);
|
||||
|
@ -677,10 +681,12 @@ void X3DImporter::readTriangleFanSet(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleFanSet, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleFanSet, ne);
|
||||
} else {
|
||||
// check data
|
||||
if (fanCount.size() == 0) throw DeadlyImportError("TriangleFanSet must contain not empty \"fanCount\" attribute.");
|
||||
if (fanCount.empty()) {
|
||||
throw DeadlyImportError("TriangleFanSet must contain not empty \"fanCount\" attribute.");
|
||||
}
|
||||
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementSet(X3DElemType::ENET_TriangleFanSet, mNodeElementCur);
|
||||
|
@ -784,7 +790,7 @@ void X3DImporter::readTriangleSet(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleSet, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleSet, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementIndexedSet(X3DElemType::ENET_TriangleSet, mNodeElementCur);
|
||||
|
@ -859,7 +865,7 @@ void X3DImporter::readTriangleStripSet(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleStripSet, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TriangleStripSet, ne);
|
||||
} else {
|
||||
// check data
|
||||
if (stripCount.size() == 0) throw DeadlyImportError("TriangleStripSet must contain not empty \"stripCount\" attribute.");
|
||||
|
@ -958,14 +964,14 @@ void X3DImporter::readTriangleStripSet(XmlNode &node) {
|
|||
void X3DImporter::readNormal(XmlNode &node) {
|
||||
std::string use, def;
|
||||
std::list<aiVector3D> vector;
|
||||
X3DNodeElementBase *ne;
|
||||
X3DNodeElementBase *ne=nullptr;
|
||||
|
||||
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
|
||||
X3DXmlHelper::getVector3DListAttribute(node, "vector", vector);
|
||||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Normal, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Normal, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementNormal(mNodeElementCur);
|
||||
|
|
|
@ -60,7 +60,7 @@ void X3DImporter::readShape(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Shape, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Shape, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementShape(mNodeElementCur);
|
||||
|
@ -74,31 +74,55 @@ void X3DImporter::readShape(XmlNode &node) {
|
|||
// check for appearance node
|
||||
if (currentChildName == "Appearance") readAppearance(currentChildNode);
|
||||
// check for X3DGeometryNodes
|
||||
else if (currentChildName == "Arc2D") readArc2D(currentChildNode);
|
||||
else if (currentChildName == "ArcClose2D") readArcClose2D(currentChildNode);
|
||||
else if (currentChildName == "Circle2D") readCircle2D(currentChildNode);
|
||||
else if (currentChildName == "Disk2D") readDisk2D(currentChildNode);
|
||||
else if (currentChildName == "Polyline2D") readPolyline2D(currentChildNode);
|
||||
else if (currentChildName == "Polypoint2D") readPolypoint2D(currentChildNode);
|
||||
else if (currentChildName == "Rectangle2D") readRectangle2D(currentChildNode);
|
||||
else if (currentChildName == "TriangleSet2D") readTriangleSet2D(currentChildNode);
|
||||
else if (currentChildName == "Box") readBox(currentChildNode);
|
||||
else if (currentChildName == "Cone") readCone(currentChildNode);
|
||||
else if (currentChildName == "Cylinder") readCylinder(currentChildNode);
|
||||
else if (currentChildName == "ElevationGrid") readElevationGrid(currentChildNode);
|
||||
else if (currentChildName == "Extrusion") readExtrusion(currentChildNode);
|
||||
else if (currentChildName == "IndexedFaceSet") readIndexedFaceSet(currentChildNode);
|
||||
else if (currentChildName == "Sphere") readSphere(currentChildNode);
|
||||
else if (currentChildName == "IndexedLineSet") readIndexedLineSet(currentChildNode);
|
||||
else if (currentChildName == "LineSet") readLineSet(currentChildNode);
|
||||
else if (currentChildName == "PointSet") readPointSet(currentChildNode);
|
||||
else if (currentChildName == "IndexedTriangleFanSet") readIndexedTriangleFanSet(currentChildNode);
|
||||
else if (currentChildName == "IndexedTriangleSet") readIndexedTriangleSet(currentChildNode);
|
||||
else if (currentChildName == "IndexedTriangleStripSet") readIndexedTriangleStripSet(currentChildNode);
|
||||
else if (currentChildName == "TriangleFanSet") readTriangleFanSet(currentChildNode);
|
||||
else if (currentChildName == "TriangleSet") readTriangleSet(currentChildNode);
|
||||
else if (currentChildName == "Arc2D")
|
||||
readArc2D(currentChildNode);
|
||||
else if (currentChildName == "ArcClose2D")
|
||||
readArcClose2D(currentChildNode);
|
||||
else if (currentChildName == "Circle2D")
|
||||
readCircle2D(currentChildNode);
|
||||
else if (currentChildName == "Disk2D")
|
||||
readDisk2D(currentChildNode);
|
||||
else if (currentChildName == "Polyline2D")
|
||||
readPolyline2D(currentChildNode);
|
||||
else if (currentChildName == "Polypoint2D")
|
||||
readPolypoint2D(currentChildNode);
|
||||
else if (currentChildName == "Rectangle2D")
|
||||
readRectangle2D(currentChildNode);
|
||||
else if (currentChildName == "TriangleSet2D")
|
||||
readTriangleSet2D(currentChildNode);
|
||||
else if (currentChildName == "Box")
|
||||
readBox(currentChildNode);
|
||||
else if (currentChildName == "Cone")
|
||||
readCone(currentChildNode);
|
||||
else if (currentChildName == "Cylinder")
|
||||
readCylinder(currentChildNode);
|
||||
else if (currentChildName == "ElevationGrid")
|
||||
readElevationGrid(currentChildNode);
|
||||
else if (currentChildName == "Extrusion")
|
||||
readExtrusion(currentChildNode);
|
||||
else if (currentChildName == "IndexedFaceSet")
|
||||
readIndexedFaceSet(currentChildNode);
|
||||
else if (currentChildName == "Sphere")
|
||||
readSphere(currentChildNode);
|
||||
else if (currentChildName == "IndexedLineSet")
|
||||
readIndexedLineSet(currentChildNode);
|
||||
else if (currentChildName == "LineSet")
|
||||
readLineSet(currentChildNode);
|
||||
else if (currentChildName == "PointSet")
|
||||
readPointSet(currentChildNode);
|
||||
else if (currentChildName == "IndexedTriangleFanSet")
|
||||
readIndexedTriangleFanSet(currentChildNode);
|
||||
else if (currentChildName == "IndexedTriangleSet")
|
||||
readIndexedTriangleSet(currentChildNode);
|
||||
else if (currentChildName == "IndexedTriangleStripSet")
|
||||
readIndexedTriangleStripSet(currentChildNode);
|
||||
else if (currentChildName == "TriangleFanSet")
|
||||
readTriangleFanSet(currentChildNode);
|
||||
else if (currentChildName == "TriangleSet")
|
||||
readTriangleSet(currentChildNode);
|
||||
// check for X3DMetadataObject
|
||||
else if (!checkForMetadataNode(currentChildNode)) skipUnsupportedNode("Shape", currentChildNode);
|
||||
else if (!checkForMetadataNode(currentChildNode))
|
||||
skipUnsupportedNode("Shape", currentChildNode);
|
||||
}
|
||||
|
||||
ParseHelper_Node_Exit();
|
||||
|
@ -123,42 +147,41 @@ void X3DImporter::readShape(XmlNode &node) {
|
|||
// </Appearance>
|
||||
void X3DImporter::readAppearance(XmlNode &node) {
|
||||
std::string use, def;
|
||||
X3DNodeElementBase* ne( nullptr );
|
||||
X3DNodeElementBase *ne(nullptr);
|
||||
|
||||
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
|
||||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty())
|
||||
{
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Appearance, ne);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!use.empty()) {
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Appearance, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementAppearance(mNodeElementCur);
|
||||
if(!def.empty()) ne->ID = def;
|
||||
if (!def.empty()) ne->ID = def;
|
||||
|
||||
// check for child nodes
|
||||
if(!isNodeEmpty(node))
|
||||
{
|
||||
if (!isNodeEmpty(node)) {
|
||||
ParseHelper_Node_Enter(ne);
|
||||
for (auto currentChildNode : node.children()) {
|
||||
const std::string ¤tChildName = currentChildNode.name();
|
||||
if (currentChildName == "Material") readMaterial(currentChildNode);
|
||||
else if (currentChildName == "ImageTexture") readImageTexture(currentChildNode);
|
||||
else if (currentChildName == "TextureTransform") readTextureTransform(currentChildNode);
|
||||
if (currentChildName == "Material")
|
||||
readMaterial(currentChildNode);
|
||||
else if (currentChildName == "ImageTexture")
|
||||
readImageTexture(currentChildNode);
|
||||
else if (currentChildName == "TextureTransform")
|
||||
readTextureTransform(currentChildNode);
|
||||
// check for X3DMetadataObject
|
||||
else if (!checkForMetadataNode(currentChildNode)) skipUnsupportedNode("Appearance", currentChildNode);
|
||||
else if (!checkForMetadataNode(currentChildNode))
|
||||
skipUnsupportedNode("Appearance", currentChildNode);
|
||||
}
|
||||
ParseHelper_Node_Exit();
|
||||
}// if(!isNodeEmpty(node))
|
||||
else
|
||||
{
|
||||
mNodeElementCur->Children.push_back(ne);// add made object as child to current element
|
||||
} // if(!isNodeEmpty(node))
|
||||
else {
|
||||
mNodeElementCur->Children.push_back(ne); // add made object as child to current element
|
||||
}
|
||||
|
||||
NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
|
||||
}// if(!use.empty()) else
|
||||
NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
|
||||
} // if(!use.empty()) else
|
||||
}
|
||||
|
||||
// <Material
|
||||
|
@ -179,7 +202,7 @@ void X3DImporter::readMaterial(XmlNode &node) {
|
|||
aiColor3D diffuseColor(0.8f, 0.8f, 0.8f);
|
||||
aiColor3D emissiveColor(0, 0, 0);
|
||||
aiColor3D specularColor(0, 0, 0);
|
||||
X3DNodeElementBase* ne( nullptr );
|
||||
X3DNodeElementBase *ne(nullptr);
|
||||
|
||||
MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
|
||||
XmlParser::getFloatAttribute(node, "ambientIntensity", ambientIntensity);
|
||||
|
@ -190,15 +213,12 @@ void X3DImporter::readMaterial(XmlNode &node) {
|
|||
X3DXmlHelper::getColor3DAttribute(node, "specularColor", specularColor);
|
||||
|
||||
// if "USE" defined then find already defined element.
|
||||
if(!use.empty())
|
||||
{
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Material, ne);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!use.empty()) {
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Material, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementMaterial(mNodeElementCur);
|
||||
if(!def.empty()) ne->ID = def;
|
||||
if (!def.empty()) ne->ID = def;
|
||||
|
||||
((X3DNodeElementMaterial *)ne)->AmbientIntensity = ambientIntensity;
|
||||
((X3DNodeElementMaterial *)ne)->Shininess = shininess;
|
||||
|
@ -207,15 +227,15 @@ void X3DImporter::readMaterial(XmlNode &node) {
|
|||
((X3DNodeElementMaterial *)ne)->EmissiveColor = emissiveColor;
|
||||
((X3DNodeElementMaterial *)ne)->SpecularColor = specularColor;
|
||||
// check for child nodes
|
||||
if(!isNodeEmpty(node))
|
||||
if (!isNodeEmpty(node))
|
||||
childrenReadMetadata(node, ne, "Material");
|
||||
else
|
||||
mNodeElementCur->Children.push_back(ne); // add made object as child to current element
|
||||
|
||||
NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
|
||||
}// if(!use.empty()) else
|
||||
NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
|
||||
} // if(!use.empty()) else
|
||||
}
|
||||
|
||||
}// namespace Assimp
|
||||
} // namespace Assimp
|
||||
|
||||
#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||
|
|
|
@ -74,7 +74,7 @@ void X3DImporter::readImageTexture(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ImageTexture, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_ImageTexture, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementImageTexture(mNodeElementCur);
|
||||
|
@ -113,7 +113,7 @@ void X3DImporter::readTextureCoordinate(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TextureCoordinate, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TextureCoordinate, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementTextureCoordinate(mNodeElementCur);
|
||||
|
@ -154,7 +154,7 @@ void X3DImporter::readTextureTransform(XmlNode &node) {
|
|||
|
||||
// if "USE" defined then find already defined element.
|
||||
if (!use.empty()) {
|
||||
MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TextureTransform, ne);
|
||||
ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_TextureTransform, ne);
|
||||
} else {
|
||||
// create and if needed - define new geometry object.
|
||||
ne = new X3DNodeElementTextureTransform(mNodeElementCur);
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "https://www.web3d.org/specifications/x3d-3.0.dtd">
|
||||
<X3D profile='Immersive' version='3.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-3.0.xsd'>
|
||||
<!-- X3D™ is a trademark of the Web3D Consortium Incorporated, standing for Extensible 3D Graphics (X3D). -->
|
||||
<head>
|
||||
<meta content='HelloX3dTrademark.x3d' name='title'/>
|
||||
<meta content='Don Brutzman' name='creator'/>
|
||||
<meta content='6 June 2001' name='created'/>
|
||||
<meta content='20 October 2019' name='modified'/>
|
||||
<meta content='Simple example showing spinning globe and X3D&#8482; trademark text. X3D (tm) is a trademark of the Web3D Consortium Inc. X3D stands for Extensible 3D Graphics (X3D), an encoding of VRML using XML. X3D has been defined since 1998. Trademark registration pending. VRML is the Virtual Reality Modeling Language (VRML), International Standard ISO/IEC 14772-1:1997. XML is the Extensible Markup Language (XML), a Recommendation of the World Wide Web Consortium (W3C).' name='description'/>
|
||||
<meta content='HelloX3dTrademark.png' name='Image'/>
|
||||
<meta content='https://www.web3d.org' name='reference'/>
|
||||
<meta content='https://www.web3d.org/x3d' name='reference'/>
|
||||
<meta content='https://www.web3d.org/Specifications/VRML97' name='reference'/>
|
||||
<meta content='http://www.w3.org/XML' name='reference'/>
|
||||
<meta content='https://www.web3d.org/x3d/content/examples/Basic/development/HelloX3dTrademark.x3d' name='identifier'/>
|
||||
<meta content='X3D-Edit 3.3, https://savage.nps.edu/X3D-Edit' name='generator'/>
|
||||
<meta content='../license.html' name='license'/>
|
||||
</head>
|
||||
<Scene>
|
||||
<WorldInfo info='"an introductory scene"' title='Hello X3D&#8482; Trademark (tm)'/>
|
||||
<Viewpoint description='Hello, world' orientation='0 1 0 3.14159' position='0 0 -8'/>
|
||||
<Transform DEF='EarthCoordinateSystem'>
|
||||
<Group DEF='MiniWorld'>
|
||||
<Shape>
|
||||
<Appearance>
|
||||
<ImageTexture url='"earth-topo.png" "earth-topo.gif" "earth-topo-small.gif" "https://www.web3d.org/x3d/content/examples/Basic/development/earth-topo.png" "https://www.web3d.org/x3d/content/examples/Basic/development/earth-topo.gif" "https://www.web3d.org/x3d/content/examples/Basic/development/earth-topo-small.gif"'/>
|
||||
</Appearance>
|
||||
<Sphere DEF='GlobeNotToScale'/>
|
||||
</Shape>
|
||||
</Group>
|
||||
<Transform DEF='SimpleGeoStationarySatellite' scale='0.1 0.3 0.1' translation='0 0 4'>
|
||||
<Shape>
|
||||
<Appearance>
|
||||
<Material diffuseColor='0.9 0.1 0.1'/>
|
||||
</Appearance>
|
||||
<Text string='"Hello" "X3D Trademark (tm)"'>
|
||||
<FontStyle justify='"MIDDLE" "MIDDLE"' size='3'/>
|
||||
</Text>
|
||||
</Shape>
|
||||
</Transform>
|
||||
</Transform>
|
||||
<TimeSensor DEF='OrbitalTimeInterval' cycleInterval='12.0' loop='true'/>
|
||||
<OrientationInterpolator DEF='SpinThoseThings' key='0.00 0.25 0.50 0.75 1.00' keyValue='0 1 0 0 0 1 0 1.57079 0 1 0 3.14159 0 1 0 4.7123889 0 1 0 6.2831852'/>
|
||||
<ROUTE fromField='fraction_changed' fromNode='OrbitalTimeInterval' toField='set_fraction' toNode='SpinThoseThings'/>
|
||||
<ROUTE fromField='value_changed' fromNode='SpinThoseThings' toField='rotation' toNode='EarthCoordinateSystem'/>
|
||||
</Scene>
|
||||
</X3D>
|
BIN
test/test.3mf
BIN
test/test.3mf
Binary file not shown.
|
@ -49,7 +49,7 @@ using namespace Assimp;
|
|||
|
||||
class utX3DImportExport : public AbstractImportExportBase {
|
||||
public:
|
||||
virtual bool importerTest() {
|
||||
bool importerTest() override {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/X3D/ComputerKeyboard.x3d", aiProcess_ValidateDataStructure);
|
||||
return nullptr != scene;
|
||||
|
|
Loading…
Reference in New Issue