#include "apiMeshSubSceneOverride.h"
#include "apiMeshShape.h"
#include "apiMeshGeom.h"
#include <maya/MDagPathArray.h>
#include <maya/MDrawRegistry.h>
#include <maya/MFnDagNode.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnSingleIndexedComponent.h>
#include <maya/MGLFunctionTable.h>
#include <maya/MGlobal.h>
#include <maya/MHWGeometry.h>
#include <maya/MHWGeometryUtilities.h>
#include <maya/MHardwareRenderer.h>
#include <maya/MObject.h>
#include <maya/MObjectArray.h>
#include <maya/MPlugArray.h>
#include <maya/MPxComponentConverter.h>
#include <maya/MSelectionContext.h>
#include <maya/MSelectionList.h>
#include <maya/MShaderManager.h>
#include <maya/MUserData.h>
#include <maya/MViewport2Renderer.h>
#include <vector>
#ifdef _WINDOWS
#include <d3d11.h>
#endif
namespace apiMeshSubSceneOverrideHelpers
{
{
public:
ShadedItemUserData(apiMeshSubSceneOverride* ov)
~ShadedItemUserData() { fOverride = NULL; }
apiMeshSubSceneOverride* fOverride;
};
class apiMeshHWSelectionUserData :
public MUserData
{
public:
apiMeshHWSelectionUserData()
, fMeshGeom(NULL)
{
}
virtual ~apiMeshHWSelectionUserData()
{
}
apiMeshGeom* fMeshGeom;
};
{
public:
, fComponentType(componentType)
, fSelectionType(selectionType) {}
virtual ~simpleComponentConverter() {}
{
fComponentObject = fComponent.create( fComponentType );
apiMeshHWSelectionUserData* selectionData =
dynamic_cast<apiMeshHWSelectionUserData*
>(renderItem.
customData());
if(selectionData) {
apiMeshGeom* meshGeom = selectionData->fMeshGeom;
unsigned int numTriangles = 0;
for (int i=0; i<meshGeom->faceCount; ++i) {
int numVerts = meshGeom->face_counts[i];
if (numVerts > 2) {
numTriangles += numVerts - 2;
}
}
fLookupTable.resize(numTriangles);
unsigned int idx = 0;
for (int faceIdx=0; faceIdx<meshGeom->faceCount; ++faceIdx) {
int numVerts = meshGeom->face_counts[faceIdx];
if (numVerts > 2) {
for (int v=1; v<numVerts-1; ++v) {
fLookupTable[idx++] = faceIdx;
}
}
}
}
}
}
{
return;
}
int idx = intersection.
index();
if (idx >= 0 && idx < (int)fLookupTable.size()) {
idx = fLookupTable[idx];
}
}
fComponent.addElement(idx);
}
{
return fComponentObject;
}
{
return fSelectionType;
}
static MPxComponentConverter* creatorVertexSelection()
{
}
static MPxComponentConverter* creatorEdgeSelection()
{
}
static MPxComponentConverter* creatorFaceSelection()
{
}
private:
std::vector<int> fLookupTable;
};
}
using namespace apiMeshSubSceneOverrideHelpers;
static const bool sUseCustomUserBuffersForBoundingBox = true;
static bool floatApproxEqual(float left, float right);
const MString apiMeshSubSceneOverride::sWireName(
"apiMeshWire");
const MString apiMeshSubSceneOverride::sSelectName(
"apiMeshSelection");
const MString apiMeshSubSceneOverride::sBoxName(
"apiMeshBox");
const MString apiMeshSubSceneOverride::sSelectedBoxName(
"apiMeshBoxSelection");
const MString apiMeshSubSceneOverride::sShadedName(
"apiMeshShaded");
const MString apiMeshSubSceneOverride::sTexturedName(
"apiMeshTextured");
const MString apiMeshSubSceneOverride::sVertexSelectionName(
"apiMeshVertexSelection");
const MString apiMeshSubSceneOverride::sEdgeSelectionName(
"apiMeshEdgeSelection");
const MString apiMeshSubSceneOverride::sFaceSelectionName(
"apiMeshFaceSelection");
const MString apiMeshSubSceneOverride::sActiveVertexName(
"apiMeshActiveVertex");
const MString apiMeshSubSceneOverride::sActiveEdgeName(
"apiMeshActiveEdge");
const MString apiMeshSubSceneOverride::sActiveFaceName(
"apiMeshActiveFace");
apiMeshSubSceneOverride::apiMeshSubSceneOverride(
const MObject& obj)
: MPxSubSceneOverride(obj)
, fObject(obj)
, fMesh(NULL)
, fWireShader(NULL)
, fThickWireShader(NULL)
, fSelectShader(NULL)
, fThickSelectShader(NULL)
, fShadedShader(NULL)
, fVertexComponentShader(NULL)
, fEdgeComponentShader(NULL)
, fFaceComponentShader(NULL)
, fPositionBuffer(NULL)
, fNormalBuffer(NULL)
, fBoxPositionBuffer(NULL)
, fBoxPositionBufferId(0)
, fBoxPositionBufferDX(NULL)
, fBoxIndexBufferId(0)
, fBoxIndexBufferDX(NULL)
, fWireIndexBuffer(NULL)
, fBoxIndexBuffer(NULL)
, fShadedIndexBuffer(NULL)
, fActiveVerticesIndexBuffer(NULL)
, fActiveEdgesIndexBuffer(NULL)
, fActiveFacesIndexBuffer(NULL)
, fThickLineWidth(-1.0)
, fQueuedLineWidth(-1.0)
, fNumInstances(0)
, fIsInstanceMode(false)
, fQueueUpdate(false)
, fUseQueuedLineUpdate(false)
{
if (status)
{
fMesh = dynamic_cast<apiMesh*>(node.userNode());
}
}
apiMeshSubSceneOverride::~apiMeshSubSceneOverride()
{
fMesh = NULL;
std::vector<ShadedItemUserData*>::iterator it;
for (it = fLinkLostCallbackData.begin(); it != fLinkLostCallbackData.end(); ++it)
{
ShadedItemUserData* cbData = *it;
cbData->fOverride = 0;
}
fLinkLostCallbackData.clear();
if (renderer)
{
if (shaderMgr)
{
if (fWireShader) {
fWireShader = NULL;
}
if (fThickWireShader) {
fThickWireShader = NULL;
}
if (fSelectShader) {
fSelectShader = NULL;
}
if (fThickSelectShader) {
fThickSelectShader = NULL;
}
if (fShadedShader) {
fShadedShader = NULL;
}
if (fVertexComponentShader) {
fVertexComponentShader = NULL;
}
if (fEdgeComponentShader) {
fEdgeComponentShader = NULL;
}
if (fFaceComponentShader) {
fFaceComponentShader = NULL;
}
}
}
deleteBuffers();
}
void apiMeshSubSceneOverride::untrackLinkLostData(ShadedItemUserData* data)
{
for (size_t i = 0; i < fLinkLostCallbackData.size(); ++i)
{
if (fLinkLostCallbackData[i] == data)
{
fLinkLostCallbackData[i] = fLinkLostCallbackData.back();
fLinkLostCallbackData.pop_back();
break;
}
}
}
{
}
bool apiMeshSubSceneOverride::requiresUpdate(
{
if (container.
count() == 0)
{
return true;
}
return true;
}
void apiMeshSubSceneOverride::update(
{
manageRenderItems(container, frameContext,
fMesh->shapeDirty() || container.
count() == 0);
fMesh->resetShapeDirty();
}
bool apiMeshSubSceneOverride::furtherUpdateRequired(
{
if (fUseQueuedLineUpdate)
{
{
return fQueueUpdate;
}
}
return false;
}
void apiMeshSubSceneOverride::manageRenderItems(
bool updateGeometry)
{
if (!fMesh || fObject.isNull()) return;
if (!renderer) return;
if (!shaderMgr) return;
if (!status) return;
if (!node.getAllPaths(instances) || instances.
length() == 0)
return;
static const float sRed[] = {1.0f, 0.0f, 0.0f, 1.0f};
static const float sGreen[] = {0.0f, 1.0f, 0.0f, 1.0f};
static const float sWhite[] = {1.0f, 1.0f, 1.0f, 1.0f};
if (!fWireShader)
{
}
if (!fThickWireShader)
{
}
if (!fSelectShader)
{
}
if (!fThickSelectShader)
{
}
if (!fVertexComponentShader)
{
const float pointSize[2] = {5.0, 5.0};
fVertexComponentShader->setParameter("pointSize", pointSize);
}
if (!fEdgeComponentShader)
{
const float lineWidth[2] = {2.0, 2.0};
fEdgeComponentShader->setParameter("lineWidth", lineWidth);
}
if (!fFaceComponentShader)
{
}
if (!fShadedShader)
{
}
if (updateGeometry) rebuildGeometryBuffers();
if (!fPositionBuffer || !fNormalBuffer || !fBoxPositionBuffer ||
!fWireIndexBuffer || !fBoxIndexBuffer || !fShadedIndexBuffer)
{
return;
}
bool anyMatrixChanged = false;
bool itemsChanged = false;
unsigned int instanceArrayLength = instances.
length();
unsigned int numInstanceSelected = 0;
unsigned int numInstanceUnselected = 0;
unsigned int numInstances = 0;
MMatrixArray selectedInstanceMatrixArray(instanceArrayLength);
MMatrixArray unselectedInstanceMatrixArray(instanceArrayLength);
for (unsigned int instIdx=0; instIdx<instanceArrayLength; instIdx++)
{
if (!instances[instIdx].isValid() || !instances[instIdx].isVisible())
continue;
unsigned int instanceNum = instances[instIdx].instanceNumber();
InstanceInfo instanceInfo(instances[instIdx].inclusiveMatrix(),
useSelectHighlight(selectedList, instances[instIdx]));
InstanceInfoMap::iterator iter = fInstanceInfoCache.find(instanceNum);
if (iter == fInstanceInfoCache.end() ||
iter->second.fIsSelected != instanceInfo.fIsSelected ||
!iter->second.fTransform.isEquivalent(instanceInfo.fTransform))
{
fInstanceInfoCache[instanceNum] = instanceInfo;
anyMatrixChanged = true;
}
instanceMatrixArray[numInstances++] = instanceInfo.fTransform;
if (instanceInfo.fIsSelected)
{
selectedInstanceMatrixArray[numInstanceSelected++] = instanceInfo.fTransform;
}
else
{
unselectedInstanceMatrixArray[numInstanceUnselected++] = instanceInfo.fTransform;
}
}
instanceMatrixArray.setLength(numInstances);
selectedInstanceMatrixArray.setLength(numInstanceSelected);
unselectedInstanceMatrixArray.setLength(numInstanceUnselected);
if (fNumInstances != numInstances)
{
anyMatrixChanged = true;
fNumInstances = numInstances;
}
const bool anyInstanceSelected = numInstanceSelected > 0;
const bool anyInstanceUnselected = numInstanceUnselected > 0;
std::set<int> activeVerticesSet;
std::set<int> activeEdgesSet;
std::set<int> activeFacesSet;
if (fMesh->hasActiveComponents())
{
if (activeComponents.
length() > 0)
{
if (fnComponent.elementCount())
{
fnComponent.getElements( activeIds );
{
for (
unsigned int i=0; i<activeIds.
length(); ++i)
activeVerticesSet.
insert( activeIds[i] );
}
{
for (
unsigned int i=0; i<activeIds.
length(); ++i)
activeEdgesSet.insert( activeIds[i] );
}
{
for (
unsigned int i=0; i<activeIds.
length(); ++i)
activeFacesSet.insert( activeIds[i] );
}
}
}
}
const bool updateActiveItems =
updateGeometry ||
fActiveVerticesSet != activeVerticesSet ||
fActiveEdgesSet != activeEdgesSet ||
fActiveFacesSet != activeFacesSet;
fActiveVerticesSet = activeVerticesSet;
fActiveEdgesSet = activeEdgesSet;
fActiveFacesSet = activeFacesSet;
if (updateActiveItems)
rebuildActiveComponentIndexBuffers();
const bool anyVertexSelected = !fActiveVerticesSet.empty();
const bool anyEdgeSelected = !fActiveEdgesSet.empty();
const bool anyFaceSelected = !fActiveFacesSet.empty();
if( (anyVertexSelected && fActiveVerticesIndexBuffer == NULL) ||
(anyEdgeSelected && fActiveEdgesIndexBuffer == NULL) ||
(anyFaceSelected && fActiveFacesIndexBuffer == NULL) )
return;
if (!wireItem && anyInstanceUnselected)
{
sWireName,
itemsChanged = true;
}
else if (wireItem && !anyInstanceUnselected)
{
wireItem = NULL;
itemsChanged = true;
}
if (!selectItem && anyInstanceSelected)
{
sSelectName,
container.
add(selectItem);
itemsChanged = true;
}
else if (selectItem && !anyInstanceSelected)
{
container.
remove(sSelectName);
selectItem = NULL;
itemsChanged = true;
}
if (!boxItem && anyInstanceUnselected)
{
sBoxName,
itemsChanged = true;
}
else if (boxItem && !anyInstanceUnselected)
{
boxItem = NULL;
itemsChanged = true;
}
if (!selectedBoxItem && anyInstanceSelected)
{
sSelectedBoxName,
container.
add(selectedBoxItem);
itemsChanged = true;
}
else if (selectedBoxItem && !anyInstanceSelected)
{
container.
remove(sSelectedBoxName);
selectedBoxItem = NULL;
itemsChanged = true;
}
if (!shadedItem)
{
sShadedName,
container.
add(shadedItem);
itemsChanged = true;
}
if (!texturedItem)
{
sTexturedName,
container.
add(texturedItem);
itemsChanged = true;
}
if (node.getConnectedSetsAndMembers(0, sets, comps, true))
{
for (
unsigned int i=0; i<sets.
length(); i++)
{
if (status)
{
MPlug shaderPlug = fnSet.findPlug(
"surfaceShader");
{
if (connectedPlugs.
length() > 0)
break;
}
}
}
}
{
ShadedItemUserData *userData = new ShadedItemUserData(this);
if (connectedPlugs.
length() > 0 &&
instances[0],
shadedItemLinkLost,
userData,
true))
{
fLinkLostCallbackData.push_back(userData);
}
else
{
delete userData;
}
}
{
ShadedItemUserData *userData = new ShadedItemUserData(this);
if (connectedPlugs.
length() > 0 &&
instances[0],
shadedItemLinkLost,
userData,
false))
{
fLinkLostCallbackData.push_back(userData);
}
else
{
delete userData;
}
}
fMesh->setMaterialDirty(false);
if (!vertexSelectionItem)
{
sVertexSelectionName,
vertexSelectionItem->
setShader(fVertexComponentShader);
container.
add(vertexSelectionItem);
itemsChanged = true;
}
static bool useDrawInstancingOnEdgeSelectionItem = false;
if (!edgeSelectionItem)
{
if (useDrawInstancingOnEdgeSelectionItem) {
}
sEdgeSelectionName,
container.
add(edgeSelectionItem);
itemsChanged = true;
}
if (!faceSelectionItem)
{
sFaceSelectionName,
faceSelectionItem->
setShader(fFaceComponentShader);
container.
add(faceSelectionItem);
itemsChanged = true;
}
if (updateGeometry)
{
apiMeshHWSelectionUserData* mySelectionData = new apiMeshHWSelectionUserData();
mySelectionData->fMeshGeom = fMesh->meshGeom();
}
if (!activeVertexItem && anyVertexSelected)
{
sActiveVertexName,
activeVertexItem->
setShader(fVertexComponentShader);
container.
add(activeVertexItem);
itemsChanged = true;
}
else if (activeVertexItem && !anyVertexSelected)
{
container.
remove(sActiveVertexName);
activeVertexItem = NULL;
itemsChanged = true;
}
if (!activeEdgeItem && anyEdgeSelected)
{
sActiveEdgeName,
activeEdgeItem->
setShader(fEdgeComponentShader);
container.
add(activeEdgeItem);
itemsChanged = true;
}
else if (activeEdgeItem && !anyEdgeSelected)
{
container.
remove(sActiveEdgeName);
activeEdgeItem = NULL;
itemsChanged = true;
}
if (!activeFaceItem && anyFaceSelected)
{
sActiveFaceName,
activeFaceItem->
setShader(fFaceComponentShader);
container.
add(activeFaceItem);
itemsChanged = true;
}
else if (activeFaceItem && !anyFaceSelected)
{
container.
remove(sActiveFaceName);
activeFaceItem = NULL;
itemsChanged = true;
}
bool userWidthChange = !floatApproxEqual(lineWidth, fThickLineWidth);
bool doUpdate = false;
const float targetRefinedLineWidth = 50.0f;
if (userWidthChange)
{
fThickLineWidth = lineWidth;
doUpdate = true;
if (fUseQueuedLineUpdate)
{
fQueuedLineWidth = lineWidth;
if (fQueuedLineWidth < targetRefinedLineWidth)
{
fQueueUpdate = true;
}
}
}
else
{
if (fUseQueuedLineUpdate && fQueueUpdate)
{
if (fQueuedLineWidth < targetRefinedLineWidth)
{
lineWidth = fQueuedLineWidth;
fQueuedLineWidth++;
fQueueUpdate = true;
doUpdate = true;
}
else
{
fQueueUpdate = false;
}
}
}
if (doUpdate)
{
if (!floatApproxEqual(lineWidth, 1.0f))
{
float lineWidthArray[2] = {0};
lineWidthArray[0] = lineWidth;
lineWidthArray[1] = lineWidth;
fThickWireShader->setParameter("lineWidth", lineWidthArray);
fThickSelectShader->setParameter("lineWidth", lineWidthArray);
if (wireItem)
if (selectItem)
}
else
{
if (wireItem)
if (selectItem)
}
}
if (itemsChanged || updateGeometry)
{
wireBuffers.
addBuffer(
"positions", fPositionBuffer);
if (wireItem)
setGeometryForRenderItem(*wireItem, wireBuffers, *fWireIndexBuffer, &bounds);
if (selectItem)
setGeometryForRenderItem(*selectItem, wireBuffers, *fWireIndexBuffer, &bounds);
setGeometryForRenderItem(*edgeSelectionItem, wireBuffers, *fWireIndexBuffer, &bounds);
boxBuffers.
addBuffer(
"positions", fBoxPositionBuffer);
if (boxItem)
setGeometryForRenderItem(*boxItem, boxBuffers, *fBoxIndexBuffer, &bounds);
if (selectedBoxItem)
setGeometryForRenderItem(*selectedBoxItem, boxBuffers, *fBoxIndexBuffer, &bounds);
shadedBuffers.
addBuffer(
"positions", fPositionBuffer);
shadedBuffers.
addBuffer(
"normals", fNormalBuffer);
setGeometryForRenderItem(*shadedItem, shadedBuffers, *fShadedIndexBuffer, &bounds);
setGeometryForRenderItem(*texturedItem, shadedBuffers, *fShadedIndexBuffer, &bounds);
setGeometryForRenderItem(*edgeSelectionItem, wireBuffers, *fWireIndexBuffer, &bounds);
setGeometryForRenderItem(*faceSelectionItem, wireBuffers, *fShadedIndexBuffer, &bounds);
}
if (itemsChanged || updateActiveItems)
{
vertexBuffer.
addBuffer(
"positions", fPositionBuffer);
if (activeVertexItem)
setGeometryForRenderItem(*activeVertexItem, vertexBuffer, *fActiveVerticesIndexBuffer, &bounds);
if (activeEdgeItem)
setGeometryForRenderItem(*activeEdgeItem, vertexBuffer, *fActiveEdgesIndexBuffer, &bounds);
if (activeFaceItem)
setGeometryForRenderItem(*activeFaceItem, vertexBuffer, *fActiveFacesIndexBuffer, &bounds);
}
if (itemsChanged || anyMatrixChanged)
{
if (!fIsInstanceMode && numInstances == 1)
{
MMatrix& objToWorld = instanceMatrixArray[0];
if (wireItem)
if (selectItem)
if (boxItem)
if (selectedBoxItem)
if (useDrawInstancingOnEdgeSelectionItem) {
transform1[3][3] = 1;
MMatrix transform2 = objToWorld * 2;
transform2[3][3] = 1;
MMatrix transform3 = objToWorld * 3;
transform3[3][3] = 1;
if (true) {
transforms.
append(transform1);
transforms.
append(transform2);
transforms.
append(transform3);
setInstanceTransformArray(*edgeSelectionItem, transforms);
}
else {
removeAllInstances(*edgeSelectionItem);
unsigned int newInstanceId = addInstanceTransform(*edgeSelectionItem, transform1);
printf("newInstanceId %u\n", newInstanceId);
newInstanceId = addInstanceTransform(*edgeSelectionItem, transform2);
printf("newInstanceId %u\n", newInstanceId);
newInstanceId = addInstanceTransform(*edgeSelectionItem, transform3);
printf("newInstanceId %u\n", newInstanceId);
}
}
if (activeVertexItem)
if (activeEdgeItem)
if (activeFaceItem)
}
else
{
if (wireItem)
setInstanceTransformArray(*wireItem, unselectedInstanceMatrixArray);
if (selectItem)
setInstanceTransformArray(*selectItem, selectedInstanceMatrixArray);
if (boxItem)
setInstanceTransformArray(*boxItem, unselectedInstanceMatrixArray);
if (selectedBoxItem)
setInstanceTransformArray(*selectedBoxItem, selectedInstanceMatrixArray);
setInstanceTransformArray(*edgeSelectionItem, instanceMatrixArray);
setInstanceTransformArray(*shadedItem, instanceMatrixArray);
setInstanceTransformArray(*texturedItem, instanceMatrixArray);
setInstanceTransformArray(*vertexSelectionItem, instanceMatrixArray);
setInstanceTransformArray(*edgeSelectionItem, instanceMatrixArray);
setInstanceTransformArray(*faceSelectionItem, instanceMatrixArray);
if (activeVertexItem)
setInstanceTransformArray(*activeVertexItem, instanceMatrixArray);
if (activeEdgeItem)
setInstanceTransformArray(*activeEdgeItem, instanceMatrixArray);
if (activeFaceItem)
setInstanceTransformArray(*activeFaceItem, instanceMatrixArray);
fIsInstanceMode = true;
}
}
if (itemsChanged || anyMatrixChanged || updateGeometry)
{
}
}
void apiMeshSubSceneOverride::rebuildGeometryBuffers()
{
{
if (renderer)
{
}
}
apiMeshGeom* meshGeom = fMesh->meshGeom();
if (!meshGeom) return;
deleteGeometryBuffers();
unsigned int numTriangles = 0;
unsigned int totalVerts = 0;
for (int i=0; i<meshGeom->faceCount; i++)
{
int numVerts = meshGeom->face_counts[i];
if (numVerts > 2)
{
numTriangles += numVerts - 2;
totalVerts += numVerts;
}
}
float* positions = (float*)fPositionBuffer->acquire(meshGeom->vertices.length(), true);
float* normals = (float*)fNormalBuffer->acquire(meshGeom->vertices.length(), true);
float* boxPositions = NULL;
unsigned short* boxIndices = NULL;
if (sUseCustomUserBuffersForBoundingBox)
{
static float sBoxPositions[8*3];
static unsigned short sBoxIndices[24];
boxPositions = sBoxPositions;
boxIndices = sBoxIndices;
}
else
{
boxPositions = (float*)fBoxPositionBuffer->acquire(8, true);
boxIndices = (unsigned short*)fBoxIndexBuffer->acquire(24, true);
}
unsigned int* wireBuffer = (unsigned int*)fWireIndexBuffer->acquire(2*totalVerts, true);
unsigned int* shadedBuffer = (unsigned int*)fShadedIndexBuffer->acquire(3*numTriangles, true);
if (!positions || !boxPositions || !normals || !wireBuffer || !boxIndices || !shadedBuffer)
{
deleteGeometryBuffers();
return;
}
int vid = 0;
int pid = 0;
int nid = 0;
for (unsigned int i=0; i<meshGeom->vertices.length(); i++)
{
MPoint position = meshGeom->vertices[i];
positions[pid++] = (float)position[0];
positions[pid++] = (float)position[1];
positions[pid++] = (float)position[2];
MVector normal = meshGeom->normals[i];
normals[nid++] = (float)normal[0];
normals[nid++] = (float)normal[1];
normals[nid++] = (float)normal[2];
}
fPositionBuffer->commit(positions); positions = NULL;
fNormalBuffer->commit(normals); normals = NULL;
boxPositions[0] = (float)bbmin.
x; boxPositions[1] = (
float)bbmin.
y; boxPositions[2] = (float)bbmin.
z;
boxPositions[3] = (
float)bbmin.
x; boxPositions[4] = (float)bbmin.
y; boxPositions[5] = (
float)bbmax.
z;
boxPositions[6] = (float)bbmax.
x; boxPositions[7] = (
float)bbmin.
y; boxPositions[8] = (float)bbmax.
z;
boxPositions[9] = (
float)bbmax.
x; boxPositions[10] = (float)bbmin.
y; boxPositions[11] = (
float)bbmin.
z;
boxPositions[12] = (float)bbmin.
x; boxPositions[13] = (
float)bbmax.
y; boxPositions[14] = (float)bbmin.
z;
boxPositions[15] = (
float)bbmin.
x; boxPositions[16] = (float)bbmax.
y; boxPositions[17] = (
float)bbmax.
z;
boxPositions[18] = (float)bbmax.
x; boxPositions[19] = (
float)bbmax.
y; boxPositions[20] = (float)bbmax.
z;
boxPositions[21] = (
float)bbmax.
x; boxPositions[22] = (float)bbmax.
y; boxPositions[23] = (
float)bbmin.
z;
boxIndices[0] = 0; boxIndices[1] = 1;
boxIndices[2] = 1; boxIndices[3] = 2;
boxIndices[4] = 2; boxIndices[5] = 3;
boxIndices[6] = 3; boxIndices[7] = 0;
boxIndices[8] = 4; boxIndices[9] = 5;
boxIndices[10] = 5; boxIndices[11] = 6;
boxIndices[12] = 6; boxIndices[13] = 7;
boxIndices[14] = 7; boxIndices[15] = 4;
boxIndices[16] = 0; boxIndices[17] = 4;
boxIndices[18] = 1; boxIndices[19] = 5;
boxIndices[20] = 2; boxIndices[21] = 6;
boxIndices[22] = 3; boxIndices[23] = 7;
if (sUseCustomUserBuffersForBoundingBox)
{
{
if (!gGLFT && pRenderer)
{
}
if (gGLFT)
{
gGLFT->
glGenBuffersARB(1, &fBoxPositionBufferId);
if (fBoxPositionBufferId != 0)
{
gGLFT->
glBindBufferARB(MGL_ARRAY_BUFFER_ARB, fBoxPositionBufferId);
gGLFT->
glBufferDataARB(MGL_ARRAY_BUFFER_ARB, 8*3*
sizeof(
float), boxPositions, MGL_STATIC_DRAW_ARB);
gGLFT->glBindBufferARB(MGL_ARRAY_BUFFER_ARB, 0);
fBoxPositionBuffer->resourceHandle(&fBoxPositionBufferId, 8*3);
}
gGLFT->glGenBuffersARB(1, &fBoxIndexBufferId);
if (fBoxIndexBufferId != 0)
{
gGLFT->glBindBufferARB(MGL_ELEMENT_ARRAY_BUFFER_ARB, fBoxIndexBufferId);
gGLFT->glBufferDataARB(MGL_ELEMENT_ARRAY_BUFFER_ARB, 24*sizeof(unsigned short), boxIndices, MGL_STATIC_DRAW_ARB);
gGLFT->glBindBufferARB(MGL_ELEMENT_ARRAY_BUFFER_ARB, 0);
fBoxIndexBuffer->resourceHandle(&fBoxIndexBufferId, 24);
}
}
}
#ifdef _WINDOWS
{
if (renderer)
{
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof(float) * 3 * 8;
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
InitData.pSysMem = boxPositions;
InitData.SysMemPitch = 0;
InitData.SysMemSlicePitch = 0;
if (pDevice)
{
pDevice->CreateBuffer( &bufferDesc, &InitData, &fBoxPositionBufferDX );
if (fBoxPositionBufferDX)
fBoxPositionBuffer->resourceHandle((void*)fBoxPositionBufferDX, 8*3);
}
bufferDesc.ByteWidth = sizeof(unsigned short) * 24;
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
InitData.pSysMem = boxIndices;
if (pDevice)
{
pDevice->CreateBuffer( &bufferDesc, &InitData, &fBoxIndexBufferDX);
if (fBoxIndexBufferDX)
fBoxIndexBuffer->resourceHandle((void*)fBoxIndexBufferDX, 24);
}
}
}
#endif
}
else
{
fBoxPositionBuffer->commit(boxPositions);
fBoxIndexBuffer->commit(boxIndices);
}
boxPositions = NULL;
boxIndices = NULL;
vid = 0;
int first = 0;
unsigned int idx = 0;
for (int faceIdx=0; faceIdx<meshGeom->faceCount; faceIdx++)
{
int numVerts = meshGeom->face_counts[faceIdx];
if (numVerts > 2)
{
first = vid;
for (int v=0; v<numVerts-1; v++)
{
wireBuffer[idx++] = meshGeom->face_connects[vid++];
wireBuffer[idx++] = meshGeom->face_connects[vid];
}
wireBuffer[idx++] = meshGeom->face_connects[vid++];
wireBuffer[idx++] = meshGeom->face_connects[first];
}
else
{
vid += numVerts;
}
}
fWireIndexBuffer->commit(wireBuffer); wireBuffer = NULL;
unsigned int base = 0;
idx = 0;
for (int faceIdx=0; faceIdx<meshGeom->faceCount; faceIdx++)
{
int numVerts = meshGeom->face_counts[faceIdx];
if (numVerts > 2)
{
for (int v=1; v<numVerts-1; v++)
{
shadedBuffer[idx++] = meshGeom->face_connects[base];
shadedBuffer[idx++] = meshGeom->face_connects[base+v];
shadedBuffer[idx++] = meshGeom->face_connects[base+v+1];
}
base += numVerts;
}
}
fShadedIndexBuffer->commit(shadedBuffer); shadedBuffer = NULL;
}
void apiMeshSubSceneOverride::rebuildActiveComponentIndexBuffers()
{
apiMeshGeom* meshGeom = fMesh->meshGeom();
if (!meshGeom) return;
deleteActiveComponentIndexBuffers();
const unsigned int numActiveVertices = fActiveVerticesSet.size();
if (numActiveVertices > 0)
{
unsigned int* activeVerticesBuffer = (unsigned int*)fActiveVerticesIndexBuffer->acquire(numActiveVertices, true);
if (activeVerticesBuffer) {
unsigned int idx = 0;
std::set<int>::const_iterator it = fActiveVerticesSet.begin();
std::set<int>::const_iterator itEnd = fActiveVerticesSet.end();
for(; it != itEnd; ++it)
activeVerticesBuffer[idx++] = *it;
fActiveVerticesIndexBuffer->commit(activeVerticesBuffer);
activeVerticesBuffer = NULL;
}
}
const unsigned int numActiveEdges = fActiveEdgesSet.size();
if (numActiveEdges > 0)
{
unsigned int* activeEdgesBuffer = (unsigned int*)fActiveEdgesIndexBuffer->acquire(2*numActiveEdges, true);
if (activeEdgesBuffer) {
unsigned int eid = 0;
unsigned int first = 0;
unsigned int vid = 0;
unsigned int idx = 0;
for (int i=0; i<meshGeom->faceCount; ++i)
{
int numVerts = meshGeom->face_counts[i];
if (numVerts > 2)
{
first = vid;
for (int v=0; v<numVerts-1; ++v)
{
if (fActiveEdgesSet.count(eid) > 0)
{
activeEdgesBuffer[idx++] = meshGeom->face_connects[vid];
activeEdgesBuffer[idx++] = meshGeom->face_connects[vid + 1];
}
++vid;
++eid;
}
if (fActiveEdgesSet.count(eid) > 0)
{
activeEdgesBuffer[idx++] = meshGeom->face_connects[vid];
activeEdgesBuffer[idx++] = meshGeom->face_connects[first];
}
++vid;
++eid;
}
else {
vid += numVerts;
}
}
fActiveEdgesIndexBuffer->commit(activeEdgesBuffer);
activeEdgesBuffer = NULL;
}
}
const unsigned int numActiveFaces = fActiveFacesSet.size();
if (numActiveFaces > 0)
{
unsigned int numActiveFacesTriangles = 0;
for (int i=0; i<meshGeom->faceCount; ++i)
{
if (fActiveFacesSet.count(i) > 0)
{
int numVerts = meshGeom->face_counts[i];
if (numVerts > 2)
numActiveFacesTriangles += numVerts - 2;
}
}
unsigned int* activeFacesBuffer = (unsigned int*)fActiveFacesIndexBuffer->acquire(3*numActiveFacesTriangles, true);
if (activeFacesBuffer)
{
unsigned int idx = 0;
unsigned int vid = 0;
for (int i=0; i<meshGeom->faceCount; ++i)
{
int numVerts = meshGeom->face_counts[i];
if (numVerts > 2)
{
if (fActiveFacesSet.count(i) > 0)
{
for (int v=1; v<numVerts-1; ++v)
{
activeFacesBuffer[idx++] = meshGeom->face_connects[vid];
activeFacesBuffer[idx++] = meshGeom->face_connects[vid+v];
activeFacesBuffer[idx++] = meshGeom->face_connects[vid+v+1];
}
}
vid += numVerts;
}
}
fActiveFacesIndexBuffer->commit(activeFacesBuffer);
activeFacesBuffer = NULL;
}
}
}
void apiMeshSubSceneOverride::deleteBuffers()
{
deleteGeometryBuffers();
deleteActiveComponentIndexBuffers();
}
void apiMeshSubSceneOverride::deleteGeometryBuffers()
{
delete fPositionBuffer; fPositionBuffer = NULL;
delete fNormalBuffer; fNormalBuffer = NULL;
delete fBoxPositionBuffer; fBoxPositionBuffer = NULL;
delete fWireIndexBuffer; fWireIndexBuffer = NULL;
delete fBoxIndexBuffer; fBoxIndexBuffer = NULL;
delete fShadedIndexBuffer; fShadedIndexBuffer = NULL;
if (sUseCustomUserBuffersForBoundingBox)
{
{
if (pRenderer && !gGLFT)
{
}
if (gGLFT)
{
if (fBoxPositionBufferId != 0)
{
gGLFT->
glDeleteBuffersARB(1, &fBoxPositionBufferId);
fBoxPositionBufferId = 0;
}
if (fBoxIndexBufferId != 0)
{
gGLFT->glDeleteBuffersARB(1, &fBoxIndexBufferId);
fBoxIndexBufferId = 0;
}
}
}
#ifdef _WINDOWS
{
if (NULL != fBoxPositionBufferDX)
{
fBoxPositionBufferDX->Release();
fBoxPositionBufferDX = NULL;
}
if (NULL != fBoxIndexBufferDX)
{
fBoxIndexBufferDX->Release();
fBoxIndexBufferDX = NULL;
}
}
#endif
}
}
void apiMeshSubSceneOverride::deleteActiveComponentIndexBuffers()
{
delete fActiveVerticesIndexBuffer; fActiveVerticesIndexBuffer = NULL;
delete fActiveEdgesIndexBuffer; fActiveEdgesIndexBuffer = NULL;
delete fActiveFacesIndexBuffer; fActiveFacesIndexBuffer = NULL;
}
void apiMeshSubSceneOverride::updateSelectionGranularity(
{
{
if(globalComponentMask.
intersects(supportedComponents))
{
}
}
else if (pointSnappingActive())
{
}
}
bool apiMeshSubSceneOverride::hasUIDrawables() const
{
return true;
}
bool apiMeshSubSceneOverride::areUIDrawablesDirty() const
{
return false;
}
void apiMeshSubSceneOverride::addUIDrawables(
{
MColor textColor( 0.1f, 0.8f, 0.8f, 1.0f );
}
MStatus apiMeshSubSceneOverride::registerComponentConverters()
{
if(status) {
if(status) {
}
}
return status;
}
MStatus apiMeshSubSceneOverride::deregisterComponentConverters()
{
if(status) {
if(status) {
}
}
return status;
}
bool apiMeshSubSceneOverride::getSelectionPath(
{
if (!status)
return false;
if (!node.getAllPaths(instances) || instances.
length() == 0)
return false;
dagPath = instances[0];
return true;
}
bool apiMeshSubSceneOverride::getInstancedSelectionPath(
{
if (!status)
return false;
if (!node.getAllPaths(instances) || instances.
length() == 0)
return false;
if (instances.
length() == 1 || instanceId == -1) {
dagPath = instances[0];
return true;
}
else {
if (instanceId > (
int)instances.
length())
return false;
dagPath = instances[instanceId - 1];
return true;
}
}
void apiMeshSubSceneOverride::shadedItemLinkLost(
MUserData* userData)
{
ShadedItemUserData* data = dynamic_cast<ShadedItemUserData*>(userData);
if (data && data->fOverride)
{
if (data->fOverride->fMesh)
data->fOverride->fMesh->setMaterialDirty(true);
data->fOverride->untrackLinkLostData(data);
}
delete userData;
}
{
{
return true;
}
do
{
if (selectedList.
hasItem(pathCopy))
{
return true;
}
}
while (status);
return false;
}
static bool floatApproxEqual(float left, float right)
{
return fabs(left - right) < 0.0001f;
}