void testApp::update() { // update all nodes context.update(); depth.update(); image.update(); user.update(); if(user.getNumberOfTrackedUsers() > 0) { ofxTrackedUser* cur = user.getTrackedUser(1); if(cur != NULL) { ofxLimb& leftArm = cur->left_lower_arm; ofxLimb& rightArm = cur->right_lower_arm; XnPoint3D& leftHand = leftArm.position[1]; XnPoint3D& rightHand = rightArm.position[1]; depth.getXnDepthGenerator().ConvertProjectiveToRealWorld(1, &leftHand, &leftHand); depth.getXnDepthGenerator().ConvertProjectiveToRealWorld(1, &rightHand, &rightHand); ofVec3f leftVec(leftHand.X, leftHand.Y, leftHand.Z); ofVec3f rightVec(rightHand.X, rightHand.Y, rightHand.Z); distance = (leftVec - rightVec).length(); ofxOscMessage msg; msg.setAddress("/distance"); msg.addFloatArg(distance); osc.sendMessage(msg); } } }
void Camera::move(float forward, float right, float up, float upAngle, float leftAngle) { position += vec3(0,up,0); vec3 forwardVec( sin(horizontalAngle), 0, cos(horizontalAngle) ); vec3 rightVec( sin(horizontalAngle - 3.14f/2.0f), 0, cos(horizontalAngle - 3.14f/2.0f) ); position += forwardVec * forward; position += rightVec * right; horizontalAngle += leftAngle; verticalAngle += upAngle; updateViewMatrix(); updateProjectionMatrix(); }
/****************************************************************************** * Render the current scene * uses the global variables from the parser *****************************************************************************/ int ntlWorld::renderScene( void ) { #ifndef ELBEEM_PLUGIN char nrStr[5]; // nr conversion std::ostringstream outfn_conv(""); // converted ppm with other suffix ntlRenderGlobals *glob; // storage for global rendering parameters myTime_t timeStart,totalStart,timeEnd; // measure user running time myTime_t rendStart,rendEnd; // measure user rendering time glob = mpGlob; // deactivate for all with index!=0 if((glob_mpactive)&&(glob_mpindex>0)) return(0); /* check if picture already exists... */ if(!glob->getSingleFrameMode() ) { snprintf(nrStr, 5, "%04d", glob->getAniCount() ); if(glob_mpactive) { outfn_conv << glob->getOutFilename() <<"_"<<glob_mpindex<<"_" << nrStr << ".png"; /// DEBUG! } else { // ORG outfn_conv << glob->getOutFilename() <<"_" << nrStr << ".png"; } //if((mpGlob->getDisplayMode() == DM_RAY)&&(mpGlob->getFrameSkip())) { if(mpGlob->getFrameSkip()) { struct stat statBuf; if(stat(outfn_conv.str().c_str(),&statBuf) == 0) { errorOut("ntlWorld::renderscene Warning: file "<<outfn_conv.str()<<" already exists - skipping frame..."); glob->setAniCount( glob->getAniCount() +1 ); return(2); } } // RAY mode } else { // single frame rendering, overwrite if necessary... outfn_conv << glob->getSingleFrameFilename(); } /* start program */ timeStart = getTime(); /* build scene geometry, calls buildScene(t,false) */ glob->getRenderScene()->prepareScene(mSimulationTime); /* start program */ totalStart = getTime(); /* view parameters are currently not animated */ /* calculate rays through projection plane */ ntlVec3Gfx direction = glob->getLookat() - glob->getEye(); /* calculate width of screen using perpendicular triangle diven by * viewing direction and screen plane */ gfxReal screenWidth = norm(direction)*tan( (glob->getFovy()*0.5/180.0)*M_PI ); /* calculate vector orthogonal to up and viewing direction */ ntlVec3Gfx upVec = glob->getUpVec(); ntlVec3Gfx rightVec( cross(upVec,direction) ); normalize(rightVec); /* calculate screen plane up vector, perpendicular to viewdir and right vec */ upVec = ntlVec3Gfx( cross(rightVec,direction) ); normalize(upVec); /* check if vectors are valid */ if( (equal(upVec,ntlVec3Gfx(0.0))) || (equal(rightVec,ntlVec3Gfx(0.0))) ) { errMsg("ntlWorld::renderScene","Invalid viewpoint vectors! up="<<upVec<<" right="<<rightVec); return(1); } /* length from center to border of screen plane */ rightVec *= (screenWidth*glob->getAspect() * -1.0); upVec *= (screenWidth * -1.0); /* screen traversal variables */ ntlVec3Gfx screenPos; /* current position on virtual screen */ int Xres = glob->getResX(); /* X resolution */ int Yres = glob->getResY(); /* Y resolution */ ntlVec3Gfx rightStep = (rightVec/(Xres/2.0)); /* one step right for a pixel */ ntlVec3Gfx upStep = (upVec/(Yres/2.0)); /* one step up for a pixel */ /* anti alias init */ char showAAPic = 0; int aaDepth = glob->getAADepth(); int aaLength; if(aaDepth>=0) aaLength = (2<<aaDepth); else aaLength = 0; float aaSensRed = 0.1; float aaSensGreen = 0.1; float aaSensBlue = 0.1; int aaArrayX = aaLength*Xres+1; int aaArrayY = ( aaLength+1 ); ntlColor *aaCol = new ntlColor[ aaArrayX*aaArrayY ]; char *aaUse = new char[ aaArrayX*aaArrayY ]; /* picture storage */ int picX = Xres; int picY = Yres; if(showAAPic) { picX = Xres *aaLength+1; picY = Yres *aaLength+1; } ntlColor *finalPic = new ntlColor[picX * picY]; /* reset picture vars */ for(int j=0;j<aaArrayY;j++) { for(int i=0;i<aaArrayX;i++) { aaCol[j*aaArrayX+i] = ntlColor(0.0, 0.0, 0.0); aaUse[j*aaArrayX+i] = 0; } } for(int j=0;j<picY;j++) { for(int i=0;i<picX;i++) { finalPic[j*picX+i] = ntlColor(0.0, 0.0, 0.0); } } /* loop over all y lines in screen, from bottom to top because * ppm format wants 0,0 top left */ rendStart = getTime(); glob->setCounterShades(0); glob->setCounterSceneInter(0); for (int scanline=Yres ; scanline > 0 ; --scanline) { debugOutInter( "ntlWorld::renderScene: Line "<<scanline<< " ("<< ((Yres-scanline)*100/Yres) <<"%) ", 2, 2000 ); screenPos = glob->getLookat() + upVec*((2.0*scanline-Yres)/Yres) - rightVec; /* loop over all pixels in line */ for (int sx=0 ; sx < Xres ; ++sx) { if((sx==glob->getDebugPixelX())&&(scanline==(Yres-glob->getDebugPixelY()) )) { // DEBUG!!! glob->setDebugOut(10); } else glob->setDebugOut(0); /* compute ray from eye through current pixel into scene... */ ntlColor col; if(aaDepth<0) { ntlVec3Gfx dir(screenPos - glob->getEye()); ntlRay the_ray(glob->getEye(), getNormalized(dir), 0, 1.0, glob ); /* ...and trace it */ col = the_ray.shade(); } else { /* anti alias */ int ai,aj; /* position in grid */ int aOrg = sx*aaLength; /* grid offset x */ int currStep = aaLength; /* step size */ char colDiff = 1; /* do colors still differ too much? */ ntlColor minCol,maxCol; /* minimum and maximum Color Values */ minCol = ntlColor(1.0,1.0,1.0); maxCol = ntlColor(0.0,0.0,0.0); while((colDiff) && (currStep>0)) { colDiff = 0; for(aj = 0;aj<=aaLength;aj+= currStep) { for(ai = 0;ai<=aaLength;ai+= currStep) { /* shade pixel if not done */ if(aaUse[aj*aaArrayX +ai +aOrg] == 0) { aaUse[aj*aaArrayX +ai +aOrg] = 1; ntlVec3Gfx aaPos( screenPos + (rightStep * (ai- aaLength/2)/(gfxReal)aaLength ) + (upStep * (aj- aaLength/2)/(gfxReal)aaLength ) ); ntlVec3Gfx dir(aaPos - glob->getEye()); ntlRay the_ray(glob->getEye(), getNormalized(dir), 0, 1.0, glob ); /* ...and trace it */ ntlColor newCol= the_ray.shade(); aaCol[aj*aaArrayX +ai +aOrg]= newCol; } /* not used? */ } } /* check color differences */ for(aj = 0;aj<aaLength;aj+= currStep) { for(ai = 0;ai<aaLength;ai+= currStep) { char thisColDiff = 0; if( (fabs(aaCol[aj*aaArrayX +ai +aOrg][0] - aaCol[(aj+0)*aaArrayX +(ai+currStep) +aOrg][0])> aaSensRed ) || (fabs(aaCol[aj*aaArrayX +ai +aOrg][1] - aaCol[(aj+0)*aaArrayX +(ai+currStep) +aOrg][1])> aaSensGreen ) || (fabs(aaCol[aj*aaArrayX +ai +aOrg][2] - aaCol[(aj+0)*aaArrayX +(ai+currStep) +aOrg][2])> aaSensBlue ) ) { thisColDiff = 1; } else if( (fabs(aaCol[aj*aaArrayX +ai +aOrg][0] - aaCol[(aj+currStep)*aaArrayX +(ai+0) +aOrg][0])> aaSensRed ) || (fabs(aaCol[aj*aaArrayX +ai +aOrg][1] - aaCol[(aj+currStep)*aaArrayX +(ai+0) +aOrg][1])> aaSensGreen ) || (fabs(aaCol[aj*aaArrayX +ai +aOrg][2] - aaCol[(aj+currStep)*aaArrayX +(ai+0) +aOrg][2])> aaSensBlue ) ) { thisColDiff = 1; } else if( (fabs(aaCol[aj*aaArrayX +ai +aOrg][0] - aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg][0])> aaSensRed ) || (fabs(aaCol[aj*aaArrayX +ai +aOrg][1] - aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg][1])> aaSensGreen ) || (fabs(aaCol[aj*aaArrayX +ai +aOrg][2] - aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg][2])> aaSensBlue ) ) { thisColDiff = 1; } //colDiff =1; if(thisColDiff) { /* set diff flag */ colDiff = thisColDiff; for(int bj=aj;bj<=aj+currStep;bj++) { for(int bi=ai;bi<=ai+currStep;bi++) { if(aaUse[bj*aaArrayX +bi +aOrg]==2) { //if(showAAPic) aaUse[bj*aaArrayX +bi +aOrg] = 0; } } } } else { /* set all values */ ntlColor avgCol = ( aaCol[(aj+0 )*aaArrayX +(ai+0 ) +aOrg] + aaCol[(aj+0 )*aaArrayX +(ai+currStep) +aOrg] + aaCol[(aj+currStep)*aaArrayX +(ai+0 ) +aOrg] + aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg] ) *0.25; for(int bj=aj;bj<=aj+currStep;bj++) { for(int bi=ai;bi<=ai+currStep;bi++) { if(aaUse[bj*aaArrayX +bi +aOrg]==0) { aaCol[bj*aaArrayX +bi +aOrg] = avgCol; aaUse[bj*aaArrayX +bi +aOrg] = 2; } } } } /* smaller values set */ } } /* half step size */ currStep /= 2; } /* repeat until diff not too big */ /* get average color */ gfxReal colNum = 0.0; col = ntlColor(0.0, 0.0, 0.0); for(aj = 0;aj<=aaLength;aj++) { for(ai = 0;ai<=aaLength;ai++) { col += aaCol[aj*aaArrayX +ai +aOrg]; colNum += 1.0; } } col /= colNum; } /* mark pixels with debugging */ if( glob->getDebugOut() > 0) col = ntlColor(0,1,0); /* store pixel */ if(!showAAPic) { finalPic[(scanline-1)*picX+sx] = col; } screenPos += rightStep; } /* foreach x */ /* init aa array */ if(showAAPic) { for(int j=0;j<=aaArrayY-1;j++) { for(int i=0;i<=aaArrayX-1;i++) { if(aaUse[j*aaArrayX +i]==1) finalPic[((scanline-1)*aaLength +j)*picX+i][0] = 1.0; } } } for(int i=0;i<aaArrayX;i++) { aaCol[(aaArrayY-1)*aaArrayX+i] = aaCol[0*aaArrayX+i]; aaUse[(aaArrayY-1)*aaArrayX+i] = aaUse[0*aaArrayX+i]; } for(int j=0;j<aaArrayY-1;j++) { for(int i=0;i<aaArrayX;i++) { aaCol[j*aaArrayX+i] = ntlColor(0.0, 0.0, 0.0); aaUse[j*aaArrayX+i] = 0; } } } /* foreach y */ rendEnd = getTime(); /* write png file */ { int w = picX; int h = picY; unsigned rowbytes = w*4; unsigned char *screenbuf, **rows; screenbuf = (unsigned char*)malloc( h*rowbytes ); rows = (unsigned char**)malloc( h*sizeof(unsigned char*) ); unsigned char *filler = screenbuf; // cutoff color values 0..1 for(int j=0;j<h;j++) { for(int i=0;i<w;i++) { ntlColor col = finalPic[j*w+i]; for (unsigned int cc=0; cc<3; cc++) { if(col[cc] <= 0.0) col[cc] = 0.0; if(col[cc] >= 1.0) col[cc] = 1.0; } *filler = (unsigned char)( col[0]*255.0 ); filler++; *filler = (unsigned char)( col[1]*255.0 ); filler++; *filler = (unsigned char)( col[2]*255.0 ); filler++; *filler = (unsigned char)( 255.0 ); filler++; // alpha channel } } for(int i = 0; i < h; i++) rows[i] = &screenbuf[ (h - i - 1)*rowbytes ]; writePng(outfn_conv.str().c_str(), rows, w, h); } // next frame glob->setAniCount( glob->getAniCount() +1 ); // done timeEnd = getTime(); char resout[1024]; snprintf(resout,1024, "NTL Done %s, frame %d/%d (took %s scene, %s raytracing, %s total, %d shades, %d i.s.'s)!\n", outfn_conv.str().c_str(), (glob->getAniCount()), (glob->getAniFrames()+1), getTimeString(totalStart-timeStart).c_str(), getTimeString(rendEnd-rendStart).c_str(), getTimeString(timeEnd-timeStart).c_str(), glob->getCounterShades(), glob->getCounterSceneInter() ); debMsgStd("ntlWorld::renderScene",DM_MSG, resout, 1 ); /* clean stuff up */ delete [] aaCol; delete [] aaUse; delete [] finalPic; glob->getRenderScene()->cleanupScene(); if(mpGlob->getSingleFrameMode() ) { debMsgStd("ntlWorld::renderScene",DM_NOTIFY, "Single frame mode done...", 1 ); return 1; } #endif // ELBEEM_PLUGIN return 0; }
//----------------------------------------------------------------------------- // calculate viewing region void MapCodegenState::calc_viewingregion(pointf f[], double *minz, double *maxz) { /* calculate rays through projection plane */ ntlVec3d camera( -gCamX, -gCamY, -gCamZ ); ntlVec3d lookat( -gLookatX, -gLookatY, 0.0 ); ntlVec3d direction = lookat - camera; double fovy = 90.0; double aspect = (double)gViewSizeX/gViewSizeY; /* calculate width of screen using perpendicular triangle diven by * viewing direction and screen plane */ double screenWidth = direction.getNorm()*tan( (fovy*0.5/180.0)*M_PI ); /* calculate vector orthogonal to up and viewing direction */ ntlVec3d upVec(0.0, 1.0, 0.0); ntlVec3d rightVec( upVec.crossProd(direction) ); rightVec.normalize(); /* calculate screen plane up vector, perpendicular to viewdir and right vec */ upVec = ntlVec3d( rightVec.crossProd(direction) ); upVec.normalize(); /* check if vectors are valid FIXME what to do if not? */ if( (upVec==ntlVec3d(0.0)) || (rightVec==ntlVec3d(0.0)) ) { return; } /* length from center to border of screen plane */ rightVec *= (screenWidth*aspect * -1.0); upVec *= (screenWidth * -1.0); /* calc edges positions */ double zplane = 0.0; double maxzcnt = ABS(camera[2]-zplane); double minzcnt = maxzcnt; ntlVec3d e[4]; e[0] = direction + rightVec + upVec; e[1] = direction - rightVec + upVec; e[2] = direction + rightVec - upVec; e[3] = direction - rightVec - upVec; for(int i=0;i<4;i++) { if((zplane-e[i][2])>1.0) { // only treat negative directions e[i][0] /= (zplane-e[i][2]); e[i][1] /= (zplane-e[i][2]); } //ntlVec3d p1( camera[0] + e[i][0] * camera[2], camera[1] + e[i][1] * camera[2], 0.0 ); f[i].x = gViewRegion[i].x = camera[0] + e[i][0] * camera[2]; f[i].y = gViewRegion[i].y = camera[1] + e[i][1] * camera[2]; //double currz = ABS(e[i][2] + zplane); ntlVec3d fiVec = ntlVec3d(f[i].x,f[i].y,zplane); double currz = (fiVec-camera).getNorm(); //cout << " f"<<i<<" "<<fiVec<<" c:"<< camera <<" d:"<<(fiVec-camera)<<" curr:"<<currz<<endl; //if(i==0) { //minzcnt = currz; //maxzcnt = currz; //} else { if( minzcnt > currz) minzcnt = currz; if( maxzcnt < currz) maxzcnt = currz; //} } // save min./max. z distance *maxz = maxzcnt; *minz = minzcnt; }