virtual void createVertexStream( const MDagPath &dagPath, MVertexBuffer &vertexBuffer, const MComponentDataIndexing &targetIndexing, const MComponentDataIndexing &, const MVertexBufferArray &) const { #else virtual void createVertexStream( const MDagPath &dagPath, MVertexBuffer &vertexBuffer, const MComponentDataIndexing &targetIndexing) const { #endif const MVertexBufferDescriptor &desc = vertexBuffer.descriptor(); MFnMesh meshFn(dagPath); int nVertices = meshFn.numVertices(); #if MAYA_API_VERSION >= 201350 float *buffer = static_cast<float*>(vertexBuffer.acquire(nVertices, true)); #else float *buffer = static_cast<float*>(vertexBuffer.acquire(nVertices)); #endif float *dst = buffer; if (_normal) { MFloatVectorArray normals; meshFn.getVertexNormals(true, normals); for (int i = 0; i < nVertices; ++i) { *dst++ = normals[i].x; *dst++ = normals[i].y; *dst++ = normals[i].z; } } else { MFloatPointArray points; meshFn.getPoints(points); for (int i = 0; i < nVertices; ++i) { *dst++ = points[i].x; *dst++ = points[i].y; *dst++ = points[i].z; } } vertexBuffer.commit(buffer); } static MPxVertexBufferGenerator *positionBufferCreator() { return new OsdBufferGenerator(/*normal = */false); } static MPxVertexBufferGenerator *normalBufferCreator() { return new OsdBufferGenerator(/*normal = */true); } private:
virtual void createVertexStream(const MObject& object, MVertexBuffer& vertexBuffer, const MComponentDataIndexing& targetIndexing, const MComponentDataIndexing& /*sharedIndexing*/, const MVertexBufferArray& /*sourceStreams*/) const { // get the descriptor from the vertex buffer. // It describes the format and layout of the stream. const MVertexBufferDescriptor& descriptor = vertexBuffer.descriptor(); // we are expecting a float stream. if (descriptor.dataType() != MGeometry::kFloat) return; // we are expecting a float2 if (descriptor.dimension() != 2) return; // we are expecting a texture channel if (descriptor.semantic() != MGeometry::kTexture) return; // get the mesh from the current path // if it is not a mesh we do nothing. MStatus status; MFnMesh mesh(object, &status); if (!status) return; // failed const MUintArray& indices = targetIndexing.indices(); unsigned int vertexCount = indices.length(); if (vertexCount <= 0) return; // acquire the buffer to fill with data. float* buffer = (float*)vertexBuffer.acquire(vertexCount, true /*writeOnly - we don't need the current buffer values*/); float* start = buffer; for(unsigned int i = 0; i < vertexCount; ++i) { // Here we are embedding some custom data into the stream. // The included effects (vertexBufferGeneratorGL.cgfx and // vertexBufferGeneratorDX11.fx) will alternate // red, green, and blue vertex colored triangles based on this input. *(buffer++) = 1.0f; *(buffer++) = (float)indices[i]; // color index } // commit the buffer to signal completion. vertexBuffer.commit(start); }
const MVertexBufferArray &) const #else virtual void createVertexStream(const MDagPath &dagPath, MVertexBuffer &vertexBuffer, const MComponentDataIndexing &targetIndexing) const #endif { const MVertexBufferDescriptor &desc = vertexBuffer.descriptor(); MFnMesh meshFn(dagPath); int nVertices = meshFn.numVertices(); if (!_normal) { MFloatPointArray points; meshFn.getPoints(points); #ifdef MAYA2013_PREVIEW float *buffer = (float*)vertexBuffer.acquire(nVertices, true); #else float *buffer = (float*)vertexBuffer.acquire(nVertices); #endif float *dst = buffer; for(int i=0; i < nVertices; ++i){ *dst++ = points[i].x; *dst++ = points[i].y; *dst++ = points[i].z; } vertexBuffer.commit(buffer); } else { MFloatVectorArray normals; meshFn.getVertexNormals(true, normals); #ifdef MAYA2013_PREVIEW float *buffer = (float*)vertexBuffer.acquire(nVertices, true); #else float *buffer = (float*)vertexBuffer.acquire(nVertices); #endif float *dst = buffer; for(int i=0; i < nVertices; ++i){ *dst++ = normals[i].x; *dst++ = normals[i].y; *dst++ = normals[i].z; } vertexBuffer.commit(buffer); } }
virtual void createVertexStream(const MObject& object, MVertexBuffer& vertexBuffer, const MComponentDataIndexing& targetIndexing, const MComponentDataIndexing& /*sourceIndexing*/, const MVertexBufferArray& sourceStreams) const { // get the descriptor from the vertex buffer. // It describes the format and layout of the stream. const MVertexBufferDescriptor& descriptor = vertexBuffer.descriptor(); // we are expecting a float or int stream. MGeometry::DataType dataType = descriptor.dataType(); if (dataType != MGeometry::kFloat && dataType != MGeometry::kInt32) return; // we are expecting a dimension of 3 or 4 int dimension = descriptor.dimension(); if (dimension != 4 && dimension != 3) return; // we are expecting a texture channel if (descriptor.semantic() != MGeometry::kTexture) return; // get the mesh from the current path // if it is not a mesh we do nothing. MStatus status; MFnMesh mesh(object, &status); if (!status) return; // failed const MUintArray& indices = targetIndexing.indices(); unsigned int vertexCount = indices.length(); if (vertexCount <= 0) return; MVertexBuffer *positionStream = sourceStreams.getBuffer( "Position" ); if(positionStream == NULL || positionStream->descriptor().dataType() != MGeometry::kFloat) return; int positionDimension = positionStream->descriptor().dimension(); if(positionDimension != 3 && positionDimension != 4) return; MVertexBuffer *normalStream = sourceStreams.getBuffer( "Normal" ); if(normalStream == NULL || normalStream->descriptor().dataType() != MGeometry::kFloat) return; int normalDimension = normalStream->descriptor().dimension(); if(normalDimension != 3 && normalDimension != 4) return; float* positionBuffer = (float*)positionStream->map(); if(positionBuffer) { float* normalBuffer = (float*)normalStream->map(); if(normalBuffer) { void* compositeBuffer = vertexBuffer.acquire(vertexCount, true /*writeOnly - we don't need the current buffer values*/); if(compositeBuffer) { void* compositeBufferStart = compositeBuffer; float* compositeBufferAsFloat = (float*)compositeBuffer; int* compositeBufferAsInt = (int*)compositeBuffer; for(unsigned int i = 0; i < vertexCount; ++i) { if(dataType == MGeometry::kFloat) { *(compositeBufferAsFloat++) = *(positionBuffer + 1); // store position.y *(compositeBufferAsFloat++) = *(positionBuffer + 2); // store position.z *(compositeBufferAsFloat++) = *(normalBuffer); // store normal.x if(dimension == 4) *(compositeBufferAsFloat++) = *(normalBuffer + 2); // store normal.z } else if(dataType == MGeometry::kInt32) { *(compositeBufferAsInt++) = (int)(*(positionBuffer + 1) * 255); // store position.y *(compositeBufferAsInt++) = (int)(*(positionBuffer + 2) * 255); // store position.z *(compositeBufferAsInt++) = (int)(*(normalBuffer) * 255); // store normal.x if(dimension == 4) *(compositeBufferAsInt++) = (int)(*(normalBuffer + 2) * 255); // store normal.z } positionBuffer += positionDimension; normalBuffer += normalDimension; } vertexBuffer.commit(compositeBufferStart); } normalStream->unmap(); } positionStream->unmap(); } }