void plPassMtl::GetInterpVtxValue(int channel, ShadeContext &sc, Point3 &val) { Mesh *mesh = sc.globContext->GetRenderInstance(sc.NodeID())->mesh; if (mesh != nil) { Face *maxFace = &mesh->faces[ sc.FaceNumber() ]; UVVert *map = mesh->mapVerts(channel); if (map != nil) { Point3 p0 = map[maxFace->getVert( 0 )]; Point3 p1 = map[maxFace->getVert( 1 )]; Point3 p2 = map[maxFace->getVert( 2 )]; Point3 interp = sc.BarycentricCoords(); val.x = interp.x * p0.x + interp.y * p1.x + interp.z * p2.x; val.y = interp.x * p0.y + interp.y * p1.y + interp.z * p2.y; val.z = interp.x * p0.z + interp.y * p1.z + interp.z * p2.z; return; } } // No value defined... set default. if (channel == MAP_SHADING) val.x = val.y = val.z = 0.0f; else val.x = val.y = val.z = 1.0f; }
// Seed random number generator void BerconGradient::seedRandomGen(ShadeContext& sc) { int seed = 1; if (previewMatIDMode) { seed = sc.mtlNum; } else { if (p_randMat) { seed += sc.mtlNum; } if (p_randObj) { int hand = (int)sc.Node()->GetHandle(); seed += hand*(hand*hand*15731 + 789221); } if (p_randPar) { Object *ob = sc.GetEvalObject(); if (ob && ob->IsParticleSystem()) { ParticleObject *obj = (ParticleObject*)ob; IChkMtlAPI* chkMtlAPI = static_cast<IChkMtlAPI*>(obj->GetInterface(I_NEWMTLINTERFACE)); if ((chkMtlAPI && chkMtlAPI->SupportsParticleIDbyFace())) { int id = chkMtlAPI->GetParticleFromFace(sc.FaceNumber()); seed += id*(id*id*571 + 789221); } } } if (p_randTile) { seed += (int)(sc.UVW(99).z); } } seed *= p_seed; srand(seed*(seed*seed*15731 + 789221)); }
AColor UVtex::EvalColor(ShadeContext& sc) { if (gbufID) sc.SetGBufferID(gbufID); #if MAX_RELEASE > 3100 Point3 uvw; if (uvChannel < 0) { if (sc.InMtlEditor()) { Point2 a, b; sc.ScreenUV(a, b); uvw = Point3(a.x, a.y, 0.0f); } else if (sc.globContext != NULL && sc.NodeID() >= 0) { RenderInstance* ri = sc.globContext->GetRenderInstance(sc.NodeID()); Mesh* m = ri->mesh; if (m->mapSupport(uvChannel)) { Point3 bc = sc.BarycentricCoords(); int i = sc.FaceNumber(); UVVert* v = m->mapVerts(uvChannel); TVFace* f = m->mapFaces(uvChannel); uvw = v[f[i].t[0]] * bc.x + v[f[i].t[1]] * bc.y + v[f[i].t[2]] * bc.z; } else { uvw = Point3(0.0,0.0,0.0); } } else { uvw = Point3(0.0,0.0,0.0); } } else { uvw = sc.UVW(uvChannel); } #else Point3 uvw = sc.UVW(uvChannel); #endif if (clampUVW) { uvw.x = Clamp(uvw.x); uvw.y = Clamp(uvw.y); uvw.z = Clamp(uvw.z); } else { uvw.x = mod(uvw.x, 1.0000001f); uvw.y = mod(uvw.y, 1.0000001f); uvw.z = mod(uvw.z, 1.0000001f); } return EvalUVtex(uvw); }
AColor CrackVisualizer::EvalColor(ShadeContext& sc) { if (gbufID) sc.SetGBufferID(gbufID); float dist = pblock->GetFloat( pb_spin, sc.CurTime() )*0.1f; float distSquared = dist*dist; float minDist = 9999999999999999999.0f; // we must be sure that minDist is a value greater than dist // ... //AColor edgeColor = AColor (1.0f,0.0f,0.0f,1.0f); AColor edgeColor = pblock->GetAColor( pb_color, sc.CurTime() ); edgeColor.a = 1.0f; int nodeID = sc.NodeID(); if( !sc.globContext ) return AColor (0.0f,0.0f,0.0f,0.0f); RenderInstance* inst = sc.globContext->GetRenderInstance(nodeID); if( (inst==NULL) || (inst->mesh==NULL) || NULL == inst->mesh->faces || inst->mesh->getNumFaces() <= sc.FaceNumber() ) { return AColor (0.0f,0.0f,0.0f,0.0f); } // if an entry for the current nodeID doesnt exist if( adjBoundaryEdges.find( nodeID ) == adjBoundaryEdges.end() ) // build the table findAdjBoundaryEdges( nodeID, inst ); int faceIndex = sc.FaceNumber(); Face& f = inst->mesh->faces[faceIndex]; // compute Position of p Point3 bary = sc.BarycentricCoords(); Point3 p = bary[0]*inst->mesh->getVert(f.getVert(0)) + bary[1]*inst->mesh->getVert(f.getVert(1)) + bary[2]*inst->mesh->getVert(f.getVert(2)); // p is not close to any boundary edge // check if p close to any vertex which neighbours a boundaryedge from another triangle for( int i=0; i<3; ++i ) { // if wireframe if(0) { DWORD edgeIdx = f.GetEdgeIndex( f.getVert(i), f.getVert((i+1)%3) ); // get vertex positions Point3 v0 = inst->mesh->getVert(f.getVert(i)); Point3 v1 = inst->mesh->getVert(f.getVert(i+1)%3); // compute distance p <-> edge v0, v1 //float edgeDistance = distancePointLine( p, v0, v1 ); float edgeDistance = Dist3DPtToLine( &p, &v0, &v1 ); edgeDistance = edgeDistance*edgeDistance; // if distance of p is closer then 1/10 of the distance of v2 to that edge if( edgeDistance < minDist ) minDist = edgeDistance; } // if there is any incident boundary edge to the current vertex, than we know that it is a // boundary vertex if( !adjBoundaryEdges[nodeID][f.getVert(i)].empty() ) { // current vertex is a boundary vertex // comute distance of p to that vertex float vertexDistance = (inst->mesh->getVert( f.getVert(i) ) - p).LengthSquared(); if( vertexDistance < minDist ) minDist = vertexDistance; // check all boundary edges which are adjacent to the vertex and may // come from other faces for( int j = 0; j<adjBoundaryEdges[nodeID][f.getVert(i)].size(); ++j ) { // compute distance to that edge Point3 v0 = inst->mesh->getVert( adjBoundaryEdges[nodeID][f.getVert(i)][j].first ); Point3 v1 = inst->mesh->getVert( adjBoundaryEdges[nodeID][f.getVert(i)][j].second ); // compute dotproduct Point3 vec = p - v0; Point3 direction = Normalize( v1 - v0 ); float maxLength = Length( v1 - v0 ); float dp = DotProd( vec, direction ); if( (dp<0.0f)||(dp>maxLength) ) continue; float edgeDistance = LengthSquared( vec - dp*direction ); if( edgeDistance < minDist ) minDist = edgeDistance; } } } if( minDist < distSquared ) return edgeColor; return AColor (0.0f,0.0f,0.0f,0.0f);}