void BaseShapeUI::getDrawRequests( const MDrawInfo & info, bool objectAndActiveOnly, MDrawRequestQueue & requests ) { MStatus status; MDrawData data; BaseShape *shape = (BaseShape *) surfaceShape(); MDrawRequest request = info.getPrototype(*this); M3dView view = info.view(); getDrawData(shape, data); request.setDrawData(data); MDagPath path = request.multiPath(); MMaterial material = MPxSurfaceShapeUI::material(path); if (!(status = material.evaluateMaterial(view, path))) status.perror("MMaterial::evaluateMaterial"); if (!(status = material.evaluateDiffuse())) status.perror("MMaterial::evaluateDiffuse"); request.setMaterial(material); request.setToken(info.displayStyle()); requests.add(request); }
void MFixedRenderer::drawOpaques(MSubMesh * subMesh, MArmature * armature) { M_PROFILE_SCOPE(MFixedRenderer::drawOpaques); // data MVector3 * vertices = subMesh->getVertices(); MVector3 * normals = subMesh->getNormals(); MColor * colors = subMesh->getColors(); if(! vertices) return; MSkinData * skinData = subMesh->getSkinData(); if(armature && skinData) { unsigned int verticesSize = subMesh->getVerticesSize(); unsigned int normalsSize = subMesh->getNormalsSize(); MVector3 * skinVertices = getVertices(verticesSize); MVector3 * skinNormals = getNormals(normalsSize); computeSkinning(armature, skinData, vertices, normals, NULL, skinVertices, skinNormals, NULL); subMesh->getBoundingBox()->initFromPoints(skinVertices, verticesSize); vertices = skinVertices; normals = skinNormals; } unsigned int i; unsigned int displayNumber = subMesh->getDisplaysNumber(); for(i=0; i<displayNumber; i++) { MDisplay * display = subMesh->getDisplay(i); if(! display->isVisible()) continue; MMaterial * material = display->getMaterial(); if(material) { if(material->getBlendMode() == M_BLENDING_NONE) drawDisplay(subMesh, display, vertices, normals, colors); } } }
void animateMaterials(MMesh * mesh, MMaterialsAnim * materialsAnim, float t) { M_PROFILE_SCOPE(animateMaterials); MMaterialAnim * matAnim = materialsAnim->getMaterialsAnim(); float opacity; float shininess; float customValue; MVector3 diffuse; MVector3 specular; MVector3 emit; MVector3 customColor; unsigned int m; unsigned int mSize = materialsAnim->getMaterialsAnimNumber(); for (m = 0; m < mSize; m++) { MMaterial * material = mesh->getMaterial(m); // opacity if(animateFloat(matAnim->getOpacityKeys(), matAnim->getOpacityKeysNumber(), t, &opacity)) material->setOpacity(opacity); // shininess if(animateFloat(matAnim->getShininessKeys(), matAnim->getShininessKeysNumber(), t, &shininess)) material->setShininess(shininess); // customValue if(animateFloat(matAnim->getCustomValueKeys(), matAnim->getCustomValueKeysNumber(), t, &customValue)) material->setCustomValue(customValue); // diffuse if(animateVector3(matAnim->getDiffuseKeys(), matAnim->getDiffuseKeysNumber(), t, &diffuse)) material->setDiffuse(diffuse); // specular if(animateVector3(matAnim->getSpecularKeys(), matAnim->getSpecularKeysNumber(), t, &specular)) material->setSpecular(specular); // emit if(animateVector3(matAnim->getEmitKeys(), matAnim->getEmitKeysNumber(), t, &emit)) material->setEmit(emit); // customColor if(animateVector3(matAnim->getCustomColorKeys(), matAnim->getCustomColorKeysNumber(), t, &customColor)) material->setCustomColor(customColor); matAnim++; } }
void BaseShapeUI::draw( const MDrawRequest & request, M3dView & view ) const { if (s_drawData.failure) return; MStatus status; view.beginGL(); if (!s_drawData.initialized) initializeDraw(); BaseShape *shape = (BaseShape *) surfaceShape(); Model::Base base(MFnDagNode(shape->thisMObject()).parent(0, &status)); if (!status) { status.perror("MFnDagNode::parent"); return; } //MDagPath path = request.multiPath(); MMaterial material = request.material(); MColor color, borderColor; if (!(status = material.getDiffuse(color))) { status.perror("MMaterial::getDiffuse"); return; } bool wireframe = (M3dView::DisplayStyle) request.token() == M3dView::kWireFrame; if (wireframe) { glPushAttrib(GL_POLYGON_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } glUseProgram(s_drawData.program); switch (request.displayStatus()) { case M3dView::kLead : borderColor = view.colorAtIndex( LEAD_COLOR); //glUniform1f(s_drawData.border_uniform, 1.0f); s_drawData.updateBorderUniform(1.0f); //glUniform3f(s_drawData.borderColor_uniform, borderColor.r, borderColor.g, borderColor.b); s_drawData.updateBorderColorUniform(borderColor.r, borderColor.g, borderColor.b); break; case M3dView::kActive : borderColor = view.colorAtIndex( ACTIVE_COLOR); //glUniform1f(s_drawData.border_uniform, 1.0f); s_drawData.updateBorderUniform(1.0f); //glUniform3f(s_drawData.borderColor_uniform, borderColor.r, borderColor.g, borderColor.b); s_drawData.updateBorderColorUniform(borderColor.r, borderColor.g, borderColor.b); break; case M3dView::kActiveAffected : borderColor = view.colorAtIndex( ACTIVE_AFFECTED_COLOR); //glUniform1f(s_drawData.border_uniform, 0.0f); s_drawData.updateBorderUniform(0.0f); break; case M3dView::kDormant : borderColor = view.colorAtIndex( DORMANT_COLOR, M3dView::kDormantColors); //glUniform1f(s_drawData.border_uniform, 0.0f); s_drawData.updateBorderUniform(0.0f); break; case M3dView::kHilite : borderColor = view.colorAtIndex( HILITE_COLOR); //glUniform1f(s_drawData.border_uniform, 1.0f); s_drawData.updateBorderUniform(1.0f); //glUniform3f(s_drawData.borderColor_uniform, borderColor.r, borderColor.g, borderColor.b); s_drawData.updateBorderColorUniform(borderColor.r, borderColor.g, borderColor.b); break; } //glUniform3f(s_drawData.color_uniform, color.r, color.g, color.b); s_drawData.updateColorUniform(color.r, color.g, color.b); glCallList(s_drawData.display_list); if (wireframe) glPopAttrib(); view.endGL(); }
// Mesh bin export bool exportMeshBin(const char * filename, MMesh * mesh) { int version = 2; char rep[256]; bool state; // create file MFile * file = M_fopen(filename, "wb"); if(! file) { printf("Error : can't create file %s\n", filename); return false; } // get file directory getRepertory(rep, filename); // header M_fwrite(M_MESH_HEADER, sizeof(char), 8, file); // version M_fwrite(&version, sizeof(int), 1, file); // Animation { // anim refs MArmatureAnimRef * armatureAnimRef = mesh->getArmatureAnimRef(); MTexturesAnimRef * texturesAnimRef = mesh->getTexturesAnimRef(); MMaterialsAnimRef * materialsAnimRef = mesh->getMaterialsAnimRef(); // armature anim ref writeDataRef(file, armatureAnimRef, rep); // textures anim ref writeDataRef(file, texturesAnimRef, rep); // materials anim ref writeDataRef(file, materialsAnimRef, rep); // anims ranges unsigned int animsRangesNumber = mesh->getAnimsRangesNumber(); MAnimRange * animsRanges = mesh->getAnimsRanges(); M_fwrite(&animsRangesNumber, sizeof(int), 1, file); if(animsRangesNumber > 0) M_fwrite(animsRanges, sizeof(MAnimRange), animsRangesNumber, file); } // Textures { unsigned int t, texturesNumber = mesh->getTexturesNumber(); M_fwrite(&texturesNumber, sizeof(int), 1, file); for(t=0; t<texturesNumber; t++) { MTexture * texture = mesh->getTexture(t); MTextureRef * textureRef = texture->getTextureRef(); M_TEX_GEN_MODES genMode = texture->getGenMode(); M_WRAP_MODES UWrapMode = texture->getUWrapMode(); M_WRAP_MODES VWrapMode = texture->getVWrapMode(); MVector2 texTranslate = texture->getTexTranslate(); MVector2 texScale = texture->getTexScale(); float texRotate = texture->getTexRotate(); // texture ref writeDataRef(file, textureRef, rep); if(textureRef) { bool mipmap = textureRef->isMipmapEnabled(); M_fwrite(&mipmap, sizeof(bool), 1, file); } // data M_fwrite(&genMode, sizeof(M_TEX_GEN_MODES), 1, file); M_fwrite(&UWrapMode, sizeof(M_WRAP_MODES), 1, file); M_fwrite(&VWrapMode, sizeof(M_WRAP_MODES), 1, file); M_fwrite(&texTranslate, sizeof(MVector2), 1, file); M_fwrite(&texScale, sizeof(MVector2), 1, file); M_fwrite(&texRotate, sizeof(float), 1, file); } } // Materials { unsigned int m, materialsNumber = mesh->getMaterialsNumber(); M_fwrite(&materialsNumber, sizeof(int), 1, file); for(m=0; m<materialsNumber; m++) { MMaterial * material = mesh->getMaterial(m); int type = material->getType(); float opacity = material->getOpacity(); float shininess = material->getShininess(); float customValue = material->getCustomValue(); M_BLENDING_MODES blendMode = material->getBlendMode(); MVector3 emit = material->getEmit(); MVector3 diffuse = material->getDiffuse(); MVector3 specular = material->getSpecular(); MVector3 customColor = material->getCustomColor(); MFXRef * FXRef = material->getFXRef(); MFXRef * ZFXRef = material->getZFXRef(); // FX ref state = FXRef != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(FXRef) { MShaderRef * vertShadRef = FXRef->getVertexShaderRef(); MShaderRef * pixShadRef = FXRef->getPixelShaderRef(); writeDataRef(file, vertShadRef, rep); writeDataRef(file, pixShadRef, rep); } // Z FX ref state = ZFXRef != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(ZFXRef) { MShaderRef * vertShadRef = ZFXRef->getVertexShaderRef(); MShaderRef * pixShadRef = ZFXRef->getPixelShaderRef(); writeDataRef(file, vertShadRef, rep); writeDataRef(file, pixShadRef, rep); } // data M_fwrite(&type, sizeof(int), 1, file); M_fwrite(&opacity, sizeof(float), 1, file); M_fwrite(&shininess, sizeof(float), 1, file); M_fwrite(&customValue, sizeof(float), 1, file); M_fwrite(&blendMode, sizeof(M_BLENDING_MODES), 1, file); M_fwrite(&emit, sizeof(MVector3), 1, file); M_fwrite(&diffuse, sizeof(MVector3), 1, file); M_fwrite(&specular, sizeof(MVector3), 1, file); M_fwrite(&customColor, sizeof(MVector3), 1, file); // textures pass unsigned int t, texturesPassNumber = material->getTexturesPassNumber(); M_fwrite(&texturesPassNumber, sizeof(int), 1, file); for(t=0; t<texturesPassNumber; t++) { MTexturePass * texturePass = material->getTexturePass(t); MTexture * texture = texturePass->getTexture(); unsigned int mapChannel = texturePass->getMapChannel(); M_TEX_COMBINE_MODES combineMode = texturePass->getCombineMode(); // texture id int textureId = getTextureId(mesh, texture); M_fwrite(&textureId, sizeof(int), 1, file); // data M_fwrite(&mapChannel, sizeof(int), 1, file); M_fwrite(&combineMode, sizeof(M_TEX_COMBINE_MODES), 1, file); } } } // Bones { MArmature * armature = mesh->getArmature(); state = armature != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(armature) { unsigned int b, bonesNumber = armature->getBonesNumber(); M_fwrite(&bonesNumber, sizeof(int), 1, file); for(b=0; b<bonesNumber; b++) { MOBone * bone = armature->getBone(b); MObject3d * parent = bone->getParent(); MVector3 position = bone->getPosition(); MVector3 scale = bone->getScale(); MQuaternion rotation = bone->getRotation(); // name writeString(file, bone->getName()); // parent id int parentId = -1; if(parent) { unsigned int id; if(armature->getBoneId(parent->getName(), &id)) parentId = (int)id; } M_fwrite(&parentId, sizeof(int), 1, file); // position / rotation / scale M_fwrite(&position, sizeof(MVector3), 1, file); M_fwrite(&rotation, sizeof(MQuaternion), 1, file); M_fwrite(&scale, sizeof(MVector3), 1, file); } } } // BoundingBox { MBox3d * box = mesh->getBoundingBox(); M_fwrite(box, sizeof(MBox3d), 1, file); } // SubMeshs { unsigned int s, subMeshsNumber = mesh->getSubMeshsNumber(); MSubMesh * subMeshs = mesh->getSubMeshs(); M_fwrite(&subMeshsNumber, sizeof(int), 1, file); for(s=0; s<subMeshsNumber; s++) { MSubMesh * subMesh = &(subMeshs[s]); unsigned int indicesSize = subMesh->getIndicesSize(); unsigned int verticesSize = subMesh->getVerticesSize(); unsigned int normalsSize = subMesh->getNormalsSize(); unsigned int tangentsSize = subMesh->getTangentsSize(); unsigned int texCoordsSize = subMesh->getTexCoordsSize(); unsigned int colorsSize = subMesh->getColorsSize(); M_TYPES indicesType = subMesh->getIndicesType(); void * indices = subMesh->getIndices(); MColor * colors = subMesh->getColors(); MVector3 * vertices = subMesh->getVertices(); MVector3 * normals = subMesh->getNormals(); MVector3 * tangents = subMesh->getTangents(); MVector2 * texCoords = subMesh->getTexCoords(); MBox3d * box = subMesh->getBoundingBox(); MSkinData * skin = subMesh->getSkinData(); map<unsigned int, unsigned int> * mapChannelOffsets = subMesh->getMapChannelOffsets(); // BoundingBox M_fwrite(box, sizeof(MBox3d), 1, file); // indices M_fwrite(&indicesSize, sizeof(int), 1, file); if(indicesSize > 0) { // indice type M_fwrite(&indicesType, sizeof(M_TYPES), 1, file); switch(indicesType) { case M_USHORT: M_fwrite(indices, sizeof(short), indicesSize, file); break; case M_UINT: M_fwrite(indices, sizeof(int), indicesSize, file); break; } } // vertices M_fwrite(&verticesSize, sizeof(int), 1, file); if(verticesSize > 0) M_fwrite(vertices, sizeof(MVector3), verticesSize, file); // normals M_fwrite(&normalsSize, sizeof(int), 1, file); if(normalsSize > 0) M_fwrite(normals, sizeof(MVector3), normalsSize, file); // tangents M_fwrite(&tangentsSize, sizeof(int), 1, file); if(tangentsSize > 0) M_fwrite(tangents, sizeof(MVector3), tangentsSize, file); // texCoords M_fwrite(&texCoordsSize, sizeof(int), 1, file); if(texCoordsSize > 0) M_fwrite(texCoords, sizeof(MVector2), texCoordsSize, file); // colors M_fwrite(&colorsSize, sizeof(int), 1, file); if(colorsSize > 0) M_fwrite(colors, sizeof(MColor), colorsSize, file); // mapChannels { unsigned int size = mapChannelOffsets->size(); M_fwrite(&size, sizeof(int), 1, file); map<unsigned int, unsigned int>::iterator mit (mapChannelOffsets->begin()), mend(mapChannelOffsets->end()); for(;mit!=mend;++mit) { M_fwrite(&mit->first, sizeof(int), 1, file); M_fwrite(&mit->second, sizeof(int), 1, file); } } // Skins state = skin != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(skin) { // skin point unsigned int p, pointsNumber = skin->getPointsNumber(); M_fwrite(&pointsNumber, sizeof(int), 1, file); for(p=0; p<pointsNumber; p++) { MSkinPoint * skinPoint = skin->getPoint(p); unsigned int vertexId = skinPoint->getVertexId(); unsigned int bonesNumber = skinPoint->getBonesNumber(); unsigned short * bonesIds = skinPoint->getBonesIds(); float * bonesWeights = skinPoint->getBonesWeights(); // data M_fwrite(&vertexId, sizeof(int), 1, file); M_fwrite(&bonesNumber, sizeof(int), 1, file); if(bonesNumber > 0) { M_fwrite(bonesIds, sizeof(short), bonesNumber, file); M_fwrite(bonesWeights, sizeof(float), bonesNumber, file); } } } // Displays unsigned int d, displaysNumber = subMesh->getDisplaysNumber(); M_fwrite(&displaysNumber, sizeof(int), 1, file); for(d=0; d<displaysNumber; d++) { MDisplay * display = subMesh->getDisplay(d); M_PRIMITIVE_TYPES primitiveType = display->getPrimitiveType(); unsigned int begin = display->getBegin(); unsigned int size = display->getSize(); MMaterial * material = display->getMaterial(); M_CULL_MODES cullMode = display->getCullMode(); int materialId = getMaterialId(mesh, material); // data M_fwrite(&primitiveType, sizeof(M_PRIMITIVE_TYPES), 1, file); M_fwrite(&begin, sizeof(int), 1, file); M_fwrite(&size, sizeof(int), 1, file); M_fwrite(&materialId, sizeof(int), 1, file); M_fwrite(&cullMode, sizeof(M_CULL_MODES), 1, file); } } } M_fclose(file); return true; }
void MFixedRenderer::drawTransparents(MSubMesh * subMesh, MArmature * armature) { M_PROFILE_SCOPE(MFixedRenderer::drawTransparents); MRenderingContext * render = MEngine::getInstance()->getRenderingContext(); // data MVector3 * vertices = subMesh->getVertices(); MVector3 * normals = subMesh->getNormals(); MColor * colors = subMesh->getColors(); if(! vertices) return; MSkinData * skinData = subMesh->getSkinData(); if(armature && skinData) { unsigned int verticesSize = subMesh->getVerticesSize(); unsigned int normalsSize = subMesh->getNormalsSize(); MVector3 * skinVertices = getVertices(verticesSize); MVector3 * skinNormals = getNormals(normalsSize); computeSkinning(armature, skinData, vertices, normals, NULL, skinVertices, skinNormals, NULL); subMesh->getBoundingBox()->initFromPoints(skinVertices, verticesSize); vertices = skinVertices; normals = skinNormals; } render->setColorMask(0, 0, 0, 0); unsigned int i; unsigned int displayNumber = subMesh->getDisplaysNumber(); for(i=0; i<displayNumber; i++) { MDisplay * display = subMesh->getDisplay(i); if((! display->isVisible()) || (! display->getMaterial())) continue; if(display->getMaterial()->getBlendMode() == M_BLENDING_ALPHA) drawDisplayTriangles(subMesh, display, vertices); } render->setColorMask(1, 1, 1, 1); render->setDepthMask(0); for(i=0; i<displayNumber; i++) { MDisplay * display = subMesh->getDisplay(i); if(! display->isVisible()) continue; MMaterial * material = display->getMaterial(); if(material) { if(material->getBlendMode() != M_BLENDING_NONE) drawDisplay(subMesh, display, vertices, normals, colors); } } render->setDepthMask(1); }
void MFixedRenderer::drawDisplay(MSubMesh * subMesh, MDisplay * display, MVector3 * vertices, MVector3 * normals, MColor * colors) { M_PROFILE_SCOPE(MFixedRenderer::drawDisplay); MEngine * engine = MEngine::getInstance(); MRenderingContext * render = engine->getRenderingContext(); render->setColor4(MVector4(1, 1, 1, 1)); // get material MMaterial * material = display->getMaterial(); { float opacity = material->getOpacity(); if(opacity <= 0.0f) return; // data M_TYPES indicesType = subMesh->getIndicesType(); void * indices = subMesh->getIndices(); MVector2 * texCoords = subMesh->getTexCoords(); // begin / size unsigned int begin = display->getBegin(); unsigned int size = display->getSize(); // get properties M_PRIMITIVE_TYPES primitiveType = display->getPrimitiveType(); M_BLENDING_MODES blendMode = material->getBlendMode(); M_CULL_MODES cullMode = display->getCullMode(); MVector3 * diffuse = material->getDiffuse(); MVector3 * specular = material->getSpecular(); MVector3 * emit = material->getEmit(); float shininess = material->getShininess(); // get current fog color MVector3 currentFogColor; render->getFogColor(¤tFogColor); // set cull mode if(cullMode == M_CULL_NONE){ render->disableCullFace(); } else{ render->enableCullFace(); render->setCullMode(cullMode); } // texture passes unsigned int texturesPassNumber = MIN(8, material->getTexturesPassNumber()); // set blending mode render->setBlendingMode(blendMode); // alpha test if(blendMode != M_BLENDING_ALPHA && texturesPassNumber > 0) { MTexturePass * texturePass = material->getTexturePass(0); MTexture * texture = texturePass->getTexture(); if(texture) { if(texture->getTextureRef()->getComponents() > 3) render->setAlphaTest(0.5f); } } // set fog color depending on blending switch(blendMode) { case M_BLENDING_ADD: case M_BLENDING_LIGHT: render->setFogColor(MVector3(0, 0, 0)); break; case M_BLENDING_PRODUCT: render->setFogColor(MVector3(1, 1, 1)); break; } // fixed pipeline { // no FX render->bindFX(0); // Vertex render->enableVertexArray(); render->setVertexPointer(M_FLOAT, 3, vertices); // Normal if(normals) { render->enableNormalArray(); render->setNormalPointer(M_FLOAT, normals); } // Color if(colors) { render->disableLighting(); render->enableColorArray(); render->setColorPointer(M_UBYTE, 4, colors); } // Material render->setMaterialDiffuse(MVector4(diffuse->x, diffuse->y, diffuse->z, opacity)); render->setMaterialSpecular(MVector4(*specular)); render->setMaterialAmbient(MVector4()); render->setMaterialEmit(MVector4(*emit)); render->setMaterialShininess(shininess); // switch to texture matrix mode if(texturesPassNumber > 0) render->setMatrixMode(M_MATRIX_TEXTURE); else render->disableTexture(); // Textures int id = texturesPassNumber; for(unsigned int t=0; t<texturesPassNumber; t++) { MTexturePass * texturePass = material->getTexturePass(t); MTexture * texture = texturePass->getTexture(); if((! texture) || (! texCoords)) { render->bindTexture(0, t); render->disableTexture(); render->disableTexCoordArray(); continue; } // texCoords unsigned int offset = 0; if(subMesh->isMapChannelExist(texturePass->getMapChannel())) offset = subMesh->getMapChannelOffset(texturePass->getMapChannel()); // texture id unsigned int textureId = 0; MTextureRef * texRef = texture->getTextureRef(); if(texRef) textureId = texRef->getTextureId(); // bind texture render->bindTexture(textureId, t); render->enableTexture(); render->setTextureCombineMode(texturePass->getCombineMode()); render->setTextureUWrapMode(texture->getUWrapMode()); render->setTextureVWrapMode(texture->getVWrapMode()); // texture matrix render->loadIdentity(); render->translate(MVector2(0.5f, 0.5f)); render->scale(*texture->getTexScale()); render->rotate(MVector3(0, 0, -1), texture->getTexRotate()); render->translate(MVector2(-0.5f, -0.5f)); render->translate(*texture->getTexTranslate()); // texture coords render->enableTexCoordArray(); render->setTexCoordPointer(M_FLOAT, 2, texCoords + offset); } // switch back to modelview matrix mode if(texturesPassNumber > 0) render->setMatrixMode(M_MATRIX_MODELVIEW); // draw if(indices) { switch(indicesType) { case M_USHORT: render->drawElement(primitiveType, size, indicesType, (unsigned short*)indices + begin); break; case M_UINT: render->drawElement(primitiveType, size, indicesType, (unsigned int*)indices + begin); break; } } else{ render->drawArray(primitiveType, begin, size); } // disable arrays render->disableVertexArray(); if(normals) render->disableNormalArray(); if(colors) render->disableColorArray(); // restore textures for(int t=(int)(id-1); t>=0; t--) { render->bindTexture(0, t); render->disableTexture(); render->disableTexCoordArray(); render->setTextureCombineMode(M_TEX_COMBINE_MODULATE); render->setMatrixMode(M_MATRIX_TEXTURE); render->loadIdentity(); render->setMatrixMode(M_MATRIX_MODELVIEW); } } // restore fog and alpha test render->setFogColor(currentFogColor); if(blendMode != M_BLENDING_ALPHA) render->setAlphaTest(0.0f); // restore lighting if(colors) render->enableLighting(); } }
/// \todo We should be firing off a separate drawRequest for the components, then we can be done with the "hiliteGroups" mechanism. void ProceduralHolderUI::getDrawRequests( const MDrawInfo &info, bool objectAndActiveOnly, MDrawRequestQueue &requests ) { // it's easy if noone want to look at us if( !info.objectDisplayStatus( M3dView::kDisplayMeshes ) ) { return; } // the node we're meant to be drawing ProceduralHolder *proceduralHolder = (ProceduralHolder *)surfaceShape(); // draw data encapsulating that node MDrawData drawData; getDrawData( proceduralHolder, drawData ); // a request for the bound if necessary MPlug pDrawBound( proceduralHolder->thisMObject(), ProceduralHolder::aDrawBound ); bool drawBound = true; pDrawBound.getValue( drawBound ); if( drawBound ) { MDrawRequest request = info.getPrototype( *this ); request.setDrawData( drawData ); request.setToken( BoundDrawMode ); request.setDisplayStyle( M3dView::kWireFrame ); setWireFrameColors( request, info.displayStatus() ); requests.add( request ); } // requests for the scene if necessary MPlug pGLPreview( proceduralHolder->thisMObject(), ProceduralHolder::aGLPreview ); bool glPreview = false; pGLPreview.getValue( glPreview ); if( glPreview ) { if( info.displayStyle()==M3dView::kGouraudShaded || info.displayStyle()==M3dView::kFlatShaded ) { // make a request for solid drawing with a material MDrawRequest solidRequest = info.getPrototype( *this ); solidRequest.setDrawData( drawData ); MDagPath path = info.multiPath(); M3dView view = info.view(); MMaterial material = MPxSurfaceShapeUI::material( path ); if( !material.evaluateMaterial( view, path ) ) { MString pathName = path.fullPathName(); IECore::msg( IECore::Msg::Warning, "ProceduralHolderUI::getDrawRequests", boost::format( "Failed to evaluate material for \"%s\"." ) % pathName.asChar() ); } if( material.materialIsTextured() ) { material.evaluateTexture( drawData ); } solidRequest.setMaterial( material ); // set the transparency request. we don't have a decent way of finding out // if shaders applied by the procedural are transparent, so we've got a transparency // attribute on the procedural holder for users to use. maya materials may also say // they're transparent. if either asks for transparency then we'll ask for it here bool transparent = false; material.getHasTransparency( transparent ); if( !transparent ) { MPlug pT( proceduralHolder->thisMObject(), ProceduralHolder::aTransparent ); bool transparent = false; pT.getValue( transparent ); } solidRequest.setIsTransparent( transparent ); solidRequest.setToken( SceneDrawMode ); requests.add( solidRequest ); // and add another request for wireframe drawing if we're selected if( info.displayStatus()==M3dView::kActive || info.displayStatus()==M3dView::kLead || info.displayStatus()==M3dView::kHilite ) { MDrawRequest wireRequest = info.getPrototype( *this ); wireRequest.setDrawData( drawData ); wireRequest.setDisplayStyle( M3dView::kWireFrame ); wireRequest.setToken( SceneDrawMode ); setWireFrameColors( wireRequest, info.displayStatus() ); wireRequest.setComponent( MObject::kNullObj ); if ( !objectAndActiveOnly ) { if ( proceduralHolder->hasActiveComponents() ) { MObjectArray components = proceduralHolder->activeComponents(); MObject component = components[0]; // Should filter list wireRequest.setComponent( component ); } } requests.add( wireRequest ); } } else { MDrawRequest request = info.getPrototype( *this ); request.setDrawData( drawData ); setWireFrameColors( request, info.displayStatus() ); request.setToken( SceneDrawMode ); request.setComponent( MObject::kNullObj ); if ( !objectAndActiveOnly ) { if ( proceduralHolder->hasActiveComponents() ) { MObjectArray components = proceduralHolder->activeComponents(); MObject component = components[0]; // Should filter list request.setComponent( component ); } } requests.add( request ); } } }
/* virtual */ MStatus pnTriangles::bind(const MDrawRequest& request, M3dView& view) // // Description: // This bind demonstrates the usage of internal material // and texture properties. This shader must be connected // to the "hardwareShader" attribute of a lambert derived // shader. // { // Setup the view view.beginGL(); glPushAttrib( GL_ALL_ATTRIB_BITS ); glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); MColor diffuse(1.0F, 1.0F, 0.0F, 1.0F); MColor specular(1.0F, 1.0F, 1.0F, 1.0F); MColor emission(0.0F, 0.0F, 0.0F, 1.0F); MColor ambient(0.2F, 0.2F, 0.2F, 1.0F); // Get the diffuse and specular colors // float shininess; bool hasTransparency = false; MMaterial material = request.material(); fInTexturedMode = material.materialIsTextured(); // Setting this to true will get the default "green" material back // since it will try and evaluate this shader, which internally // Maya does not understand -> thus giving the "green" material back bool useInternalMaterialSetting = false; if (!useInternalMaterialSetting) { material.getEmission( emission ); material.getSpecular( specular ); shininess = 13.0; } material.getHasTransparency( hasTransparency ); if (!fInTexturedMode) { if (!fTestVertexProgram && !useInternalMaterialSetting) material.getDiffuse( diffuse ); } // In textured mode. Diffuse material is always white // for texture blends else { if (!useInternalMaterialSetting) diffuse.r = diffuse.g = diffuse.b = diffuse.a = 1.0; } // Use a vertex program to set up shading // if (fTestVertexProgram) { bindVertexProgram(diffuse, specular, emission, ambient); } else if (fTestFragmentProgram) { bindFragmentProgram(); } // Don't use a vertex program to set up shading // else { // Set up the material state // glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); glColor4fv(&ambient.r); if (fInTexturedMode) { glEnable( GL_TEXTURE_2D ); MDrawData drawData = request.drawData(); material.applyTexture( view, drawData ); float scaleS, scaleT, translateS, translateT, rotate; material.getTextureTransformation(scaleS, scaleT, translateS, translateT, rotate); rotate = DEG_TO_RAD(-rotate); float c = cosf(rotate); float s = sinf(rotate); translateS += ((c+s)/2.0F); translateT += ((c-s)/2.0F); glMatrixMode(GL_TEXTURE); glPushMatrix(); glLoadIdentity(); if(scaleS != 1.0f || scaleT != 1.0f) glScalef(1.0f/scaleS, 1.0f/scaleT, 1.0f); if(translateS != 0.0f || translateT != 0.0f) glTranslatef(0.5f-translateS, 0.5f-translateT, 0.0f); else glTranslatef(0.5f, 0.5f, 0.0f); if(rotate != 0.0f) glRotatef(-rotate, 0.0f, 0.0f, 1.0f); glMatrixMode(GL_MODELVIEW); } if (!useInternalMaterialSetting) { glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glColor4fv(&diffuse.r); glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); glColor4fv(&specular.r); glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION); glColor4fv(&emission.r); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess); } else { const MDagPath dagPath = request.multiPath(); material.evaluateMaterial( view, dagPath ); material.setMaterial(dagPath, hasTransparency); } } // Do PN triangles in hardware, or do nothing // if LOD = 0 if (fExtensionSupported[kPNTriangesEXT] || (fSubdivisions == 0)) { if (fSubdivisions != 0) { glEnable( GL_PN_TRIANGLES_ATI ); // Set point mode // if (fPointMode == kPointLinear) glPNTrianglesiATI( GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI); else glPNTrianglesiATI( GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI); // Set normal mode // if (fNormalMode == kNormalLinear) glPNTrianglesiATI( GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI); else glPNTrianglesiATI( GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI); // Set tessellation level // glPNTrianglesiATI( GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, fSubdivisions ); } } view.endGL(); return MS::kSuccess; }
/* override */ void apiSimpleShapeUI::getDrawRequests( const MDrawInfo & info, bool objectAndActiveOnly, MDrawRequestQueue & queue ) // // Description: // // Add draw requests to the draw queue // // Arguments: // // info - current drawing state // objectsAndActiveOnly - no components if true // queue - queue of draw requests to add to // { // Get the data necessary to draw the shape // MDrawData data; apiSimpleShape* shape = (apiSimpleShape*) surfaceShape(); MVectorArray* geomPtr = shape->getControlPoints(); // This call creates a prototype draw request that we can fill // in and then add to the draw queue. // MDrawRequest request = info.getPrototype( *this ); // Stuff our data into the draw request, it'll be used when the drawing // actually happens getDrawData( geomPtr, data ); request.setDrawData( data ); // Decode the draw info and determine what needs to be drawn // M3dView::DisplayStyle appearance = info.displayStyle(); M3dView::DisplayStatus displayStatus = info.displayStatus(); switch ( appearance ) { case M3dView::kWireFrame : { request.setToken( kDrawWireframe ); M3dView::ColorTable activeColorTable = M3dView::kActiveColors; M3dView::ColorTable dormantColorTable = M3dView::kDormantColors; switch ( displayStatus ) { case M3dView::kLead : request.setColor( LEAD_COLOR, activeColorTable ); break; case M3dView::kActive : request.setColor( ACTIVE_COLOR, activeColorTable ); break; case M3dView::kActiveAffected : request.setColor( ACTIVE_AFFECTED_COLOR, activeColorTable ); break; case M3dView::kDormant : request.setColor( DORMANT_COLOR, dormantColorTable ); break; case M3dView::kHilite : request.setColor( HILITE_COLOR, activeColorTable ); break; default: break; } queue.add( request ); break; } case M3dView::kGouraudShaded : { // Create the smooth shaded draw request // request.setToken( kDrawSmoothShaded ); // Need to get the material info // MDagPath path = info.multiPath(); // path to your dag object M3dView view = info.view();; // view to draw to MMaterial material = MPxSurfaceShapeUI::material( path ); // Evaluate the material and if necessary, the texture. // if ( ! material.evaluateMaterial( view, path ) ) { cerr << "Couldnt evaluate\n"; } bool drawTexture = true; if ( drawTexture && material.materialIsTextured() ) { material.evaluateTexture( data ); } request.setMaterial( material ); // request.setDisplayStyle( appearance ); bool materialTransparent = false; material.getHasTransparency( materialTransparent ); if ( materialTransparent ) { request.setIsTransparent( true ); } queue.add( request ); // create a draw request for wireframe on shaded if // necessary. // if ( (displayStatus == M3dView::kActive) || (displayStatus == M3dView::kLead) || (displayStatus == M3dView::kHilite) ) { MDrawRequest wireRequest = info.getPrototype( *this ); wireRequest.setDrawData( data ); wireRequest.setToken( kDrawWireframeOnShaded ); wireRequest.setDisplayStyle( M3dView::kWireFrame ); M3dView::ColorTable activeColorTable = M3dView::kActiveColors; switch ( displayStatus ) { case M3dView::kLead : wireRequest.setColor( LEAD_COLOR, activeColorTable ); break; case M3dView::kActive : wireRequest.setColor( ACTIVE_COLOR, activeColorTable ); break; case M3dView::kHilite : wireRequest.setColor( HILITE_COLOR, activeColorTable ); break; default : break; } queue.add( wireRequest ); } break; } case M3dView::kFlatShaded : request.setToken( kDrawFlatShaded ); break; default: break; } // Add draw requests for components // if ( !objectAndActiveOnly ) { // Inactive components // if ( (appearance == M3dView::kPoints) || (displayStatus == M3dView::kHilite) ) { MDrawRequest vertexRequest = info.getPrototype( *this ); vertexRequest.setDrawData( data ); vertexRequest.setToken( kDrawVertices ); vertexRequest.setColor( DORMANT_VERTEX_COLOR, M3dView::kActiveColors ); queue.add( vertexRequest ); } // Active components // if ( surfaceShape()->hasActiveComponents() ) { MDrawRequest activeVertexRequest = info.getPrototype( *this ); activeVertexRequest.setDrawData( data ); activeVertexRequest.setToken( kDrawVertices ); activeVertexRequest.setColor( ACTIVE_VERTEX_COLOR, M3dView::kActiveColors ); MObjectArray clist = surfaceShape()->activeComponents(); MObject vertexComponent = clist[0]; // Should filter list activeVertexRequest.setComponent( vertexComponent ); queue.add( activeVertexRequest ); } } }
bool xmlMeshLoad(const char * filename, void * data) { MLOG_DEBUG("xmlMeshLoad " << filename?filename:"NULL"); MLevel * level = MEngine::getInstance()->getLevel(); // read document TiXmlDocument doc(filename); if(! doc.LoadFile()) { MLOG_WARNING("TiXmlDocument load failed : " << doc.ErrorDesc() << " line " << doc.ErrorRow()); return false; } TiXmlHandle hDoc(&doc); TiXmlElement * pRootNode; TiXmlHandle hRoot(0); // Maratis pRootNode = hDoc.FirstChildElement().Element(); if(! pRootNode) { MLOG_WARNING("Cannot find any root node"); return false; } if(strcmp(pRootNode->Value(), "Maratis") != 0) { MLOG_WARNING("Cannot find Maratis root node"); return false; } hRoot = TiXmlHandle(pRootNode); // Mesh TiXmlElement * pMeshNode = pRootNode->FirstChildElement("Mesh"); if(! pMeshNode) { MLOG_WARNING("Cannot find a Mesh node"); return false; } // create new mesh MMesh * mesh = (MMesh *)data; mesh->clear(); char path[256]; char meshRep[256]; char vertShadPath[256]; char fragShadPath[256]; // mesh rep getRepertory(meshRep, filename); // animation if(! loadAnim(pMeshNode, meshRep, mesh)) { // load external anim file (depracated) char animFilename[256]; strcpy(animFilename, filename); strcpy(animFilename + strlen(animFilename) - 4, "anim"); loadAnimFile(mesh, animFilename, meshRep); } // Textures TiXmlElement * texturesNode = pMeshNode->FirstChildElement("Textures"); if(texturesNode) { MLOG_DEBUG("entering Textures node"); unsigned int numTextures = 0; texturesNode->QueryUIntAttribute("num", &numTextures); mesh->allocTextures(numTextures); // Texture TiXmlElement * textureNode = texturesNode->FirstChildElement("Texture"); for(textureNode; textureNode; textureNode=textureNode->NextSiblingElement("Texture")) { const char * file = NULL; bool mipmap = true; // image TiXmlElement * imageNode = textureNode->FirstChildElement("image"); if(imageNode) { int value = 1; file = imageNode->Attribute("filename"); imageNode->QueryIntAttribute("mipmap", &value); mipmap = (value == 1); } if(! file) { mesh->addNewTexture(NULL); continue; } // load texture getGlobalFilename(path, meshRep, file); MTextureRef * texRef = level->loadTexture(path, mipmap); MTexture * texture = mesh->addNewTexture(texRef); // tile TiXmlElement * tileNode = textureNode->FirstChildElement("tile"); if(tileNode) { const char * uTile = tileNode->Attribute("u"); const char * vTile = tileNode->Attribute("v"); if(uTile){ if(strcmp(uTile, "clamp") == 0) texture->setUWrapMode(M_WRAP_CLAMP); else texture->setUWrapMode(M_WRAP_REPEAT); } if(vTile){ if(strcmp(vTile, "clamp") == 0) texture->setVWrapMode(M_WRAP_CLAMP); else texture->setVWrapMode(M_WRAP_REPEAT); } } // translate TiXmlElement * translateNode = textureNode->FirstChildElement("translate"); if(translateNode) { MVector2 translate = texture->getTexTranslate(); translateNode->QueryFloatAttribute("x", &translate.x); translateNode->QueryFloatAttribute("y", &translate.y); texture->setTexTranslate(translate); } // scale TiXmlElement * scaleNode = textureNode->FirstChildElement("scale"); if(scaleNode) { MVector2 scale = texture->getTexScale(); scaleNode->QueryFloatAttribute("x", &scale.x); scaleNode->QueryFloatAttribute("y", &scale.y); texture->setTexScale(scale); } // rotate TiXmlElement * rotateNode = textureNode->FirstChildElement("rotate"); if(rotateNode) { float angle = 0; rotateNode->QueryFloatAttribute("angle", &angle); texture->setTexRotate(angle); } } } // Materials TiXmlElement * materialsNode = pMeshNode->FirstChildElement("Materials"); if(materialsNode) { MLOG_DEBUG("entering Materials node"); unsigned int numMaterials = 0; materialsNode->QueryUIntAttribute("num", &numMaterials); mesh->allocMaterials(numMaterials); // Material TiXmlElement * materialNode = materialsNode->FirstChildElement("Material"); for(materialNode; materialNode; materialNode=materialNode->NextSiblingElement("Material")) { MMaterial * material = mesh->addNewMaterial(); int type = 0; materialNode->QueryIntAttribute("type", &type); material->setType(type); float opacity=1, shininess=0, customValue=0; MVector3 diffuseColor; MVector3 specularColor; MVector3 emitColor; MVector3 customColor; // blend int blendType = 0; TiXmlElement * blendNode = materialNode->FirstChildElement("blend"); if(blendNode) blendNode->QueryIntAttribute("type", &blendType); switch(blendType) { case 2: material->setBlendMode(M_BLENDING_ALPHA); break; case 3: material->setBlendMode(M_BLENDING_ADD); break; case 4: material->setBlendMode(M_BLENDING_PRODUCT); break; } // opacity TiXmlElement * opacityNode = materialNode->FirstChildElement("opacity"); if(opacityNode) opacityNode->QueryFloatAttribute("value", &opacity); // shininess TiXmlElement * shininessNode = materialNode->FirstChildElement("shininess"); if(shininessNode) shininessNode->QueryFloatAttribute("value", &shininess); // customValue TiXmlElement * customValueNode = materialNode->FirstChildElement("customValue"); if(customValueNode) customValueNode->QueryFloatAttribute("value", &customValue); material->setOpacity(opacity); material->setShininess(shininess); material->setCustomValue(customValue); // diffuseColor TiXmlElement * diffuseColorNode = materialNode->FirstChildElement("diffuseColor"); if(diffuseColorNode){ diffuseColorNode->QueryFloatAttribute("r", &diffuseColor.x); diffuseColorNode->QueryFloatAttribute("g", &diffuseColor.y); diffuseColorNode->QueryFloatAttribute("b", &diffuseColor.z); material->setDiffuse(diffuseColor); } // specularColor TiXmlElement * specularColorNode = materialNode->FirstChildElement("specularColor"); if(specularColorNode){ specularColorNode->QueryFloatAttribute("r", &specularColor.x); specularColorNode->QueryFloatAttribute("g", &specularColor.y); specularColorNode->QueryFloatAttribute("b", &specularColor.z); material->setSpecular(specularColor); } // emitColor TiXmlElement * emitColorNode = materialNode->FirstChildElement("emitColor"); if(emitColorNode){ emitColorNode->QueryFloatAttribute("r", &emitColor.x); emitColorNode->QueryFloatAttribute("g", &emitColor.y); emitColorNode->QueryFloatAttribute("b", &emitColor.z); material->setEmit(emitColor); } // customColor TiXmlElement * customColorNode = materialNode->FirstChildElement("customColor"); if(customColorNode){ customColorNode->QueryFloatAttribute("r", &customColor.x); customColorNode->QueryFloatAttribute("g", &customColor.y); customColorNode->QueryFloatAttribute("b", &customColor.z); material->setCustomColor(customColor); } // TexturesPass TiXmlElement * texturesPassNode = materialNode->FirstChildElement("TexturesPass"); if(texturesPassNode) { unsigned int numTexturesPass = 0; texturesPassNode->QueryUIntAttribute("num", &numTexturesPass); material->allocTexturesPass(numTexturesPass); // texturePass TiXmlElement * texturePassNode = texturesPassNode->FirstChildElement("texturePass"); for(texturePassNode; texturePassNode; texturePassNode=texturePassNode->NextSiblingElement("texturePass")) { int textureId = -1; unsigned int mapChannel = 0; const char * mode = texturePassNode->Attribute("mode"); texturePassNode->QueryIntAttribute("texture", &textureId); if(textureId < 0) { material->addTexturePass(NULL, M_TEX_COMBINE_MODULATE, 0); continue; } texturePassNode->QueryUIntAttribute("mapChannel", &mapChannel); // combine mode M_TEX_COMBINE_MODES texCombine = M_TEX_COMBINE_MODULATE; if(strcmp(mode, "modulate") == 0) texCombine = M_TEX_COMBINE_MODULATE; else if(strcmp(mode, "replace") == 0) texCombine = M_TEX_COMBINE_REPLACE; else if(strcmp(mode, "alpha") == 0) texCombine = M_TEX_COMBINE_ALPHA; else if(strcmp(mode, "dot") == 0) texCombine = M_TEX_COMBINE_DOT; else if(strcmp(mode, "add") == 0) texCombine = M_TEX_COMBINE_ADD; else if(strcmp(mode, "sub") == 0) texCombine = M_TEX_COMBINE_SUB; // add texture pass material->addTexturePass(mesh->getTexture(textureId), texCombine, mapChannel); } } // FX { // vertexShader const char * vertShadFile = NULL; TiXmlElement * vertexShaderNode = materialNode->FirstChildElement("vertexShader"); if(vertexShaderNode){ vertShadFile = vertexShaderNode->Attribute("file"); } // fragmentShader const char * fragShadFile = NULL; TiXmlElement * fragmentShaderNode = materialNode->FirstChildElement("fragmentShader"); if(fragmentShaderNode){ fragShadFile = fragmentShaderNode->Attribute("file"); } // create FX if(vertShadFile && fragShadFile) { getGlobalFilename(vertShadPath, meshRep, vertShadFile); getGlobalFilename(fragShadPath, meshRep, fragShadFile); MShaderRef * vertShad = level->loadShader(vertShadPath, M_SHADER_VERTEX); MShaderRef * pixShad = level->loadShader(fragShadPath, M_SHADER_PIXEL); if(vertShad && pixShad) { MFXRef * FXRef = level->createFX(vertShad, pixShad); material->setFXRef(FXRef); } } } // ZFX (optional optim) { // ZVertexShader const char * vertShadFile = NULL; TiXmlElement * vertexShaderNode = materialNode->FirstChildElement("ZVertexShader"); if(vertexShaderNode){ vertShadFile = vertexShaderNode->Attribute("file"); } // ZFragmentShader const char * fragShadFile = NULL; TiXmlElement * fragmentShaderNode = materialNode->FirstChildElement("ZFragmentShader"); if(fragmentShaderNode){ fragShadFile = fragmentShaderNode->Attribute("file"); } // create ZFX if(vertShadFile && fragShadFile) { getGlobalFilename(vertShadPath, meshRep, vertShadFile); getGlobalFilename(fragShadPath, meshRep, fragShadFile); MShaderRef * vertShad = level->loadShader(vertShadPath, M_SHADER_VERTEX); MShaderRef * pixShad = level->loadShader(fragShadPath, M_SHADER_PIXEL); if(vertShad && pixShad) { MFXRef * ZFXRef = level->createFX(vertShad, pixShad); material->setZFXRef(ZFXRef); } } } } } // Bones TiXmlElement * bonesNode = pMeshNode->FirstChildElement("Bones"); if(bonesNode) { MLOG_DEBUG("entering Bones node"); MArmature * armature = mesh->createArmature(); unsigned int b, numBones = 0; bonesNode->QueryUIntAttribute("num", &numBones); armature->allocBones(numBones); // add bones for(b=0; b<numBones; b++) armature->addNewBone(); b = 0; // Bone TiXmlElement * boneNode = bonesNode->FirstChildElement("Bone"); for(boneNode; boneNode; boneNode=boneNode->NextSiblingElement("Bone")) { if(b >= armature->getBonesNumber()) break; MOBone * bone = armature->getBone(b); const char * name = boneNode->Attribute("name"); if(name) bone->setName(name); // parent TiXmlElement * parentNode = boneNode->FirstChildElement("parent"); if(parentNode){ unsigned int boneId = 0; parentNode->QueryUIntAttribute("id", &boneId); bone->linkTo(armature->getBone(boneId)); } // position TiXmlElement * positionNode = boneNode->FirstChildElement("position"); if(positionNode){ MVector3 position; positionNode->QueryFloatAttribute("x", &position.x); positionNode->QueryFloatAttribute("y", &position.y); positionNode->QueryFloatAttribute("z", &position.z); bone->setPosition(position); } // rotation TiXmlElement * rotationNode = boneNode->FirstChildElement("rotation"); if(rotationNode){ MVector3 euler; rotationNode->QueryFloatAttribute("x", &euler.x); rotationNode->QueryFloatAttribute("y", &euler.y); rotationNode->QueryFloatAttribute("z", &euler.z); bone->setEulerRotation(euler); } // scale TiXmlElement * scaleNode = boneNode->FirstChildElement("scale"); if(scaleNode){ MVector3 scale; scaleNode->QueryFloatAttribute("x", &scale.x); scaleNode->QueryFloatAttribute("y", &scale.y); scaleNode->QueryFloatAttribute("z", &scale.z); bone->setScale(scale); } b++; } // construct bones inverse pose matrix armature->constructBonesInversePoseMatrix(); } // SubMeshs TiXmlElement * subMeshsNode = pMeshNode->FirstChildElement("SubMeshs"); if(! subMeshsNode) return true; unsigned int numSubMeshs = 0; subMeshsNode->QueryUIntAttribute("num", &numSubMeshs); if(numSubMeshs == 0) return true; // alloc subMeshs MSubMesh * subMeshs = mesh->allocSubMeshs(numSubMeshs); // BoundingBox TiXmlElement * boundingBoxNode = pMeshNode->FirstChildElement("BoundingBox"); if(boundingBoxNode) { MVector3 * min = &mesh->getBoundingBox()->min; MVector3 * max = &mesh->getBoundingBox()->max; boundingBoxNode->QueryFloatAttribute("minx", &min->x); boundingBoxNode->QueryFloatAttribute("miny", &min->y); boundingBoxNode->QueryFloatAttribute("minz", &min->z); boundingBoxNode->QueryFloatAttribute("maxx", &max->x); boundingBoxNode->QueryFloatAttribute("maxy", &max->y); boundingBoxNode->QueryFloatAttribute("maxz", &max->z); } // SubMesh TiXmlElement * SubMeshNode = subMeshsNode->FirstChildElement("SubMesh"); for(SubMeshNode; SubMeshNode; SubMeshNode=SubMeshNode->NextSiblingElement("SubMesh")) { MSubMesh * subMesh = subMeshs; // BoundingBox boundingBoxNode = SubMeshNode->FirstChildElement("BoundingBox"); if(boundingBoxNode) { MVector3 * min = &subMesh->getBoundingBox()->min; MVector3 * max = &subMesh->getBoundingBox()->max; boundingBoxNode->QueryFloatAttribute("minx", &min->x); boundingBoxNode->QueryFloatAttribute("miny", &min->y); boundingBoxNode->QueryFloatAttribute("minz", &min->z); boundingBoxNode->QueryFloatAttribute("maxx", &max->x); boundingBoxNode->QueryFloatAttribute("maxy", &max->y); boundingBoxNode->QueryFloatAttribute("maxz", &max->z); } // Vertices TiXmlElement * verticesNode = SubMeshNode->FirstChildElement("Vertices"); if(verticesNode) { unsigned int numVertices = 0; verticesNode->QueryUIntAttribute("num", &numVertices); MVector3 * vertices = subMesh->allocVertices(numVertices); // vertex TiXmlElement * vertexNode = verticesNode->FirstChildElement("vertex"); for(vertexNode; vertexNode; vertexNode=vertexNode->NextSiblingElement("vertex")) { vertexNode->QueryFloatAttribute("x", &vertices->x); vertexNode->QueryFloatAttribute("y", &vertices->y); vertexNode->QueryFloatAttribute("z", &vertices->z); vertices++; } } // Normals TiXmlElement * normalsNode = SubMeshNode->FirstChildElement("Normals"); if(normalsNode) { unsigned int numNormals = 0; normalsNode->QueryUIntAttribute("num", &numNormals); MVector3 * normals = subMesh->allocNormals(numNormals); // normal TiXmlElement * normalNode = normalsNode->FirstChildElement("normal"); for(normalNode; normalNode; normalNode=normalNode->NextSiblingElement("normal")) { normalNode->QueryFloatAttribute("x", &normals->x); normalNode->QueryFloatAttribute("y", &normals->y); normalNode->QueryFloatAttribute("z", &normals->z); normals->normalize(); normals++; } } // Tangents TiXmlElement * tangentsNode = SubMeshNode->FirstChildElement("Tangents"); if(tangentsNode) { unsigned int numTangents = 0; tangentsNode->QueryUIntAttribute("num", &numTangents); MVector3 * tangents = subMesh->allocTangents(numTangents); // tangent TiXmlElement * tangentNode = tangentsNode->FirstChildElement("tangent"); for(tangentNode; tangentNode; tangentNode=tangentNode->NextSiblingElement("tangent")) { tangentNode->QueryFloatAttribute("x", &tangents->x); tangentNode->QueryFloatAttribute("y", &tangents->y); tangentNode->QueryFloatAttribute("z", &tangents->z); tangents->normalize(); tangents++; } } // TexCoords TiXmlElement * texCoordsNode = SubMeshNode->FirstChildElement("TexCoords"); if(texCoordsNode) { // num unsigned int numTexCoords = 0; texCoordsNode->QueryUIntAttribute("num", &numTexCoords); MVector2 * texCoords = subMesh->allocTexCoords(numTexCoords); // mapChannels unsigned int numVertices = subMesh->getVerticesSize(); const char * mapChannelsData = texCoordsNode->Attribute("mapChannels"); // read channels if(mapChannelsData) { char str[256]; strcpy(str, mapChannelsData); char * pch; unsigned int offset = 0; pch = strtok(str, " "); while(pch != NULL) { unsigned int channel = 0; sscanf(pch, "%d", &channel); subMesh->setMapChannelOffset(channel, offset); pch = strtok(NULL, " "); offset += numVertices; } } // create default channels else if((numVertices > 0) && (numTexCoords > numVertices)) { unsigned int numChannels = numTexCoords / numVertices; for(unsigned int c=0; c<numChannels; c++) subMesh->setMapChannelOffset(c, numVertices*c); } // texCoord TiXmlElement * texCoordNode = texCoordsNode->FirstChildElement("texCoord"); for(texCoordNode; texCoordNode; texCoordNode=texCoordNode->NextSiblingElement("texCoord")) { texCoordNode->QueryFloatAttribute("x", &texCoords->x); texCoordNode->QueryFloatAttribute("y", &texCoords->y); texCoords++; } } // Colors TiXmlElement * colorsNode = SubMeshNode->FirstChildElement("Colors"); if(colorsNode) { unsigned int numColors = 0; colorsNode->QueryUIntAttribute("num", &numColors); MColor * colors = subMesh->allocColors(numColors); // color TiXmlElement * colorNode = colorsNode->FirstChildElement("color"); for(colorNode; colorNode; colorNode=colorNode->NextSiblingElement("color")) { float x = 1, y = 1, z = 1, w = 1; colorNode->QueryFloatAttribute("x", &x); colorNode->QueryFloatAttribute("y", &y); colorNode->QueryFloatAttribute("z", &z); colorNode->QueryFloatAttribute("w", &w); colors->r = (unsigned char)x*255; colors->g = (unsigned char)y*255; colors->b = (unsigned char)z*255; colors->a = (unsigned char)w*255;; colors++; } } // Indices TiXmlElement * indicesNode = SubMeshNode->FirstChildElement("Indices"); if(indicesNode) { M_TYPES indicesType; unsigned int vSize = subMesh->getVerticesSize(); if(vSize < 65536){ indicesType = M_USHORT; } else{ indicesType = M_UINT; } unsigned int numIndices = 0; indicesNode->QueryUIntAttribute("num", &numIndices); subMesh->allocIndices(numIndices, indicesType); // indices TiXmlElement * indexNode = indicesNode->FirstChildElement("index"); switch(indicesType) { case M_USHORT: { unsigned short * indices = (unsigned short *)subMesh->getIndices(); for(indexNode; indexNode; indexNode=indexNode->NextSiblingElement("index")) { unsigned int id; indexNode->QueryUIntAttribute("value", &id); *indices = (unsigned short)id; indices++; } } break; case M_UINT: { unsigned int * indices = (unsigned int *)subMesh->getIndices(); for(indexNode; indexNode; indexNode=indexNode->NextSiblingElement("index")) { indexNode->QueryUIntAttribute("value", indices); indices++; } } break; } } // Skins TiXmlElement * skinsNode = SubMeshNode->FirstChildElement("Skins"); if(skinsNode) { MSkinData * skinData = subMesh->createSkinData(); unsigned int numSkins = 0; skinsNode->QueryUIntAttribute("num", &numSkins); MSkinPoint * skinPoints = skinData->allocPoints(numSkins); // skin TiXmlElement * skinNode = skinsNode->FirstChildElement("skin"); for(skinNode; skinNode; skinNode=skinNode->NextSiblingElement("skin")) { unsigned int vertexId = 0; unsigned int numBones = 0; skinNode->QueryUIntAttribute("vertex", &vertexId); skinNode->QueryUIntAttribute("numBones", &numBones); if(numBones > 0) { skinPoints->setVertexId(vertexId); skinPoints->allocateBonesLinks(numBones); unsigned short * bonesIds = skinPoints->getBonesIds(); float * bonesWeights = skinPoints->getBonesWeights(); TiXmlElement * boneNode = skinNode->FirstChildElement("bone"); for(boneNode; boneNode; boneNode=boneNode->NextSiblingElement("bone")) { unsigned int id; boneNode->QueryUIntAttribute("id", &id); boneNode->QueryFloatAttribute("weight", bonesWeights); *bonesIds = id; bonesIds++; bonesWeights++; } } skinPoints++; } } // Displays TiXmlElement * displaysNode = SubMeshNode->FirstChildElement("Displays"); if(displaysNode) { unsigned int numDisplays = 0; displaysNode->QueryUIntAttribute("num", &numDisplays); subMesh->allocDisplays(numDisplays); // display TiXmlElement * displayNode = displaysNode->FirstChildElement("display"); for(displayNode; displayNode; displayNode=displayNode->NextSiblingElement("display")) { unsigned int begin, size, material, cullFace = 0; displayNode->QueryUIntAttribute("begin", &begin); displayNode->QueryUIntAttribute("size", &size); displayNode->QueryUIntAttribute("material", &material); displayNode->QueryUIntAttribute("cullFace", &cullFace); // create display MDisplay * display = subMesh->addNewDisplay(M_PRIMITIVE_TRIANGLES, begin, size); // set material if(material < mesh->getMaterialsNumber()) display->setMaterial(mesh->getMaterial(material)); // set cull mode M_CULL_MODES cullMode = M_CULL_BACK; if(cullFace == 1) cullMode = M_CULL_FRONT; else if(cullFace == 2) cullMode = M_CULL_NONE; display->setCullMode(cullMode); } } // generate tangents if needed if(! subMesh->getTangents()) generateTangents(subMesh); subMeshs++; } MLOG_DEBUG("xmlMeshLoad success: "<<numSubMeshs<<" submeshs found"); return true; }
void generateTangents(MSubMesh * subMesh) { MVector3 * vertices = subMesh->getVertices(); MVector3 * normals = subMesh->getNormals(); MVector2 * texCoords = subMesh->getTexCoords(); if(! (vertices && normals && texCoords)) return; bool generate = false; unsigned int mapChannel; // find normal mapChannel unsigned int d; unsigned int dSize = subMesh->getDisplaysNumber(); for(d=0; d<dSize; d++) { MDisplay * display = subMesh->getDisplay(d); MMaterial * material = display->getMaterial(); if(material) { if(material->getType() == 1) // standard { if(material->getTexturesPassNumber() > 2) { MTexturePass * texturePass = material->getTexturePass(2); // Normal map pass if(texturePass) { mapChannel = texturePass->getMapChannel(); generate = true; } } } else { unsigned tSize = material->getTexturesPassNumber(); unsigned int t; for(t=0; t<tSize; t++) { MTexturePass * texturePass = material->getTexturePass(t); if(texturePass) { if(texturePass->getCombineMode() == M_TEX_COMBINE_DOT) { mapChannel = texturePass->getMapChannel(); generate = true; } } } } } } // generate if(generate) { M_TYPES indicesType = subMesh->getIndicesType(); void * indices = subMesh->getIndices(); MVector3 * tangents = subMesh->allocTangents(subMesh->getNormalsSize()); // texCoord offset unsigned int offset = 0; if(subMesh->isMapChannelExist(mapChannel)) offset = subMesh->getMapChannelOffset(mapChannel); texCoords = texCoords + offset; // scan triangles to generate tangents from vertices and texCoords for(d=0; d<dSize; d++) { MDisplay * display = subMesh->getDisplay(d); if(display->getPrimitiveType() == M_PRIMITIVE_TRIANGLES) { unsigned int begin = display->getBegin(); unsigned int size = display->getSize(); if(! indices) { for(unsigned int i=begin; i<(begin+size); i+=3) { MVector3 * P1 = &vertices[i]; MVector3 * P2 = &vertices[i+1]; MVector3 * P3 = &vertices[i+2]; MVector3 * N1 = &normals[i]; MVector3 * N2 = &normals[i+1]; MVector3 * N3 = &normals[i+2]; MVector2 * UV1 = &texCoords[i]; MVector2 * UV2 = &texCoords[i+1]; MVector2 * UV3 = &texCoords[i+2]; MVector3 tangent = computeTangent(*P1, *P2, *P3, *UV1, *UV2, *UV3); tangents[i] = (tangent - ((*N1) * tangent.dotProduct(*N1))).getNormalized(); tangents[i+1] = (tangent - ((*N2) * tangent.dotProduct(*N2))).getNormalized(); tangents[i+2] = (tangent - ((*N3) * tangent.dotProduct(*N3))).getNormalized(); } } else if(indicesType == M_USHORT) { unsigned short * _indices = (unsigned short *)indices; for(unsigned int i=begin; i<(begin+size); i+=3) { unsigned short A = _indices[i]; unsigned short B = _indices[i+1]; unsigned short C = _indices[i+2]; MVector3 * P1 = &vertices[A]; MVector3 * P2 = &vertices[B]; MVector3 * P3 = &vertices[C]; MVector3 * N1 = &normals[A]; MVector3 * N2 = &normals[B]; MVector3 * N3 = &normals[C]; MVector2 * UV1 = &texCoords[A]; MVector2 * UV2 = &texCoords[B]; MVector2 * UV3 = &texCoords[C]; MVector3 tangent = computeTangent(*P1, *P2, *P3, *UV1, *UV2, *UV3); tangents[A] = (tangent - ((*N1) * tangent.dotProduct(*N1))).getNormalized(); tangents[B] = (tangent - ((*N2) * tangent.dotProduct(*N2))).getNormalized(); tangents[C] = (tangent - ((*N3) * tangent.dotProduct(*N3))).getNormalized(); } } else if(indicesType == M_UINT) { unsigned int * _indices = (unsigned int *)indices; for(unsigned int i=begin; i<(begin+size); i+=3) { unsigned int A = _indices[i]; unsigned int B = _indices[i+1]; unsigned int C = _indices[i+2]; MVector3 * P1 = &vertices[A]; MVector3 * P2 = &vertices[B]; MVector3 * P3 = &vertices[C]; MVector3 * N1 = &normals[A]; MVector3 * N2 = &normals[B]; MVector3 * N3 = &normals[C]; MVector2 * UV1 = &texCoords[A]; MVector2 * UV2 = &texCoords[B]; MVector2 * UV3 = &texCoords[C]; MVector3 tangent = computeTangent(*P1, *P2, *P3, *UV1, *UV2, *UV3); tangents[A] = (tangent - ((*N1) * tangent.dotProduct(*N1))).getNormalized(); tangents[B] = (tangent - ((*N2) * tangent.dotProduct(*N2))).getNormalized(); tangents[C] = (tangent - ((*N3) * tangent.dotProduct(*N3))).getNormalized(); } } } } } }
void SceneShapeUI::getDrawRequests( const MDrawInfo &info, bool objectAndActiveOnly, MDrawRequestQueue &requests ) { // it's easy if no one want to look at us if( !info.objectDisplayStatus( M3dView::kDisplayMeshes ) ) { return; } // the node we're meant to be drawing SceneShape *sceneShape = (SceneShape *)surfaceShape(); if( !sceneShape->getSceneInterface() ) { return; } // draw data encapsulating that node MDrawData drawData; getDrawData( sceneShape, drawData ); // a request for the bound if necessary MPlug pDrawBound( sceneShape->thisMObject(), SceneShape::aDrawRootBound ); bool drawBound; pDrawBound.getValue( drawBound ); if( drawBound ) { bool doDrawBound = true; // If objectOnly is true, check for an object. If none found, no need to add the bound request. MPlug pObjectOnly( sceneShape->thisMObject(), SceneShape::aObjectOnly ); bool objectOnly; pObjectOnly.getValue( objectOnly ); if( objectOnly && !sceneShape->getSceneInterface()->hasObject() ) { doDrawBound = false; } if( doDrawBound ) { MDrawRequest request = info.getPrototype( *this ); request.setDrawData( drawData ); request.setToken( BoundDrawMode ); request.setDisplayStyle( M3dView::kWireFrame ); setWireFrameColors( request, info.displayStatus() ); requests.add( request ); } } MPlug pDrawAllBounds( sceneShape->thisMObject(), SceneShape::aDrawChildBounds ); bool drawAllBounds = false; pDrawAllBounds.getValue( drawAllBounds ); // requests for the scene if necessary MPlug pGLPreview( sceneShape->thisMObject(), SceneShape::aDrawGeometry ); bool glPreview; pGLPreview.getValue( glPreview ); if( glPreview || drawAllBounds ) { if( info.displayStyle()==M3dView::kGouraudShaded || info.displayStyle()==M3dView::kFlatShaded ) { // make a request for solid drawing with a material MDrawRequest solidRequest = info.getPrototype( *this ); solidRequest.setDrawData( drawData ); MDagPath path = info.multiPath(); M3dView view = info.view(); MMaterial material = MPxSurfaceShapeUI::material( path ); if( !material.evaluateMaterial( view, path ) ) { MString pathName = path.fullPathName(); IECore::msg( IECore::Msg::Warning, "SceneShapeUI::getDrawRequests", boost::format( "Failed to evaluate material for \"%s\"." ) % pathName.asChar() ); } if( material.materialIsTextured() ) { material.evaluateTexture( drawData ); } solidRequest.setMaterial( material ); // set the transparency request. we don't have a decent way of finding out // if shaders applied by the procedural are transparent, so we've got a transparency // attribute on the procedural holder for users to use. maya materials may also say // they're transparent. if either asks for transparency then we'll ask for it here bool transparent = false; material.getHasTransparency( transparent ); solidRequest.setIsTransparent( transparent ); solidRequest.setToken( SceneDrawMode ); requests.add( solidRequest ); if( info.displayStatus()==M3dView::kActive || info.displayStatus()==M3dView::kLead || info.displayStatus()==M3dView::kHilite ) { MDrawRequest wireRequest = info.getPrototype( *this ); wireRequest.setDrawData( drawData ); wireRequest.setDisplayStyle( M3dView::kWireFrame ); wireRequest.setToken( SceneDrawMode ); setWireFrameColors( wireRequest, info.displayStatus() ); wireRequest.setComponent( MObject::kNullObj ); if ( !objectAndActiveOnly ) { if ( sceneShape->hasActiveComponents() ) { MObjectArray components = sceneShape->activeComponents(); MObject component = components[0]; wireRequest.setComponent( component ); } } requests.add( wireRequest ); } } else { MDrawRequest request = info.getPrototype( *this ); request.setDrawData( drawData ); setWireFrameColors( request, info.displayStatus() ); request.setToken( SceneDrawMode ); request.setComponent( MObject::kNullObj ); if ( !objectAndActiveOnly ) { if ( sceneShape->hasActiveComponents() ) { MObjectArray components = sceneShape->activeComponents(); MObject component = components[0]; request.setComponent( component ); } } requests.add( request ); } } }