int GetMaps::proc(ReferenceMaker *rm) { if (IsTex((MtlBase*)rm)) mlib->AddMtl((MtlBase *)rm); return REF_ENUM_CONTINUE; }
//*************************************************************************** // Calculate ambient or diffuse color at each vertex. // Pass in TRUE as the "diffuse" parameter to calculate the diffuse color. // If FALSE is passed in, ambient color is calculated. //*************************************************************************** BOOL calcMixedVertexColors(INode* node, TimeValue t, int lightModel, ColorTab& vxColTab, EvalColProgressCallback* fn) { ObjectState ostate; BOOL deleteTri; Mesh* mesh; SContext sc; DefaultLight dl1, dl2; MtlBaseLib mtls; Matrix3 tm; sc.SetNodeAndTime(node, t); tm = sc.tmAfterWSM; TriObject* tri = GetTriObjectFromNode(node, t, deleteTri); // We will only work on GeomObjects if (!tri) { return FALSE; } // Get the mesh from the object mesh = &tri->GetMesh(); if (!mesh) { return FALSE; } // If the node doesn't have a material attached, // we create a dummy material. Mtl* mtl = node->GetMtl(); if (!mtl) { mtl = new DumMtl(Color(node->GetWireColor())); } mesh->buildRenderNormals(); vxColTab.ZeroCount(); vxColTab.Shrink(); sc.SetMesh(mesh); sc.CalcBoundObj(); // Add the material to the list mtls.AddMtl(mtl); // Setup ambient light if (lightModel == LIGHT_AMBIENT) { sc.SetAmbientLight(Color(1.0f, 1.0f, 1.0f)); } else { sc.SetAmbientLight(Color(0.0f, 0.0f, 0.0f)); } // If we're using the real lights, we need to find them first if (lightModel == LIGHT_SCENELIGHT) { AddSceneLights(&sc, &mtls); // Add default lights if there are no lights in the scene if (sc.lightTab.Count() == 0) { dl1.ls.intens = 1.0f; dl1.ls.color = Color(0.8f, 0.8f, 0.8f); dl1.ls.type = OMNI_LGT; dl1.tm = TransMatrix(1000.0f * Point3(-900.0f, -1000.0f, 1500.0f)); dl2.ls.intens = 1.0f; dl2.ls.color = Color(0.8f, 0.8f, 0.8f); dl2.ls.type = OMNI_LGT; dl2.tm = TransMatrix(-1000.0f * Point3(-900.0f, -1000.0f, 1500.0f)); sc.AddLight(new LightInfo(&dl1)); sc.AddLight(new LightInfo(&dl2)); } sc.SetAmbientLight(GetCOREInterface()->GetAmbient(t, FOREVER)); } sc.UpdateLights(); // Update material mtl->Update(t, FOREVER); int numVerts = mesh->numVerts; for (unsigned int v = 0; v < (unsigned)numVerts; v++) { if (fn) { if (fn->progress(float(v)/float(numVerts))) { if (deleteTri) { delete tri; } mtls.Empty(); if (mtl->ClassID() == DUMMTL_CLASS_ID) { delete mtl; } // What to return here is up for discussion. // 1) We are aborting so FALSE might be in order. // 2) We have calculated some colors. Let's use what we've got so far. return TRUE; } } // Create a new entry Color* vxCol = new Color; Point3 tmpCol(0.0f, 0.0f, 0.0f); int numShades = 0; BitArray faceList; faceList.SetSize(mesh->numFaces, 0); // Get vertex normal // We also pass in a BitArray that will be filled in with // to inform us to which faces this vertex belongs. // We could do this manually, but we need to do it to get // the vertex normal anyway so this is done to speed things // up a bit. Point3 vxNormal = interpVertexNormal(mesh, tm, v, faceList); Point3 viewDir = -vxNormal; Point3 viewPoint = tm*mesh->verts[v] + 5.0f*vxNormal; Point3 lightPos = viewPoint; Point3 viewTarget = tm*mesh->verts[v]; // We now have a viewpoint and a view target. // Now we just have to shade this point on the mesh in order // to get it's color. // Note: // Since materials are assigned on Face basis we need to render each // vertex as many times as it has connecting faces. // the colors collected are mixed to get the resulting // color at each vertex. for (int nf = 0; nf < faceList.GetSize(); nf++) { if (faceList[nf]) { // render vertex for this face. sc.SetViewPoint(viewPoint); sc.SetTargetPoint(viewTarget); sc.SetViewDir(viewDir); sc.SetFaceNum(nf); Face* f = &mesh->faces[nf]; sc.SetMtlNum(f->getMatID()); sc.CalcNormals(); // Setup the barycentric coordinate if (mesh->faces[nf].v[0] == v) sc.SetBaryCoord(Point3(1.0f, 0.0f, 0.0f)); else if (mesh->faces[nf].v[1] == v) sc.SetBaryCoord(Point3(0.0f, 1.0f, 0.0f)); else if (mesh->faces[nf].v[2] == v) sc.SetBaryCoord(Point3(0.0f, 0.0f, 1.0f)); // Use diffuse color instead of ambient // The only difference is that we create a special light // located at the viewpoint and we set the ambient light to black. if (lightModel == LIGHT_DIFFUSE) { dl1.ls.intens = 1.0f; dl1.ls.color = Color(0.8f, 0.8f, 0.8f); dl1.ls.type = OMNI_LGT; dl1.tm = TransMatrix(lightPos); sc.ClearLights(); sc.AddLight(new LightInfo(&dl1)); sc.UpdateLights(); } // Shade the vertex mtl->Shade(sc); tmpCol.x += sc.out.c.r; tmpCol.y += sc.out.c.g; tmpCol.z += sc.out.c.b; numShades++; } } // The color mixes. We just add the colors together and // then divide with as many colors as we added. if (numShades > 0) { tmpCol = tmpCol / (float)numShades; } vxCol->r = tmpCol.x; vxCol->g = tmpCol.y; vxCol->b = tmpCol.z; vxCol->ClampMinMax(); // Append the Color to the table. If the array needs // to be realloc'ed, allocate extra space for 100 points. vxColTab.Append(1, &vxCol, 100); } // Some objects gives us a temporary mesh that we need to delete afterwards. if (deleteTri) { delete tri; } mtls.Empty(); if (mtl->ClassID() == DUMMTL_CLASS_ID) { delete mtl; } return TRUE; }
void GetMaps::proc(ReferenceMaker *rm) { if (IsTex((MtlBase*)rm)) { mlib->AddMtl((MtlBase *)rm); } }