diff options
author | sanine <sanine.not@pm.me> | 2022-04-16 11:55:09 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2022-04-16 11:55:09 -0500 |
commit | db81b925d776103326128bf629cbdda576a223e7 (patch) | |
tree | 58bea8155c686733310009f6bed7363f91fbeb9d /libs/assimp/code/AssetLib/X3D/X3DImporter_Group.cpp | |
parent | 55860037b14fb3893ba21cf2654c83d349cc1082 (diff) |
move 3rd-party librarys into libs/ and add built-in honeysuckle
Diffstat (limited to 'libs/assimp/code/AssetLib/X3D/X3DImporter_Group.cpp')
-rw-r--r-- | libs/assimp/code/AssetLib/X3D/X3DImporter_Group.cpp | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/libs/assimp/code/AssetLib/X3D/X3DImporter_Group.cpp b/libs/assimp/code/AssetLib/X3D/X3DImporter_Group.cpp new file mode 100644 index 0000000..e7a2e91 --- /dev/null +++ b/libs/assimp/code/AssetLib/X3D/X3DImporter_Group.cpp @@ -0,0 +1,277 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2019, 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. + +---------------------------------------------------------------------- +*/ +/// \file X3DImporter_Group.cpp +/// \brief Parsing data from nodes of "Grouping" set of X3D. +/// date 2015-2016 +/// author smal.root@gmail.com + +#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER + +#include "X3DImporter.hpp" +#include "X3DImporter_Macro.hpp" +#include "X3DXmlHelper.h" + +namespace Assimp { + +// <Group +// DEF="" ID +// USE="" IDREF +// bboxCenter="0 0 0" SFVec3f [initializeOnly] +// bboxSize="-1 -1 -1" SFVec3f [initializeOnly] +// > +// <\!-- ChildContentModel --> +// ChildContentModel is the child-node content model corresponding to X3DChildNode, combining all profiles. ChildContentModel can contain most nodes, +// other Grouping nodes, Prototype declarations and ProtoInstances in any order and any combination. When the assigned profile is less than Full, the +// precise palette of legal nodes that are available depends on assigned profile and components. +// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. +// </Group> +// A Group node contains children nodes without introducing a new transformation. It is equivalent to a Transform node containing an identity transform. +void X3DImporter::startReadGroup(XmlNode &node) { + std::string def, use; + + MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use); + + // if "USE" defined then find already defined element. + if (!use.empty()) { + 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. + if (!def.empty()) mNodeElementCur->ID = def; + // in grouping set of nodes check X3DMetadataObject is not needed, because it is done in <Scene> parser function. + + // for empty element exit from node in that place + if (isNodeEmpty(node)) ParseHelper_Node_Exit(); + } // if(!use.empty()) else +} + +void X3DImporter::endReadGroup() { + ParseHelper_Node_Exit(); // go up in scene graph +} + +// <StaticGroup +// DEF="" ID +// USE="" IDREF +// bboxCenter="0 0 0" SFVec3f [initializeOnly] +// bboxSize="-1 -1 -1" SFVec3f [initializeOnly] +// > +// <\!-- ChildContentModel --> +// ChildContentModel is the child-node content model corresponding to X3DChildNode, combining all profiles. ChildContentModel can contain most nodes, +// other Grouping nodes, Prototype declarations and ProtoInstances in any order and any combination. When the assigned profile is less than Full, the +// precise palette of legal nodes that are available depends on assigned profile and components. +// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. +// </StaticGroup> +// The StaticGroup node contains children nodes which cannot be modified. StaticGroup children are guaranteed to not change, send events, receive events or +// contain any USE references outside the StaticGroup. +void X3DImporter::startReadStaticGroup(XmlNode &node) { + std::string def, use; + + MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use); + + // if "USE" defined then find already defined element. + if (!use.empty()) { + X3DNodeElementBase *ne(nullptr); + + 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. + if (!def.empty()) mNodeElementCur->ID = def; + // in grouping set of nodes check X3DMetadataObject is not needed, because it is done in <Scene> parser function. + + // for empty element exit from node in that place + if (isNodeEmpty(node)) ParseHelper_Node_Exit(); + } // if(!use.empty()) else +} + +void X3DImporter::endReadStaticGroup() { + ParseHelper_Node_Exit(); // go up in scene graph +} + +// <Switch +// DEF="" ID +// USE="" IDREF +// bboxCenter="0 0 0" SFVec3f [initializeOnly] +// bboxSize="-1 -1 -1" SFVec3f [initializeOnly] +// whichChoice="-1" SFInt32 [inputOutput] +// > +// <\!-- ChildContentModel --> +// ChildContentModel is the child-node content model corresponding to X3DChildNode, combining all profiles. ChildContentModel can contain most nodes, +// other Grouping nodes, Prototype declarations and ProtoInstances in any order and any combination. When the assigned profile is less than Full, the +// precise palette of legal nodes that are available depends on assigned profile and components. +// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. +// </Switch> +// The Switch grouping node traverses zero or one of the nodes specified in the children field. The whichChoice field specifies the index of the child +// to traverse, with the first child having index 0. If whichChoice is less than zero or greater than the number of nodes in the children field, nothing +// is chosen. +void X3DImporter::startReadSwitch(XmlNode &node) { + std::string def, use; + int32_t whichChoice = -1; + + MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use); + XmlParser::getIntAttribute(node, "whichChoice", whichChoice); + + // if "USE" defined then find already defined element. + if (!use.empty()) { + 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. + if (!def.empty()) mNodeElementCur->ID = def; + + // also set values specific to this type of group + ((X3DNodeElementGroup *)mNodeElementCur)->UseChoice = true; + ((X3DNodeElementGroup *)mNodeElementCur)->Choice = whichChoice; + // in grouping set of nodes check X3DMetadataObject is not needed, because it is done in <Scene> parser function. + + // for empty element exit from node in that place + if (isNodeEmpty(node)) ParseHelper_Node_Exit(); + } // if(!use.empty()) else +} + +void X3DImporter::endReadSwitch() { + // just exit from node. Defined choice will be accepted at postprocessing stage. + ParseHelper_Node_Exit(); // go up in scene graph +} + +// <Transform +// DEF="" ID +// USE="" IDREF +// bboxCenter="0 0 0" SFVec3f [initializeOnly] +// bboxSize="-1 -1 -1" SFVec3f [initializeOnly] +// center="0 0 0" SFVec3f [inputOutput] +// rotation="0 0 1 0" SFRotation [inputOutput] +// scale="1 1 1" SFVec3f [inputOutput] +// scaleOrientation="0 0 1 0" SFRotation [inputOutput] +// translation="0 0 0" SFVec3f [inputOutput] +// > +// <\!-- ChildContentModel --> +// ChildContentModel is the child-node content model corresponding to X3DChildNode, combining all profiles. ChildContentModel can contain most nodes, +// other Grouping nodes, Prototype declarations and ProtoInstances in any order and any combination. When the assigned profile is less than Full, the +// precise palette of legal nodes that are available depends on assigned profile and components. +// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model. +// </Transform> +// The Transform node is a grouping node that defines a coordinate system for its children that is relative to the coordinate systems of its ancestors. +// Given a 3-dimensional point P and Transform node, P is transformed into point P' in its parent's coordinate system by a series of intermediate +// transformations. In matrix transformation notation, where C (center), SR (scaleOrientation), T (translation), R (rotation), and S (scale) are the +// equivalent transformation matrices, +// P' = T * C * R * SR * S * -SR * -C * P +void X3DImporter::startReadTransform(XmlNode &node) { + aiVector3D center(0, 0, 0); + float rotation[4] = { 0, 0, 1, 0 }; + aiVector3D scale(1, 1, 1); // A value of zero indicates that any child geometry shall not be displayed + float scale_orientation[4] = { 0, 0, 1, 0 }; + aiVector3D translation(0, 0, 0); + aiMatrix4x4 matr, tmatr; + std::string use, def; + + MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use); + X3DXmlHelper::getVector3DAttribute(node, "center", center); + X3DXmlHelper::getVector3DAttribute(node, "scale", scale); + X3DXmlHelper::getVector3DAttribute(node, "translation", translation); + std::vector<float> tvec; + if (X3DXmlHelper::getFloatArrayAttribute(node, "rotation", tvec)) { + if (tvec.size() != 4) throw DeadlyImportError("<Transform>: rotation vector must have 4 elements."); + memcpy(rotation, tvec.data(), sizeof(rotation)); + tvec.clear(); + } + if (X3DXmlHelper::getFloatArrayAttribute(node, "scaleOrientation", tvec)) { + if (tvec.size() != 4) throw DeadlyImportError("<Transform>: scaleOrientation vector must have 4 elements."); + memcpy(scale_orientation, tvec.data(), sizeof(scale_orientation)); + tvec.clear(); + } + + // if "USE" defined then find already defined element. + if (!use.empty()) { + X3DNodeElementBase *ne(nullptr); + bool newgroup = (nullptr == mNodeElementCur); + if(newgroup) + ParseHelper_Group_Begin(); + ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_Group, ne); + if (newgroup && isNodeEmpty(node)) { + ParseHelper_Node_Exit(); + } + } 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. + if (!def.empty()) { + mNodeElementCur->ID = def; + } + + // + // also set values specific to this type of group + // + // calculate transformation matrix + aiMatrix4x4::Translation(translation, matr); // T + aiMatrix4x4::Translation(center, tmatr); // C + matr *= tmatr; + aiMatrix4x4::Rotation(rotation[3], aiVector3D(rotation[0], rotation[1], rotation[2]), tmatr); // R + matr *= tmatr; + aiMatrix4x4::Rotation(scale_orientation[3], aiVector3D(scale_orientation[0], scale_orientation[1], scale_orientation[2]), tmatr); // SR + matr *= tmatr; + aiMatrix4x4::Scaling(scale, tmatr); // S + matr *= tmatr; + aiMatrix4x4::Rotation(-scale_orientation[3], aiVector3D(scale_orientation[0], scale_orientation[1], scale_orientation[2]), tmatr); // -SR + matr *= tmatr; + aiMatrix4x4::Translation(-center, tmatr); // -C + matr *= tmatr; + // and assign it + ((X3DNodeElementGroup *)mNodeElementCur)->Transformation = matr; + // in grouping set of nodes check X3DMetadataObject is not needed, because it is done in <Scene> parser function. + + // for empty element exit from node in that place + if (isNodeEmpty(node)) { + ParseHelper_Node_Exit(); + } + } // if(!use.empty()) else +} + +void X3DImporter::endReadTransform() { + ParseHelper_Node_Exit(); // go up in scene graph +} + +} // namespace Assimp + +#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER |