Hello
I'm working on a plugin that takes in points from polygon objects and then uses effectors fed in by the user to change the positions of the points that I then draw.
With the code below I am able to change the positions of the points but the final result is different than the equivalent setup with a Matrix object as seen here. Both my code and the matrix are working from points set as the center point of the polygons of a Sphere with only a default Plain Effector in the Effector List.
My results are shown with the white dots compared to the cubes from the Matrix object.
PolygonObject *poly = (PolygonObject*)doc->SearchObject("Sphere"_s);
if (!poly )
return;
maxon::BaseArray<Vector> drawPoints;
if (poly == nullptr)
return;
polygonMatrix = poly->GetMg();
const CPolygon *polyArray = poly->GetPolygonR();
if (polyArray == nullptr)
return;
Matrix objMx = poly->GetMg();
BaseObject *obj = (BaseObject*)Get();
BaseTag * motag = obj->GetTag(ID_MOTAGDATA);
if (motag == nullptr)
motag = obj->MakeTag(ID_MOTAGDATA);
if (motag == nullptr)
return;
BaseTag * polyObjMocacheTag = obj->GetTag(ID_MOBAKETAG);
GetMoDataMessage modataMsg = GetMoDataMessage();
modataMsg.index = 0;
if (polyObjMocacheTag)
{
polyObjMocacheTag->Message(MSG_GET_MODATA, &modataMsg);
}
BaseTag *objTag = obj->GetTag(ID_MOTAGDATA);
if (objTag)
objTag->Message(MSG_GET_MODATA, &modataMsg);
if (!modataMsg.modata)
{
if (!motag->Message(MSG_GET_MODATA, &modataMsg) || !modataMsg.modata)
return;
}
MoData *md = modataMsg.modata;
if (md)
{
md->GetAutoLock();
MDArray<Matrix> matrixArray;
drawPoints.Reset();
polygonCount = poly->GetPolygonCount();
pointCount = poly->GetPointCount();
const CPolygon* polygons = poly->GetPolygonR();
const Vector *posArray = poly->GetPointR();
// Used as a standin for finding a center point for the polygon
for (Int32 polyIndex = 0; polyIndex < polygonCount; polyIndex++)
{
Vector centerPointOfPolygon = Vector(0);
if (polygons[polyIndex].c == polygons[polyIndex].d)
{
centerPointOfPolygon += posArray[polygons[polyIndex].a];
centerPointOfPolygon += posArray[polygons[polyIndex].b];
centerPointOfPolygon += posArray[polygons[polyIndex].c];
centerPointOfPolygon = (centerPointOfPolygon / 3.0);
}
else
{
centerPointOfPolygon += posArray[polygons[polyIndex].a];
centerPointOfPolygon += posArray[polygons[polyIndex].b];
centerPointOfPolygon += posArray[polygons[polyIndex].c];
centerPointOfPolygon += posArray[polygons[polyIndex].d];
centerPointOfPolygon = (centerPointOfPolygon / 4.0);
}
drawPoints.Append(centerPointOfPolygon);
}
md->SetCount(drawPoints.GetCount());
matrixArray = md->GetMatrixArray(MODATA_MATRIX);
pointCount = poly->GetPointCount();
polygonCount = poly->GetPolygonCount();
// Grabs the modata from the Matrix object for comparision purposes
BaseObject *matrix = doc->SearchObject("Matrix"_s);
if (!matrix)
return;
BaseTag *tmpMatrixTag = matrix->GetTag(ID_MOTAGDATA);
if (!tmpMatrixTag)
return;
GetMoDataMessage modataMatrixMsg;
if (!tmpMatrixTag->Message(MSG_GET_MODATA, &modataMatrixMsg))
return;
MDArray<Matrix> matrixMDArray = modataMatrixMsg.modata->GetMatrixArray(MODATA_MATRIX);
BaseContainer *dataInstance = op->GetDataInstance();
const CustomDataType * effectorsraw = dataInstance->GetCustomDataType(idEffectorList, CUSTOMDATATYPE_INEXCLUDE_LIST);
InExcludeData * effectors = nullptr;
if (effectorsraw)
effectors = (InExcludeData*)effectorsraw;
for (Int drawIndex = 0; drawIndex < drawPoints.GetCount(); drawIndex++)
{
Vector holdNormal = CalcFaceNormal(posArray, polyArray[drawIndex]);
Vector pointNormal = ~opMatrix * polygonMatrix * VectorToHPB(holdNormal);
MoData *matrixData = modataMatrixMsg.modata; UInt32 newDirty = 0;
maxon::Int32* flags = static_cast<maxon::Int32*>(matrixData->GetArray(MODATA_FLAGS));
Matrix setMat = HPBToMatrix(pointNormal, ROTATIONORDER::DEFAULT);
setMat.off = drawPoints[drawIndex];
matrixArray[drawIndex] = setMat;
}
if (effectors)
{
Effector_PassData emsg = Effector_PassData();
emsg.op = op;
emsg.md = md;
emsg.weight = 1.0;
emsg.thread = nullptr;
for (Int i = 0; i < effectors->GetObjectCount(); i++)
{
BaseObject * e = (BaseObject*)effectors->ObjectFromIndex(doc, i);
if (!e)
return;
if (!e->GetDeformMode())
return;
e->Message(MSG_EXECUTE_EFFECTOR, &emsg);
}
GetMoDataMessage modataMatrixMsg;
Int32 matrixItemCnt = md->GetCount();
MDArray<Matrix> itemsMtxArray = md->GetMatrixArray(MODATA_MATRIX);
for (Int32 drawIndex = 0; drawIndex < matrixItemCnt; drawIndex ++)
{
drawPoints[drawIndex ] = itemsMtxArray[drawIndex ].off;
}
}
}
My problem seems to be a result of the matrixs that I am filling the MoData with not having the proper rotation information. In my code I use CalcFaceNormal to get the normal of the polygons from the Sphere and then go through the steps to convert the normal to a matrix that is used by the MoData to be used by the Effectors. I run into the same kind of problem when I use a Random Effector.
I tried comparing the information inside the MoData from my object against that of the Matrix and they have different rotations.
Is there a proper way to determine this rotation value so that I can mimic the behavior of the MoGraph objects?
Any help would be greatly appreciated.
John Terenece