//----------------------------------------------------------------------------- //! Gets called whenever a mouse button gets pressed. SLbool SLCamera::onMouseDown(const SLMouseButton button, const SLint x, const SLint y, const SLKey mod) { SLScene* s = SLScene::current; // Determine the lookAt point by ray cast eyeToPixelRay((SLfloat)(_scrW>>1), (SLfloat)(_scrH>>1), &_lookAtRay); //eyeToPixelRay(x, y, &_lookAtRay); if (s->root3D()) s->root3D()->hitRec(&_lookAtRay); // Init both position in case that the second finger came with delay _oldTouchPos1.set((SLfloat)x, (SLfloat)y); _oldTouchPos2.set((SLfloat)x, (SLfloat)y); return false; }
/*! SLCamera::onMouseWheel event handler moves camera forwards or backwards */ SLbool SLCamera::onMouseWheel(const SLint delta, const SLKey mod) { SLScene* s = SLScene::current; SLfloat sign = (SLfloat)SL_sign(delta); if (_camAnim==turntableYUp || _camAnim==turntableZUp) //.................... { if (mod==KeyNone) { // Determine the lookAt point by ray cast eyeToPixelRay((SLfloat)(_scrW>>1), (SLfloat)(_scrH>>1), &_lookAtRay); if (s->root3D()) s->root3D()->hitRec(&_lookAtRay); if (_lookAtRay.length < FLT_MAX) _lookAtRay.hitPoint = _lookAtRay.origin + _lookAtRay.dir*_lookAtRay.length; // Scale the mouse delta by the lookAt distance SLfloat lookAtDist; if (_lookAtRay.length < FLT_MAX && _lookAtRay.hitNode) lookAtDist = _lookAtRay.length; else lookAtDist = _focalDist; translate(SLVec3f(0, 0, -sign*lookAtDist*_dPos), TS_Object); _lookAtRay.length = FLT_MAX; } if (mod==KeyCtrl) { _eyeSeparation *= (1.0f + sign*0.1f); } if (mod==KeyAlt) { _fov += sign*5.0f; currentFOV = _fov; } if (mod==KeyShift) { _focalDist *= (1.0f + sign*0.05f); } return true; }
/*! SLCamera::onDoubleTouch gets called whenever two fingers touch a handheld screen. */ SLbool SLCamera::onTouch2Down(const SLint x1, const SLint y1, const SLint x2, const SLint y2) { SLScene* s = SLScene::current; SLSceneView* sv = s->activeSV(); // Determine the lookAt point by ray cast eyeToPixelRay((SLfloat)sv->scrWdiv2(), (SLfloat)sv->scrHdiv2(), &_lookAtRay); s->root3D()->hit(&_lookAtRay); _oldTouchPos1.set((SLfloat)x1, (SLfloat)y1); _oldTouchPos2.set((SLfloat)x2, (SLfloat)y2); return true; }
/*! SLCamera::onMouseWheel event handler moves camera forwards or backwards */ SLbool SLCamera::onMouseWheel(const SLint delta, const SLKey mod) { SLScene* s = SLScene::current; SLSceneView* sv = s->activeSV(); SLfloat sign = (SLfloat)SL_sign(delta); if (_camAnim==turntableYUp || _camAnim==turntableZUp) //.................... { if (mod==KeyNone) { // Determine the lookAt point by ray cast eyeToPixelRay((SLfloat)sv->scrWdiv2(), (SLfloat)sv->scrHdiv2(), &_lookAtRay); s->root3D()->hit(&_lookAtRay); if (_lookAtRay.length < FLT_MAX) _lookAtRay.hitPoint = _lookAtRay.origin + _lookAtRay.dir*_lookAtRay.length; // Scale the mouse delta by the lookAt distance SLfloat lookAtDist; if (_lookAtRay.length < FLT_MAX && _lookAtRay.hitShape) { lookAtDist = _lookAtRay.length; } else lookAtDist = _focalDist; _vm.translation(_vm.m(12),_vm.m(13),_vm.m(14) + sign*lookAtDist*_dPos); _lookAtRay.length = FLT_MAX; setWMandState(); } if (mod==KeyCtrl) { _eyeSeparation *= (1.0f + sign*0.1f); } if (mod==KeyAlt) { _fov += sign*5.0f; currentFOV = _fov; } if (mod==KeyShift) { _focalDist *= (1.0f + sign*0.05f); } return true; } else if (_camAnim==walkingYUp || _camAnim==walkingZUp) //................... { _speedLimit *= (1.0f + sign*0.1f); } return false; }
//----------------------------------------------------------------------------- //! Gets called whenever a mouse button gets pressed. SLbool SLCamera::onMouseDown(const SLMouseButton button, const SLint x, const SLint y, const SLKey mod) { SLScene* s = SLScene::current; SLSceneView* sv = s->activeSV(); // Determine the lookAt point by ray cast eyeToPixelRay((SLfloat)sv->scrWdiv2(), (SLfloat)sv->scrHdiv2(), &_lookAtRay); s->root3D()->hit(&_lookAtRay); // Init both position in case that the second finger came with delay _oldTouchPos1.set((SLfloat)x, (SLfloat)y); _oldTouchPos2.set((SLfloat)x, (SLfloat)y); return false; }
/*! Photons are scattered (or absorbed) according to surface properties. This is done by russian roulette. Photons are stored on diffuse surfaces only. */ void SLPhotonMapper::photonScatter(SLRay* photon, SLVec3f power, SLPhotonType photonType)//, SLint RGB) { SLScene* s = SLScene::current; // scene shortcut s->root3D()->hit(photon); if (photon->length < SL_FLOAT_MAX) { //photons "absorbed" by luminaire if (typeid(*photon->hitShape)==typeid(SLLightSphere) || typeid(*photon->hitShape)==typeid(SLLightRect)) return; //abort if maps are full or depth>100 if((_mapCaustic->isFull() && _mapGlobal->isFull()) || photon->depth>100) //physically plausible ;-) return; photon->normalizeNormal(); SLMaterial* mat = photon->hitMat; //store photon if diffuse surface and not from light if (photon->nodeDiffuse() && photonType!=LIGHT)//photon->type()!=PRIMARY) { if(photonType!=CAUSTIC) _mapGlobal->store(photon->hitPoint,photon->dir,power); else { _mapCaustic->store(photon->hitPoint,photon->dir,power); return; // caustic photons "die" on diffuse surfaces } } //calculate average of materials SLfloat avgDiffuse = (mat->diffuse().x+mat->diffuse().y+mat->diffuse().z)/3.0f; SLfloat avgSpecular = (mat->specular().x+mat->specular().y+mat->specular().z)/3.0f; SLfloat avgTransmission= (mat->transmission().x+mat->transmission().y+mat->transmission().z)/3.0f; SLfloat eta = _russianRandom->Random(); //Decide type of photon (Global or Caustic) if from light if (photonType == LIGHT) { if ((eta*(avgDiffuse+avgSpecular+avgTransmission))<=avgDiffuse) photonType=GLOBAL; else photonType=CAUSTIC; } //Russian Roulette if (eta <= avgDiffuse) { //scattered diffuse (cosine distribution around normal) SLRay scattered; photon->diffuseMC(&scattered); //adjust power power.x*=(mat->diffuse().x/avgDiffuse); power.y*=(mat->diffuse().y/avgDiffuse); power.z*=(mat->diffuse().z/avgDiffuse); ++SLRay::diffusePhotons; photonScatter(&scattered, power, photonType); } else if (eta <= avgDiffuse+avgSpecular) { //scatter toward perfect specular direction SLRay scattered; photon->reflect(&scattered); //scatter around perfect reflected direction only if material not perfect if(photon->hitMat->shininess() < SLMaterial::PERFECT) { //rotation matrix SLMat3f rotMat; SLVec3f rotAxis((SLVec3f(0.0,0.0,1.0) ^ scattered.dir).normalize()); SLfloat rotAngle=acos(scattered.dir.z);//z*scattered.dir() rotMat.rotation(rotAngle*180.0/SL_PI,rotAxis); photon->reflectMC(&scattered,rotMat); } //avoid scattering into surface if (scattered.dir*photon->hitNormal >= 0.0f) { //adjust power power.x*=(mat->specular().x/avgSpecular); power.y*=(mat->specular().y/avgSpecular); power.z*=(mat->specular().z/avgSpecular); ++SLRay::reflectedPhotons; photonScatter(&scattered,power,photonType); } } else if (eta <= avgDiffuse+avgSpecular+avgTransmission) //scattered refracted { //scatter toward perfect transmissive direction SLRay scattered; photon->refract(&scattered); //scatter around perfect transmissive direction only if material not perfect if(photon->hitMat->translucency() < SLMaterial::PERFECT) { //rotation matrix SLMat3f rotMat; SLVec3f rotAxis((SLVec3f(0.0,0.0,1.0) ^ scattered.dir).normalize()); SLfloat rotAngle=acos(scattered.dir.z);//z*scattered.dir() rotMat.rotation(rotAngle*180.0/SL_PI,rotAxis); photon->refractMC(&scattered,rotMat); } SLVec3f N = -photon->hitNormal; if(scattered.type==REFLECTED) N*=-1.0; //In case of total reflection invert the Normal if (scattered.dir*N >= 0.0f) { //adjust power power.x*=(mat->transmission().x/avgTransmission); power.y*=(mat->transmission().y/avgTransmission); power.z*=(mat->transmission().z/avgTransmission); if(scattered.type==TRANSMITTED) ++SLRay::refractedPhotons; else ++SLRay::tirPhotons; photonScatter(&scattered,power,photonType); } } else //absorbed [rest in peace] { } } }