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); }
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; }
bool Plate::IsLocalOutputMeaningful( ShadeContext& sc ) { PlateMap *pmap = FindMap( sc.NodeID() ); if ( pmap != NULL && sc.globContext == NULL ) return false; return true; }
RGBA Plate::EvalColor(ShadeContext& sc) { BMM_Color_64 c; IPoint2 s; int id = sc.NodeID(); PlateMap *pmap = FindMap(id); if (gbufID) sc.SetGBufferID(gbufID); if (pmap) { s = sc.ScreenCoord(); int w = pmap->bm->Width(); int h = pmap->bm->Height(); Point3 view = sc.OrigView(); Point3 v2 = sc.V(); Point3 p = sc.P(); Point3 dV,dvf; Point3 N0 = sc.OrigNormal(); Point3 vf = RefractVector(sc, N0, view, sc.GetIOR()); RenderGlobalContext *gc = sc.globContext; if (gc==NULL) return blackrgba; // total deflection due to refraction dV = view-v2; // deflection due to flat refracton (no bumps) dvf = view-vf; dV = refrAmt*(dV-dvf) + thick*dvf; // compute screen deflection: This is really a cheat, and the // scale factor is arbitrary. Infact it depends on the distance // between to the point on the glass plate and to the point being // seen behind it, which we don't know. // these should be multiplied by the factor (Zbehind-Zcur)/Zcur // This assumes that the factor is .1 float dsx,dsy; if (gc->projType==0) { // perspective dsx = dV.x*0.1f*gc->xscale; dsy = dV.y*0.1f*gc->yscale; } else { // parallel projection dsx = -dV.x*gc->xscale*10.0f; dsy = -dV.y*gc->yscale*10.0f; } if (gc->fieldRender) dsy *= 2.0f; int x = s.x - (pmap->org.x+gc->devWidth/2); int y = s.y - (pmap->org.y+gc->devHeight/2); if (applyBlur) { float du = 1.0f/float(w); float dv = 1.0f/float(h); float u = (float(x)+dsx)*du; float v = (float(y)+dsy)*dv; if (u<0.0f||u>1.0f||v<0.0f||v>1.0f) { if (useEnvMap) { return sc.EvalGlobalEnvironMap(view-dvf); } else return blackrgba; } else pmap->bm->GetFiltered(u,v, du*blur, dv*blur,&c); } else { int ix = x + int(dsx); int iy = y + int(dsy); if (ix<0||ix>=w||iy<0||iy>=h) { if (useEnvMap) return sc.EvalGlobalEnvironMap(view-dvf); else return blackrgba; } else pmap->bm->GetLinearPixels(ix,iy,1,&c); } return c; } else return blackrgba; }
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);}