#ifdef WIN32
#pragma warning( disable : 4786 )
#endif
#include <maya/MIOStream.h>
#include <maya/MDagPath.h>
#include <maya/MDoubleArray.h>
#include <maya/MFloatVector.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnLightDataAttribute.h>
#include <maya/MFnMesh.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MGlobal.h>
#include <maya/MPlug.h>
#include <maya/MPlugArray.h>
#include <maya/MString.h>
#if defined(OSMac_MachO_)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#include "blindDataShader.h"
void mergeSort( int startIndex, int sortingOffset,
MIntArray& sortingArray, int* tempSortingArray,
MDoubleArray& otherArray, double* tempOtherArray)
{
if (sortingOffset == 2)
{
if (sortingArray[startIndex] > sortingArray[startIndex+1])
{
int temp = sortingArray[startIndex+1];
sortingArray[startIndex+1] = sortingArray[startIndex];
sortingArray[startIndex] = temp;
double ftemp = otherArray[startIndex+1];
otherArray[startIndex+1] = otherArray[startIndex];
otherArray[startIndex] = ftemp;
}
}
else if (sortingOffset > 2)
{
int leftCount = sortingOffset / 2;
int rightCount = sortingOffset - leftCount;
int leftIndex = startIndex;
int rightIndex = startIndex + leftCount;
mergeSort(leftIndex, leftCount, sortingArray, tempSortingArray,
otherArray, tempOtherArray);
mergeSort(rightIndex, rightCount, sortingArray, tempSortingArray,
otherArray, tempOtherArray);
int index = startIndex;
while (leftIndex < (startIndex + leftCount)
&& rightIndex < (startIndex + sortingOffset) )
{
if (sortingArray[leftIndex] < sortingArray[rightIndex])
{
tempSortingArray[index] = sortingArray[leftIndex];
tempOtherArray[index++] = otherArray[leftIndex++];
}
else
{
tempSortingArray[index] = sortingArray[rightIndex];
tempOtherArray[index++] = otherArray[rightIndex++];
}
}
while (leftIndex < (startIndex + leftCount) )
{
tempSortingArray[index] = sortingArray[leftIndex];
tempOtherArray[index++] = otherArray[leftIndex++];
}
while (rightIndex < (startIndex + sortingOffset) )
{
tempSortingArray[index] = sortingArray[rightIndex];
tempOtherArray[index++] = otherArray[rightIndex++];
}
for (index = startIndex; index < (startIndex + sortingOffset); ++index)
{
sortingArray[index] = tempSortingArray[index];
otherArray[index] = tempOtherArray[index];
}
}
}
int binarySearch(int searchValue, MIntArray& searchArray)
{
int max = searchArray.length();
int min = 0;
while (max - min > 1)
{
int currentIndex = ((max - min) / 2) + min;
int currentValue = searchArray[currentIndex];
if (currentValue == searchValue) return currentIndex;
else if (currentValue < searchValue) min = currentIndex;
else max = currentIndex;
}
if (searchArray[min] == searchValue) return min;
else return -1;
}
MTypeId blindDataShader::id( 0x00086000 );
void* blindDataShader::creator()
{
return new blindDataShader();
}
MStatus blindDataShader::initialize()
{
return MS::kSuccess;
}
MStatus blindDataShader::compute(
const MPlug& plug,
MDataBlock& block )
{
bool k = false;
k |= (plug==outColor);
k |= (plug==outColorR);
k |= (plug==outColorG);
k |= (plug==outColorB);
if( !k ) return MS::kUnknownParameter;
MFloatVector resultColor(0.0,0.0,0.0);
MDataHandle outColorHandle = block.outputValue( outColor );
MFloatVector& outColor = outColorHandle.asFloatVector();
outColor = resultColor;
outColorHandle.setClean();
return MS::kSuccess;
}
MStatus blindDataShader::bind(const MDrawRequest& request, M3dView& view)
{
view.beginGL();
glPushAttrib( GL_ALL_ATTRIB_BITS );
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
view.endGL();
return MS::kSuccess;
}
MStatus blindDataShader::unbind(const MDrawRequest& request,
M3dView& view)
{
view.beginGL();
glPopClientAttrib();
glPopAttrib();
view.endGL();
return MS::kSuccess;
}
MStatus blindDataShader::geometry( const MDrawRequest& request,
M3dView& view,
int prim,
unsigned int writable,
int indexCount,
const unsigned int * indexArray,
int vertexCount,
const int * vertexIDs,
const float * vertexArray,
int normalCount,
const float ** normalArrays,
int colorCount,
const float ** colorArrays,
int texCoordCount,
const float ** texCoordArrays)
{
const int blindDataUniqueID = 60;
MStatus stat;
int i;
double* colours = new double[vertexCount * 3];
float defaultColour[3] = { 0.0f, 0.0f, 0.0f };
MPlug plug( thisMObject(), outColor );
MObject colorObject;
plug.getValue(colorObject);
MFnNumericData data(colorObject);
data.getData(defaultColour[0], defaultColour[1], defaultColour[2]);
MFnMesh mesh(request.multiPath().node(), &stat);
if (stat && mesh.hasBlindData(MFn::kMeshVertComponent, &stat)
&& mesh.hasBlindData(vertexIDs[0], MFn::kMeshVertComponent,
blindDataUniqueID, &stat))
{
MIntArray redComponentIDs, greenComponentIDs, blueComponentIDs;
MDoubleArray redColour, greenColour, blueColour;
stat = mesh.getDoubleBlindData( MFn::kMeshVertComponent,
blindDataUniqueID, "red", redComponentIDs, redColour);
if (stat) stat = mesh.getDoubleBlindData( MFn::kMeshVertComponent,
blindDataUniqueID, "green", greenComponentIDs, greenColour);
if (stat) stat = mesh.getDoubleBlindData( MFn::kMeshVertComponent,
blindDataUniqueID, "blue", blueComponentIDs, blueColour);
if (stat && redComponentIDs.length() == redColour.length()
&& greenComponentIDs.length() == greenColour.length()
&& blueComponentIDs.length() == blueColour.length())
{
int maxArrayLength =
(redComponentIDs.length() > greenComponentIDs.length()) ?
((redComponentIDs.length() > blueComponentIDs.length()) ?
redComponentIDs.length() : blueComponentIDs.length()) :
((greenComponentIDs.length() > blueComponentIDs.length()) ?
greenComponentIDs.length() : blueComponentIDs.length());
int* tempIntArray = new int[maxArrayLength];
double* tempFloatArray = new double[maxArrayLength];
mergeSort(0, redComponentIDs.length(), redComponentIDs,
tempIntArray, redColour, tempFloatArray);
mergeSort(0, greenComponentIDs.length(), greenComponentIDs,
tempIntArray, greenColour, tempFloatArray);
mergeSort(0, blueComponentIDs.length(), blueComponentIDs,
tempIntArray, blueColour, tempFloatArray);
for (i = 0; i < vertexCount; ++i)
{
int index = binarySearch(vertexIDs[i], redComponentIDs);
if (index != -1) colours[3*i] = redColour[index];
else colours[3*i] = defaultColour[0];
index = binarySearch(vertexIDs[i], greenComponentIDs);
if (index != -1) colours[3*i+1] = greenColour[index];
else colours[3*i+1] = defaultColour[1];
index = binarySearch(vertexIDs[i], blueComponentIDs);
if (index != -1) colours[3*i+2] = blueColour[index];
else colours[3*i+2] = defaultColour[2];
}
}
}
view.beginGL();
glPushAttrib( GL_ALL_ATTRIB_BITS );
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
glDisable(GL_LIGHTING);
glVertexPointer(3, GL_FLOAT, 0, vertexArray);
glEnableClientState(GL_VERTEX_ARRAY);
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glColorPointer(3, GL_DOUBLE, 0, colours);
glEnableClientState(GL_COLOR_ARRAY);
glDrawElements(prim, indexCount, GL_UNSIGNED_INT, indexArray);
glDisable(GL_COLOR_MATERIAL);
glPopClientAttrib();
glPopAttrib();
view.endGL();
return MS::kSuccess;
}