aboutsummaryrefslogtreecommitdiff
path: root/mayaPlug/shaveHairGeomIt.cpp
diff options
context:
space:
mode:
authorBen Marsh <[email protected]>2019-10-22 09:07:59 -0400
committerBen Marsh <[email protected]>2019-10-22 09:07:59 -0400
commitbd0027e737c6512397f841c22786274ed74b927f (patch)
treef7ffbdb8f3741bb7f24635616cc189cba5cb865c /mayaPlug/shaveHairGeomIt.cpp
downloadshave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.tar.xz
shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.zip
Adding Shave-and-a-Haircut 9.6
Diffstat (limited to 'mayaPlug/shaveHairGeomIt.cpp')
-rw-r--r--mayaPlug/shaveHairGeomIt.cpp247
1 files changed, 247 insertions, 0 deletions
diff --git a/mayaPlug/shaveHairGeomIt.cpp b/mayaPlug/shaveHairGeomIt.cpp
new file mode 100644
index 0000000..8ce71a0
--- /dev/null
+++ b/mayaPlug/shaveHairGeomIt.cpp
@@ -0,0 +1,247 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include <maya/MDagPath.h>
+#include <maya/MFnComponent.h>
+#include <maya/MFnDoubleIndexedComponent.h>
+#include <maya/MFnSingleIndexedComponent.h>
+#include <maya/MMatrix.h>
+#include <maya/MObjectArray.h>
+#include <maya/MPoint.h>
+#include <maya/MPxGeometryIterator.h>
+
+#include "shaveHairGeomIt.h"
+#include "shaveHairShape.h"
+#include "shaveSDKTYPES.h"
+
+static const int mid = SHAVE_VERTS_PER_GUIDE / 2;
+
+
+shaveHairGeomIt::shaveHairGeomIt(void* geom, MObjectArray& components)
+: MPxGeometryIterator(geom, components)
+, mComponents(components)
+, mHairShape((shaveHairShape*)geom)
+{
+ mWholeGeom = (components.length() == 0);
+ reset();
+}
+
+shaveHairGeomIt::shaveHairGeomIt(void* geom, MObject& components)
+: MPxGeometryIterator(geom, components)
+, mHairShape((shaveHairShape*)geom)
+{
+ mWholeGeom = components.isNull();
+
+ if (!mWholeGeom) mComponents.append(components);
+
+ reset();
+}
+
+
+void shaveHairGeomIt::component(MObject& comp)
+{
+ if (mIsDone)
+ comp = MObject::kNullObj;
+ else
+ {
+ MFnDoubleIndexedComponent compFn;
+
+ comp = compFn.create(shaveHairShape::kShaveGuideVertComponent);
+ compFn.addElement(mCurGuide, mCurVert);
+ }
+}
+
+
+int shaveHairGeomIt::index() const
+{
+ return mIterationIndex;
+}
+
+
+int shaveHairGeomIt::indexUnsimplified() const
+{
+ return mCurGuide * SHAVE_VERTS_PER_GUIDE + mCurVert;
+}
+
+
+int shaveHairGeomIt::iteratorCount() const
+{
+ return mNumGuides * SHAVE_VERTS_PER_GUIDE;
+}
+
+
+void shaveHairGeomIt::next()
+{
+ if (!mIsDone)
+ {
+ if (mWholeGeom)
+ {
+ if (++mCurVert >= SHAVE_VERTS_PER_GUIDE)
+ {
+ mCurVert = 0;
+ mIsDone = (++mCurGuide >= mNumGuides);
+ }
+ }
+ else
+ {
+ MFnComponent compFn(mComponents[mObjIndex]);
+
+ if (++mElementIndex >= compFn.elementCount())
+ {
+ mElementIndex = 0;
+
+ //
+ // I don't know if we need to worry about the
+ // possibility of empty component objects, but if so,
+ // this should take care of them.
+ //
+ while (++mObjIndex < mComponents.length())
+ {
+ compFn.setObject(mComponents[mObjIndex]);
+
+ if (compFn.elementCount() > 0) break;
+ }
+
+ mIsDone = (mObjIndex >= mComponents.length());
+ }
+
+ if (!mIsDone)
+ {
+ if (mComponents[mObjIndex].hasFn(MFn::kSingleIndexedComponent))
+ {
+ MFnSingleIndexedComponent guideComp(mComponents[mObjIndex]);
+
+ mCurGuide = guideComp.element(mElementIndex);
+ mCurVert = mid;
+ }
+ else
+ {
+ MFnDoubleIndexedComponent vertComp(mComponents[mObjIndex]);
+
+ vertComp.getElement(mElementIndex, mCurGuide, mCurVert);
+ }
+ }
+ }
+
+ mIterationIndex++;
+ }
+}
+
+
+MPoint shaveHairGeomIt::point() const
+{
+ MPoint p;
+
+ if (!mIsDone && mHairShape)
+ {
+ //
+ // Load the hairShape into the Shave engine.
+ //
+ mHairShape->makeCurrent();
+
+ SOFTGUIDE guide;
+
+ if (SHAVEfetch_guide(mCurGuide, &guide) != -1)
+ {
+ VERT& vert = guide.guide[mCurVert];
+
+ p.x = (double)vert.x;
+ p.y = (double)vert.y;
+ p.z = (double)vert.z;
+
+ //
+ // Transform the point into local space.
+ //
+ MDagPath shapePath;
+
+ MDagPath::getAPathTo(mHairShape->thisMObject(), shapePath);
+
+ p *= shapePath.inclusiveMatrixInverse();
+ }
+ }
+
+ return p;
+}
+
+
+void shaveHairGeomIt::reset()
+{
+ MPxGeometryIterator::reset();
+ setCurrentPoint(0);
+
+ mIterationIndex = 0;
+
+ if (mHairShape)
+ {
+ mNumGuides = (int)mHairShape->getGuideCount();
+ setMaxPoints(mNumGuides * SHAVE_VERTS_PER_GUIDE);
+ }
+ else
+ {
+ setMaxPoints(0);
+ mNumGuides = 0;
+ }
+
+ mCurGuide = 0;
+ mCurVert = 0;
+
+ if (mWholeGeom)
+ {
+ mIsDone = (mNumGuides == 0);
+ }
+ else
+ {
+ //
+ // I don't know if we have to worry about getting empty component
+ // objects, but let's check, just to be safe.
+ //
+ for (mObjIndex = 0; mObjIndex < mComponents.length(); mObjIndex++)
+ {
+ if (mComponents[mObjIndex].hasFn(MFn::kSingleIndexedComponent))
+ {
+ MFnSingleIndexedComponent compFn(mComponents[mObjIndex]);
+
+ if (compFn.elementCount() > 0)
+ {
+ mCurGuide = compFn.element(0);
+ mCurVert = mid;
+ break;
+ }
+ }
+ else if (mComponents[mObjIndex].hasFn(MFn::kDoubleIndexedComponent))
+ {
+ MFnDoubleIndexedComponent compFn(mComponents[mObjIndex]);
+
+ if (compFn.elementCount() > 0)
+ {
+ compFn.getElement(0, mCurGuide, mCurVert);
+ break;
+ }
+ }
+ }
+
+ mIsDone = (mObjIndex >= mComponents.length());
+ mElementIndex = 0;
+ }
+}
+
+
+void shaveHairGeomIt::setPoint(const MPoint& newPoint) const
+{
+cout << "shaveHairGeomIt::setPoint" << endl;
+ // %%% not yet implemented
+}
+
+
+int shaveHairGeomIt::setPointGetNext(MPoint& pointInOut)
+{
+ // %%% 'set' portion not yet implemented
+
+cout << "shaveHairGeomIt::setPointGetNext" << endl;
+ next();
+ pointInOut = point();
+
+ return index();
+}
+