int CrackVisualizer::BuildMaps(TimeValue t, RenderMapsContext &rmc) { //MessageBox( 0, "test", "test", MB_OK ); int nodeID = rmc.NodeRenderID(); // get the renderinstance for the current node RenderInstance* inst = rmc.GetGlobalContext()->GetRenderInstance(nodeID); if( (inst==NULL) || (inst->mesh==NULL) || (NULL == inst->mesh->faces) ) return Texmap::BuildMaps( t, rmc ); findAdjBoundaryEdges( nodeID, inst ); // done return Texmap::BuildMaps( t, rmc ); }
int Plate::BuildMaps(TimeValue t, RenderMapsContext &rmc) { SubRendParams srp; rmc.GetSubRendParams(srp); PlateMap *pmap = FindMap(rmc.NodeRenderID()); if (pmap&&!DoThisFrame(t,srp.fieldRender,pmap->mapTime)) return 1; ViewParams vp; Box2 sbox; rmc.GetCurrentViewParams(vp); rmc.FindMtlScreenBox(sbox, &vp.affineTM, rmc.SubMtlIndex()); int xmin,xmax,ymin,ymax; BOOL fieldRender = FALSE; if (srp.fieldRender) { sbox.top *= 2; sbox.bottom *= 2; fieldRender = TRUE; } // add a margin around object for refraction int ew = srp.devWidth/20; int eh = srp.devHeight/20; xmax = sbox.right+ew; xmin = sbox.left-ew; ymax = sbox.bottom+eh; ymin = sbox.top-eh; if (srp.rendType==RENDTYPE_REGION) { ymin = MAX(ymin,srp.ymin-eh); ymax = MIN(ymax,srp.ymax+eh); xmin = MAX(xmin,srp.xmin-ew); xmax = MIN(xmax,srp.xmax+ew); } srp.xmin = MAX(xmin,-ew); srp.xmax = MIN(xmax,srp.devWidth+ew); srp.ymin = MAX(ymin,-eh); srp.ymax = MIN(ymax,srp.devHeight+eh); int xorg = xmin; int yorg = ymin; int devw = srp.devWidth; int devh = srp.devHeight; // The renderer is set up to allocate A-buffer for the range // 0..devWidth-1, 0..devHeight-1. If the region of the plate // bitmap goes out of this region, it must be extended. int d1 = 0, d2 = 0; if (srp.xmin<0) d1 = -srp.xmin; if (srp.xmax>=srp.devWidth) d2 = srp.xmax-srp.devWidth+1; int d = MAX(d1,d2); if (d) { srp.devWidth += 2*d; srp.xmax += d; srp.xmin += d; // must also correct fov (or zoom) so the renderer computes the // same xscale and yscale if (vp.projType==PROJ_PERSPECTIVE) { vp.fov = 2.0f*(float)atan((float(srp.devWidth)/float(devw))*tan(0.5*vp.fov)); } else { vp.zoom *= (float(srp.devWidth)/float(devw)); } srp.blowupCenter.x += d; // DS: 11/6/00 } d1 = d2 = 0; if (srp.ymin<0) d1 = -srp.ymin; if (srp.ymax>=srp.devHeight) d2 = srp.ymax-srp.devHeight+1; d = MAX(d1,d2); if (d) { // if (fieldRender) // d = ((d+1)>>1)<<1; // make d even, so line doubling (below) works right. srp.devHeight += 2*d; srp.ymax += d; srp.ymin += d; srp.blowupCenter.y += d; // DS: 11/6/00 } srp.xorg = srp.xmin; srp.yorg = srp.ymin; srp.doEnvMap = useEnvMap; //srp.doingMirror = TRUE; // DS: 11/6/00: no longer necessary int w = srp.xmax-srp.xmin; int h = srp.ymax-srp.ymin; if (w<=0||h<=0) return 1; #ifdef DBG w = ((w+3)/4)*4; // For some reason this needs to be a multiple of 4 for bm->Display #endif if (pmap==NULL) { pmap = new PlateMap; pmap->nodeID = rmc.NodeRenderID(); pmap->next = maps; maps = pmap; } pmap->AllocMap(w, h); pmap->org.x = xorg-devw/2; pmap->org.y = yorg-devh/2; pmap->devW = devw; // TBD: This should be accessable from the SC pmap->mapTime = t; // Set up clipping planes to clip out stuff between camera and plate. Box3 b = rmc.ObjectSpaceBoundingBox(); Matrix3 tmObToWorld = rmc.ObjectToWorldTM(); Matrix3 obToCam = tmObToWorld*vp.affineTM; int nplanes=0; Point4 pl[6],pc; Point4 clip[6]; pl[0] = Point4( 1.0f, 0.0f, 0.0f, -b.pmax.x); pl[1] = Point4(-1.0f, 0.0f, 0.0f, b.pmin.x); pl[2] = Point4( 0.0f, 1.0f, 0.0f, -b.pmax.y); pl[3] = Point4( 0.0f,-1.0f, 0.0f, b.pmin.y); pl[4] = Point4( 0.0f, 0.0f, 1.0f, -b.pmax.z); pl[5] = Point4( 0.0f, 0.0f,-1.0f, b.pmin.z); if (vp.projType==PROJ_PARALLEL) { for (int i=0; i<6; i++) { pc = TransformPlane(obToCam,pl[i]); // see if camera = (0,0,0) is in front of plane if (pc.z>0.0f) clip[nplanes++] = -pc; } } else { for (int i=0; i<6; i++) { pc = TransformPlane(obToCam,pl[i]); // see if camera = (0,0,0) is in front of plane if (pc.w>0.0f) clip[nplanes++] = -pc; } } srp.fieldRender = FALSE; // assert(nplanes<4); if (!rmc.Render(pmap->bm, vp, srp, clip, nplanes)) return 0; /* if (srp.fieldRender) { // Double the lines, otherwise the blur wont work right, // because the blank lines in between get averaged in and darken it. int evenLines = srp.evenLines; if(srp.ymin&1) evenLines = !evenLines; PixelBuf l64(w); if (evenLines) { for (int i=0; i<h; i+=2) { BMM_Color_64 *p64=l64.Ptr(); if (i+1<h) { pmap->bm->GetPixels(0,i, w, p64); pmap->bm->PutPixels(0,i+1,w, p64); } } } else { for (int i=0; i<h; i+=2) { BMM_Color_64 *p64=l64.Ptr(); if (i+1<h) { pmap->bm->GetPixels(0,i+1,w, p64); pmap->bm->PutPixels(0,i ,w, p64); } } } } */ #ifdef DBG if (devw>200){ pmap->bm->UnDisplay(); TSTR buf; RenderGlobalContext *gc = rmc.GetGlobalContext(); RenderInstance* inst = gc->GetRenderInstance(rmc.NodeRenderID()); INode *node = inst->GetINode(); buf.printf(_T("Thinwall: %s"), node->GetName()); pmap->bm->Display(buf, BMM_UR); MessageBox(NULL, _T("hi"), _T(" Plate Test"), MB_OK|MB_ICONEXCLAMATION); } #endif if (applyBlur) { // I tried pyramids here, but SATs looked much better. // maybe we should give users a choice? pmap->bm->SetFilter(BMM_FILTER_SUM); // pmap->bm->SetFilter(BMM_FILTER_PYRAMID); BitmapFilter *filt = pmap->bm->Filter(); if (filt) filt->MakeDirty(); // so filter gets recomputed for each frame } else pmap->bm->SetFilter(BMM_FILTER_NONE); return 1; }