sRGBAfloat cRenderWorker::LightShading(const sShaderInputData &input, cLights::sLight light, int number, sRGBAfloat *outSpecular) { sRGBAfloat shading; CVector3 d = light.position - input.point; double distance = d.Length(); //angle of incidence CVector3 lightVector = d; lightVector.Normalize(); double intensity = 100.0 * light.intensity / (distance * distance) / number; double shade = input.normal.Dot(lightVector); if (shade < 0) shade = 0; shade = shade * intensity; if (shade > 500.0) shade = 500.0; //specular CVector3 half = lightVector - input.viewVector; half.Normalize(); double shade2 = input.normal.Dot(half); if (shade2 < 0.0) shade2 = 0.0; shade2 = pow(shade2, 30.0) * 1.0; shade2 *= intensity * params->specular; if (shade2 > 15.0) shade2 = 15.0; //calculate shadow if ((shade > 0.01 || shade2 > 0.01) && params->shadow) { double light = AuxShadow(input, distance, lightVector); shade *= light; shade2 *= light; } else { if (params->shadow) { shade = 0; shade2 = 0; } } shading.R = shade * light.colour.R / 65536.0; shading.G = shade * light.colour.G / 65536.0; shading.B = shade * light.colour.B / 65536.0; outSpecular->R = shade2 * light.colour.R / 65536.0; outSpecular->G = shade2 * light.colour.G / 65536.0; outSpecular->B = shade2 * light.colour.B / 65536.0; return shading; }
double CalculateDistanceMinPlane(const sParamRender ¶ms, const cNineFractals &fractals, const CVector3 planePoint, const CVector3 direction, const CVector3 orthDirection, bool *stopRequest) { // the plane is defined by the 'planePoint' and the orthogogonal 'direction' // the method will return the minimum distance from the plane to the fractal double distStep = 0.0; CVector3 point = planePoint; const double detail = 0.5; const int transVectorAngles = 5; CVector3 rotationAxis = planePoint; rotationAxis.Normalize(); while (distStep == 0 || distStep > 0.00001) { CVector3 pointNextBest(0, 0, 0); double newDistStepMin = 0; for (int i = 0; i <= transVectorAngles; i++) { const double angle = (double(i) / transVectorAngles) * 2.0 * M_PI; CVector3 transversalVect = orthDirection; transversalVect = transversalVect.RotateAroundVectorByAngle(rotationAxis, angle); transversalVect.Normalize(); CVector3 pointNext = point + direction * distStep; if (i > 0) pointNext += transversalVect * distStep / 2.0; const sDistanceIn in(pointNext, 0, false); sDistanceOut out; const double dist = CalculateDistance(params, fractals, in, &out); const double newDistStep = dist * detail * 0.5; if (newDistStep < newDistStepMin || newDistStepMin == 0) { pointNextBest = pointNext; newDistStepMin = newDistStep; } } if (newDistStepMin > 1000) newDistStepMin = 1000; if (distStep != 0 && newDistStepMin > distStep) break; distStep = newDistStepMin; point = pointNextBest; // qDebug() << "pointNextBest" << pointNextBest.Debug(); if (point.Length() > 1000000) { WriteLog("CalculateDistanceMinPlane(): surface not found!", 1); return 0; } gApplication->processEvents(); if (*stopRequest) { return 0; } } return CVector3(point - planePoint).Dot(direction); }
CVector3 cRenderWorker::NormalMapShader(const sShaderInputData &input) { cObjectData objectData = data->objectData[input.objectId]; CVector3 texX, texY; double texturePixelSize = 1.0; CVector2<double> texPoint = TextureMapping(input.point, input.normal, objectData, input.material, &texX, &texY) + CVector2<double>(0.5, 0.5); // mipmapping - calculation of texture pixel size double delta = CalcDelta(input.point); double deltaTexX = ((TextureMapping(input.point + texX * delta, input.normal, objectData, input.material) + CVector2<double>(0.5, 0.5)) - texPoint) .Length(); double deltaTexY = ((TextureMapping(input.point + texY * delta, input.normal, objectData, input.material) + CVector2<double>(0.5, 0.5)) - texPoint) .Length(); deltaTexX = deltaTexX / fabs(input.viewVector.Dot(input.normal)); deltaTexY = deltaTexY / fabs(input.viewVector.Dot(input.normal)); texturePixelSize = 1.0 / max(deltaTexX, deltaTexY); CVector3 n = input.normal; // tangent vectors: CVector3 t = n.Cross(texX); t.Normalize(); CVector3 b = n.Cross(texY); b.Normalize(); CMatrix33 tbn(b, t, n); CVector3 tex; if (input.material->normalMapTextureFromBumpmap) { tex = input.material->normalMapTexture.NormalMapFromBumpMap( texPoint, input.material->normalMapTextureHeight, texturePixelSize); } else { tex = input.material->normalMapTexture.NormalMap( texPoint, input.material->normalMapTextureHeight, texturePixelSize); } CVector3 result = tbn * tex; result.Normalize(); return result; }
// --[ Method ]--------------------------------------------------------------- // // - Class : CMatrix // // - prototype : void RemoveScale() // // - Purpose : Removes matrix's scale values. // // ----------------------------------------------------------------------------- void CMatrix::RemoveScale() { CVector3 xAxis = XAxis(); CVector3 yAxis = YAxis(); CVector3 zAxis = ZAxis(); xAxis.Normalize(); yAxis.Normalize(); zAxis.Normalize(); SetXAxis(xAxis); SetYAxis(yAxis); SetZAxis(zAxis); }
void CBuzzControllerSpiri::SetDirection(const CVector3& c_heading) { CVector3 cDir = c_heading; if(cDir.SquareLength() > 0.01f) { cDir.Normalize(); cDir *= 0.01; } m_pcPropellers->SetRelativePosition(cDir); }
void game_physics_engine::CParticalDrag::UpdateForce( CPartical* pPartical, const real duration ) { CVector3 force = pPartical->GetVelocity(); real dragCoeff = force.Magnitude(); dragCoeff = m_k1 * dragCoeff + m_k2 * dragCoeff * dragCoeff; force.Normalize(); force *= -dragCoeff; pPartical->AddForce(force); }
void Moose::Math::CPlane::Calculate( CVector3<float> vNormal, const CVector3<float> & vPoint ) { vNormal.Normalize(); m_aValues[0] = vNormal[0]; m_aValues[1] = vNormal[1]; m_aValues[2] = vNormal[2]; m_aValues[3] = -(vNormal.Dot(vPoint)); }
sRGBAfloat cRenderWorker::MainSpecular(const sShaderInputData &input) { sRGBAfloat specular; CVector3 half = input.lightVect - input.viewVector; half.Normalize(); double shade2 = input.normal.Dot(half); if (shade2 < 0.0) shade2 = 0.0; shade2 = pow(shade2, 30.0) * 1.0; if (shade2 > 15.0) shade2 = 15.0; specular.R = shade2; specular.G = shade2; specular.B = shade2; return specular; }
void game_physics_engine::CParticalAnchoredSpring::UpdateForce( CPartical* pOther, real fDuration ) { CVector3 force; force = pOther->GetPosition(); force -= *m_pAnchor; real fMagnitude = force.Magnitude(); //that is what written on the book, but I think it is wrong. //fMagnitude = real_abs(fMagnitude - m_fRestLength); fMagnitude = m_fRestLength - fMagnitude; fMagnitude *= m_fSpringConstant; force.Normalize(); force *= -fMagnitude; pOther->AddForce(force); }
sRGBAfloat cRenderWorker::MainSpecular(const sShaderInputData &input) { sRGBAfloat specular; CVector3 half = input.lightVect - input.viewVector; half.Normalize(); double shade2 = input.normal.Dot(half); if (shade2 < 0.0) shade2 = 0.0; double diffuse = 10.0 * (1.1 - input.material->diffussionTextureIntensity * (input.texDiffuse.R + input.texDiffuse.G + input.texDiffuse.B) / 3.0); shade2 = pow(shade2, 30.0 / input.material->specularWidth / diffuse) / diffuse; if (shade2 > 15.0) shade2 = 15.0; specular.R = shade2 * input.material->specularColor.R / 65536.0 * (input.texDiffuse.R * 0.5 + 0.5); specular.G = shade2 * input.material->specularColor.G / 65536.0 * (input.texDiffuse.G * 0.5 + 0.5); specular.B = shade2 * input.material->specularColor.B / 65536.0 * (input.texDiffuse.B * 0.5 + 0.5); return specular; }
void game_physics_engine::CParticalBungee::UpdateForce( CPartical* pPartical, const real duration ) { assert(pPartical != nullptr); if (pPartical == NULL) { return; } CVector3 force = pPartical->GetPosition(); force -= m_pOther->GetPosition(); real magnitude = force.Magnitude(); if (magnitude <= m_fRestLength) { return; } magnitude -= m_fRestLength; magnitude *= m_fSpringConstant; force.Normalize(); force *= -magnitude; pPartical->AddForce(force); }
CVector3 cTexture::NormalMapFromBumpMap(CVector2<double> point, double bump, double pixelSize) const { int intX = point.x; int intY = point.y; point.x = point.x - intX; point.y = point.y - intY; if(point.x < 0.0) point.x += 1.0; if(point.y < 0.0) point.y += 1.0; double m[3][3]; for(int y = 0; y<=2; y++) { for(int x = 0; x<=2; x++) { m[x][y] = MipMap(point.x*width + x - 1.0, point.y*height + y - 1.0, pixelSize).R; } } CVector3 normal; normal.x = bump * (m[2][2]-m[0][2]+2*(m[2][1]-m[0][1])+m[2][0]-m[0][0]); normal.y = bump * (m[0][0]-m[0][2]+2*(m[1][0]-m[1][2])+m[2][0]-m[2][2]); normal.z = 1.0; normal.Normalize(); return normal; }
void Main() { glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glColor3f(1.0f, 1.0f, 1.0f); APP->Print(.7f, .9f, "FPS: %4.2f", APP->GetFPS()); APP->Print(.7f, .8f, "Cubes: %d", vCubes.size()); APP->Print(.7f, .7f, "Active: %d", i_ActiveCube); APP->Print(-1.f, .9f, "Position: %.2lf %.2lf %.2lf", g_Camera.m_vPosition.x, g_Camera.m_vPosition.y, g_Camera.m_vPosition.z); APP->Print(-1.f, .8f, "View: %.2lf %.2lf %.2lf", g_Camera.m_vView.x, g_Camera.m_vView.y, g_Camera.m_vView.z); APP->Print(-1.f, .7f, "Up: %.2lf %.2lf %.2lf", g_Camera.m_vUpVector.x, g_Camera.m_vUpVector.y, g_Camera.m_vUpVector.z); APP->Print(-1.f, .6f, "CameraRot: %.2lf", g_Camera.curRotY); if (APP->GetSet()->network) APP->Print(-1.f, .5f, "IP: %s", APP->GetSet()->ip_server); else APP->Print(-1.f, .5f, "IP: no"); glLoadIdentity(); EventKeysDown(); if (i_ActiveCube >= 0 && i_ActiveCube < (int)vCubes.size()) { if (changeActiveCube) { CVector3 vec = vCubes[i_ActiveCube]->GetCenter() - g_Camera.m_vView; float angle = vCubes[i_ActiveCube]->angleRotY - g_Camera.curRotY; if (g_Camera.curRotY > 0.0f && vCubes[i_ActiveCube]->angleRotY < 0.0f) { angle = minAbs(angle, 2.0f * Pi + vCubes[i_ActiveCube]->angleRotY - g_Camera.curRotY); } else if (g_Camera.curRotY < 0.0f && vCubes[i_ActiveCube]->angleRotY > 0.0f) { angle = minAbs(angle, -2.0f * Pi + vCubes[i_ActiveCube]->angleRotY - g_Camera.curRotY); } if (vec.Magnitude() <= 2.0f * MOVEMENT_SPEED) { if (abs(angle) <= MOVEMENT_ANGLE) { g_Camera.m_vView = vCubes[i_ActiveCube]->GetCenter(); g_Camera.RotateAroundPoint(g_Camera.m_vView, angle, 0.0f, 1.0f, 0.0f); changeActiveCube = false; } else { if (angle > 0) g_Camera.RotateAroundPoint(g_Camera.m_vView, MOVEMENT_ANGLE, 0.0f, 1.0f, 0.0f); else g_Camera.RotateAroundPoint(g_Camera.m_vView, -MOVEMENT_ANGLE, 0.0f, 1.0f, 0.0f); } } else { float k = vec.Magnitude() / (2.0f * MOVEMENT_SPEED); if (k > 0.1f) g_Camera.RotateAroundPoint(g_Camera.m_vView, angle / k, 0.0f, 1.0f, 0.0f); vec.Normalize(); vec *= 2.0f * MOVEMENT_SPEED; g_Camera.m_vView += vec; g_Camera.m_vPosition += vec; } } else { g_Camera.SetViewByMouse(); vCubes[i_ActiveCube]->Set(g_Camera.m_vView.x, 0.0f, g_Camera.m_vView.z); vCubes[i_ActiveCube]->angleRotY = g_Camera.curRotY; } } gluLookAt(g_Camera.m_vPosition.x, g_Camera.m_vPosition.y, g_Camera.m_vPosition.z, g_Camera.m_vView.x, g_Camera.m_vView.y, g_Camera.m_vView.z, g_Camera.m_vUpVector.x, g_Camera.m_vUpVector.y, g_Camera.m_vUpVector.z); for (size_t i = 0; i < vCubes.size(); i++) { vCubes[i]->Render(); } }
sRGBAfloat cRenderWorker::VolumetricShader( const sShaderInputData &input, sRGBAfloat oldPixel, sRGBAfloat *opacityOut) { sRGBAfloat output; float totalOpacity = 0.0; output.R = oldPixel.R; output.G = oldPixel.G; output.B = oldPixel.B; output.A = oldPixel.A; // volumetric fog init double colourThresh = params->volFogColour1Distance; double colourThresh2 = params->volFogColour2Distance; double fogReduce = params->volFogDistanceFactor; double fogIntensity = params->volFogDensity; // visible lights init int numberOfLights = data->lights.GetNumberOfLights(); if (numberOfLights < 4) numberOfLights = 4; // glow init double glow = input.stepCount * params->glowIntensity / 512.0 * params->DEFactor; double glowN = 1.0 - glow; if (glowN < 0.0) glowN = 0.0; double glowR = (params->glowColor1.R * glowN + params->glowColor2.R * glow) / 65536.0; double glowG = (params->glowColor1.G * glowN + params->glowColor2.G * glow) / 65536.0; double glowB = (params->glowColor1.B * glowN + params->glowColor2.B * glow) / 65536.0; double totalStep = 0.0; // qDebug() << "Start volumetric shader &&&&&&&&&&&&&&&&&&&&"; sShaderInputData input2 = input; for (int index = input.stepCount - 1; index > 0; index--) { double step = input.stepBuff[index].step; double distance = input.stepBuff[index].distance; CVector3 point = input.stepBuff[index].point; totalStep += step; input2.point = point; input2.distThresh = input.stepBuff[index].distThresh; // qDebug() << "i" << index << "dist" << distance << "iters" << input.stepBuff[index].iters << // "distThresh" << input2.distThresh << "step" << step << "point" << point.Debug(); if (totalStep < CalcDelta(point)) { continue; } step = totalStep; totalStep = 0.0; //------------------- glow if (params->glowEnabled) { double glowOpacity = glow / input.stepCount; if (glowOpacity > 1.0) glowOpacity = 1.0; output.R = glowOpacity * glowR + (1.0 - glowOpacity) * output.R; output.G = glowOpacity * glowG + (1.0 - glowOpacity) * output.G; output.B = glowOpacity * glowB + (1.0 - glowOpacity) * output.B; output.A += glowOpacity; } // qDebug() << "step" << step; //------------------ visible light if (params->auxLightVisibility > 0) { double miniStep = 0.0; double lastMiniSteps = -1.0; for (double miniSteps = 0.0; miniSteps < step; miniSteps += miniStep) { double lowestLightSize = 1e10; double lowestLightDist = 1e10; for (int i = 0; i < numberOfLights; ++i) { const cLights::sLight *light = data->lights.GetLight(i); if (light->enabled) { CVector3 lightDistVect = (point - input.viewVector * miniSteps) - light->position; double lightDist = lightDistVect.Length(); double lightSize = sqrt(light->intensity) * params->auxLightVisibilitySize; double distToLightSurface = lightDist - lightSize; if (distToLightSurface < 0.0) distToLightSurface = 0.0; if (distToLightSurface <= lowestLightDist) { if (lightSize < lowestLightSize) { lowestLightSize = lightSize; } lowestLightDist = distToLightSurface; } } } miniStep = 0.1 * (lowestLightDist + 0.1 * lowestLightSize); if (miniStep > step - miniSteps) miniStep = step - miniSteps; // qDebug() << "lowDist:" << lowestLightDist << "lowSize" << lowestLightSize << "miniStep" // << miniStep; for (int i = 0; i < numberOfLights; ++i) { const cLights::sLight *light = data->lights.GetLight(i); if (light->enabled) { CVector3 lightDistVect = (point - input.viewVector * miniSteps) - light->position; double lightDist = lightDistVect.Length(); double lightSize = sqrt(light->intensity) * params->auxLightVisibilitySize; double r2 = lightDist / lightSize; double bellFunction = 1.0 / (1.0 + pow(r2, 4.0)); double lightDensity = miniStep * bellFunction * params->auxLightVisibility / lightSize; output.R += lightDensity * light->colour.R / 65536.0; output.G += lightDensity * light->colour.G / 65536.0; output.B += lightDensity * light->colour.B / 65536.0; output.A += lightDensity; } } if (miniSteps == lastMiniSteps) { // qWarning() << "Dead computation\n" // << "\npoint:" << (point - input.viewVector * miniSteps).Debug(); break; } lastMiniSteps = miniSteps; } } // fake lights (orbit trap) if (params->fakeLightsEnabled) { sFractalIn fractIn(point, params->minN, params->N, params->common, -1); sFractalOut fractOut; Compute<fractal::calcModeOrbitTrap>(*fractal, fractIn, &fractOut); double r = fractOut.orbitTrapR; r = sqrt(1.0f / (r + 1.0e-30f)); double fakeLight = 1.0 / (pow(r, 10.0 / params->fakeLightsVisibilitySize) * pow(10.0, 10.0 / params->fakeLightsVisibilitySize) + 1e-100); output.R += fakeLight * step * params->fakeLightsVisibility; output.G += fakeLight * step * params->fakeLightsVisibility; output.B += fakeLight * step * params->fakeLightsVisibility; output.A += fakeLight * step * params->fakeLightsVisibility; } //---------------------- volumetric lights with shadows in fog for (int i = 0; i < 5; i++) { if (i == 0 && params->volumetricLightEnabled[0]) { sRGBAfloat shadowOutputTemp = MainShadow(input2); output.R += shadowOutputTemp.R * step * params->volumetricLightIntensity[0] * params->mainLightColour.R / 65536.0; output.G += shadowOutputTemp.G * step * params->volumetricLightIntensity[0] * params->mainLightColour.G / 65536.0; output.B += shadowOutputTemp.B * step * params->volumetricLightIntensity[0] * params->mainLightColour.B / 65536.0; output.A += (shadowOutputTemp.R + shadowOutputTemp.G + shadowOutputTemp.B) / 3.0 * step * params->volumetricLightIntensity[0]; } if (i > 0) { const cLights::sLight *light = data->lights.GetLight(i - 1); if (light->enabled && params->volumetricLightEnabled[i]) { CVector3 lightVectorTemp = light->position - point; double distanceLight = lightVectorTemp.Length(); double distanceLight2 = distanceLight * distanceLight; lightVectorTemp.Normalize(); double lightShadow = AuxShadow(input2, distanceLight, lightVectorTemp); output.R += lightShadow * light->colour.R / 65536.0 * params->volumetricLightIntensity[i] * step / distanceLight2; output.G += lightShadow * light->colour.G / 65536.0 * params->volumetricLightIntensity[i] * step / distanceLight2; output.B += lightShadow * light->colour.B / 65536.0 * params->volumetricLightIntensity[i] * step / distanceLight2; output.A += lightShadow * params->volumetricLightIntensity[i] * step / distanceLight2; } } } //----------------------- basic fog if (params->fogEnabled) { double fogDensity = step / params->fogVisibility; if (fogDensity > 1.0) fogDensity = 1.0; output.R = fogDensity * params->fogColor.R / 65536.0 + (1.0 - fogDensity) * output.R; output.G = fogDensity * params->fogColor.G / 65536.0 + (1.0 - fogDensity) * output.G; output.B = fogDensity * params->fogColor.B / 65536.0 + (1.0 - fogDensity) * output.B; totalOpacity = fogDensity + (1.0 - fogDensity) * totalOpacity; output.A = fogDensity + (1.0 - fogDensity) * output.A; } //-------------------- volumetric fog if (fogIntensity > 0.0 && params->volFogEnabled) { double densityTemp = (step * fogReduce) / (distance * distance + fogReduce * fogReduce); double k = distance / colourThresh; if (k > 1) k = 1.0; double kn = 1.0 - k; double fogRtemp = (params->volFogColour1.R * kn + params->volFogColour2.R * k); double fogGtemp = (params->volFogColour1.G * kn + params->volFogColour2.G * k); double fogBtemp = (params->volFogColour1.B * kn + params->volFogColour2.B * k); double k2 = distance / colourThresh2 * k; if (k2 > 1) k2 = 1.0; kn = 1.0 - k2; fogRtemp = (fogRtemp * kn + params->volFogColour3.R * k2); fogGtemp = (fogGtemp * kn + params->volFogColour3.G * k2); fogBtemp = (fogBtemp * kn + params->volFogColour3.B * k2); double fogDensity = 0.3 * fogIntensity * densityTemp / (1.0 + fogIntensity * densityTemp); if (fogDensity > 1) fogDensity = 1.0; output.R = fogDensity * fogRtemp / 65536.0 + (1.0 - fogDensity) * output.R; output.G = fogDensity * fogGtemp / 65536.0 + (1.0 - fogDensity) * output.G; output.B = fogDensity * fogBtemp / 65536.0 + (1.0 - fogDensity) * output.B; // qDebug() << "densityTemp " << densityTemp << "k" << k << "k2" << k2 << "fogTempR" << // fogRtemp << "fogDensity" << fogDensity << "output.R" << output.R; totalOpacity = fogDensity + (1.0 - fogDensity) * totalOpacity; output.A = fogDensity + (1.0 - fogDensity) * output.A; } // iter fog if (params->iterFogEnabled) { int L = input.stepBuff[index].iters; double opacity = IterOpacity(step, L, params->N, params->iterFogOpacityTrim, params->iterFogOpacity); sRGBAfloat newColour(0.0, 0.0, 0.0, 0.0); if (opacity > 0) { // fog colour double iterFactor1 = (L - params->iterFogOpacityTrim) / (params->iterFogColor1Maxiter - params->iterFogOpacityTrim); double k = iterFactor1; if (k > 1.0) k = 1.0; if (k < 0.0) k = 0.0; double kn = 1.0 - k; double fogColR = (params->iterFogColour1.R * kn + params->iterFogColour2.R * k); double fogColG = (params->iterFogColour1.G * kn + params->iterFogColour2.G * k); double fogColB = (params->iterFogColour1.B * kn + params->iterFogColour2.B * k); double iterFactor2 = (L - params->iterFogColor1Maxiter) / (params->iterFogColor2Maxiter - params->iterFogColor1Maxiter); double k2 = iterFactor2; if (k2 < 0.0) k2 = 0.0; if (k2 > 1.0) k2 = 1.0; kn = 1.0 - k2; fogColR = (fogColR * kn + params->iterFogColour3.R * k2); fogColG = (fogColG * kn + params->iterFogColour3.G * k2); fogColB = (fogColB * kn + params->iterFogColour3.B * k2); //---- for (int i = 0; i < 5; i++) { if (i == 0) { if (params->mainLightEnable && params->mainLightIntensity > 0.0) { sRGBAfloat shadowOutputTemp = MainShadow(input2); newColour.R += shadowOutputTemp.R * params->mainLightColour.R / 65536.0 * params->mainLightIntensity; newColour.G += shadowOutputTemp.G * params->mainLightColour.G / 65536.0 * params->mainLightIntensity; newColour.B += shadowOutputTemp.B * params->mainLightColour.B / 65536.0 * params->mainLightIntensity; } } if (i > 0) { const cLights::sLight *light = data->lights.GetLight(i - 1); if (light->enabled) { CVector3 lightVectorTemp = light->position - point; double distanceLight = lightVectorTemp.Length(); double distanceLight2 = distanceLight * distanceLight; lightVectorTemp.Normalize(); double lightShadow = AuxShadow(input2, distanceLight, lightVectorTemp); double intensity = light->intensity * 100.0; newColour.R += lightShadow * light->colour.R / 65536.0 / distanceLight2 * intensity; newColour.G += lightShadow * light->colour.G / 65536.0 / distanceLight2 * intensity; newColour.B += lightShadow * light->colour.B / 65536.0 / distanceLight2 * intensity; } } } if (params->ambientOcclusionEnabled && params->ambientOcclusionMode == params::AOmodeMultipeRays) { sRGBAfloat AO = AmbientOcclusion(input2); newColour.R += AO.R * params->ambientOcclusion; newColour.G += AO.G * params->ambientOcclusion; newColour.B += AO.B * params->ambientOcclusion; } if (opacity > 1.0) opacity = 1.0; output.R = output.R * (1.0 - opacity) + newColour.R * opacity * fogColR / 65536.0; output.G = output.G * (1.0 - opacity) + newColour.G * opacity * fogColG / 65536.0; output.B = output.B * (1.0 - opacity) + newColour.B * opacity * fogColB / 65536.0; totalOpacity = opacity + (1.0 - opacity) * totalOpacity; output.A = opacity + (1.0 - opacity) * output.A; } } if (totalOpacity > 1.0) totalOpacity = 1.0; if (output.A > 1.0) output.A = 1.0; (*opacityOut).R = totalOpacity; (*opacityOut).G = totalOpacity; (*opacityOut).B = totalOpacity; } // next stepCount return output; }
sRGBAfloat cRenderWorker::BackgroundShader(const sShaderInputData &input) { sRGBAfloat pixel2; if (params->texturedBackground) { switch (params->texturedBackgroundMapType) { case params::mapDoubleHemisphere: { double alphaTexture = input.viewVector.GetAlpha(); double betaTexture = input.viewVector.GetBeta(); int texWidth = data->textures.backgroundTexture.Width() * 0.5; int texHeight = data->textures.backgroundTexture.Height(); int offset = 0; if (betaTexture < 0) { betaTexture = -betaTexture; alphaTexture = M_PI - alphaTexture; offset = texWidth; } double texX = 0.5 * texWidth + cos(alphaTexture) * (1.0 - betaTexture / (0.5 * M_PI)) * texWidth * 0.5 + offset; double texY = 0.5 * texHeight + sin(alphaTexture) * (1.0 - betaTexture / (0.5 * M_PI)) * texHeight * 0.5; sRGBfloat pixel = data->textures.backgroundTexture.Pixel(texX, texY); pixel2.R = pixel.R; pixel2.G = pixel.G; pixel2.B = pixel.B; break; } case params::mapEquirectangular: { double alphaTexture = fmod(-input.viewVector.GetAlpha() + 3.5 * M_PI, 2 * M_PI); double betaTexture = -input.viewVector.GetBeta(); if (betaTexture > 0.5 * M_PI) betaTexture = 0.5 * M_PI - betaTexture; if (betaTexture < -0.5 * M_PI) betaTexture = -0.5 * M_PI + betaTexture; double texX = alphaTexture / (2.0 * M_PI) * data->textures.backgroundTexture.Width(); double texY = (betaTexture / (M_PI) + 0.5) * data->textures.backgroundTexture.Height(); sRGBfloat pixel = data->textures.backgroundTexture.Pixel(texX, texY); pixel2.R = pixel.R; pixel2.G = pixel.G; pixel2.B = pixel.B; break; } case params::mapFlat: { CVector3 vect = mRotInv.RotateVector(input.viewVector); double texX = vect.x / vect.y / params->fov * params->imageHeight / params->imageWidth; double texY = -vect.z / vect.y / params->fov; texX = (texX + 0.5); texY = (texY + 0.5); sRGBfloat pixel = data->textures.backgroundTexture.Pixel(CVector2<double>(texX, texY)); pixel2.R = pixel.R; pixel2.G = pixel.G; pixel2.B = pixel.B; break; } } pixel2.R *= params->background_brightness; pixel2.G *= params->background_brightness; pixel2.B *= params->background_brightness; } else { CVector3 vector(0.0, 0.0, 1.0); vector.Normalize(); CVector3 viewVectorNorm = input.viewVector; viewVectorNorm.Normalize(); double grad = (viewVectorNorm.Dot(vector) + 1.0); sRGB16 pixel; if (grad < 1) { double Ngrad = 1.0 - grad; pixel.R = (params->background_color3.R * Ngrad + params->background_color2.R * grad); pixel.G = (params->background_color3.G * Ngrad + params->background_color2.G * grad); pixel.B = (params->background_color3.B * Ngrad + params->background_color2.B * grad); } else { grad = grad - 1; double Ngrad = 1.0 - grad; pixel.R = (params->background_color2.R * Ngrad + params->background_color1.R * grad); pixel.G = (params->background_color2.G * Ngrad + params->background_color1.G * grad); pixel.B = (params->background_color2.B * Ngrad + params->background_color1.B * grad); } pixel2.R = pixel.R / 65536.0; pixel2.G = pixel.G / 65536.0; pixel2.B = pixel.B / 65536.0; pixel2.A = 0.0; } CVector3 viewVectorNorm = input.viewVector; viewVectorNorm.Normalize(); double light = (viewVectorNorm.Dot(input.lightVect) - 1.0) * 360.0 / params->mainLightVisibilitySize; light = 1.0 / (1.0 + pow(light, 6.0)) * params->mainLightVisibility * params->mainLightIntensity; pixel2.R += light * params->mainLightColour.R / 65536.0; pixel2.G += light * params->mainLightColour.G / 65536.0; pixel2.B += light * params->mainLightColour.B / 65536.0; return pixel2; }
CVector2<double> TextureMapping(CVector3 inPoint, CVector3 normalVector, const cObjectData &objectData, const cMaterial *material, CVector3 *textureVectorX, CVector3 *textureVectorY) { CVector2<double> textureCoordinates; CVector3 point = inPoint - objectData.position; point = objectData.rotationMatrix.RotateVector(point); point /= objectData.size; point = material->rotMatrix.RotateVector(point); switch (material->textureMappingType) { case cMaterial::mappingPlanar: { textureCoordinates = CVector2<double>(point.x, point.y); textureCoordinates.x /= -material->textureScale.x; textureCoordinates.y /= material->textureScale.y; textureCoordinates.x -= material->textureCenter.x; textureCoordinates.y -= material->textureCenter.y; if (textureVectorX && textureVectorY) { CVector3 texX(1.0, 0.0, 0.0); texX = objectData.rotationMatrix.Transpose().RotateVector(texX); texX = material->rotMatrix.Transpose().RotateVector(texX); *textureVectorX = texX; CVector3 texY(0.0, -1.0, 0.0); texY = objectData.rotationMatrix.Transpose().RotateVector(texY); texY = material->rotMatrix.Transpose().RotateVector(texY); *textureVectorY = texY; } break; } case cMaterial::mappingCylindrical: { double alphaTexture = fmod(point.GetAlpha() + 2.0 * M_PI, 2.0 * M_PI); textureCoordinates.x = alphaTexture / (2.0 * M_PI); textureCoordinates.y = -point.z; textureCoordinates.x /= material->textureScale.x; textureCoordinates.y /= material->textureScale.y; textureCoordinates.x -= material->textureCenter.x; textureCoordinates.y -= material->textureCenter.y; if (textureVectorX && textureVectorY) { CVector3 texY(0.0, 0.0, 1.0); CVector3 texX = point.Cross(texY); texX = objectData.rotationMatrix.Transpose().RotateVector(texX); texX = material->rotMatrix.Transpose().RotateVector(texX); *textureVectorX = texX; texY = objectData.rotationMatrix.Transpose().RotateVector(texY); texY = material->rotMatrix.Transpose().RotateVector(texY); *textureVectorY = texY; } break; } case cMaterial::mappingSpherical: { double alphaTexture = fmod(point.GetAlpha() + 2.0 * M_PI, 2.0 * M_PI); double betaTexture = -point.GetBeta(); textureCoordinates.x = alphaTexture / (2.0 * M_PI); textureCoordinates.y = (betaTexture / M_PI); textureCoordinates.x /= material->textureScale.x; textureCoordinates.y /= material->textureScale.y; textureCoordinates.x -= material->textureCenter.x; textureCoordinates.y -= material->textureCenter.y; CVector3 texY(0.0, 0.0, -1.0); CVector3 texX = texY.Cross(point); texX.Normalize(); texY = texX.Cross(point); if (textureVectorX && textureVectorY) { texX = objectData.rotationMatrix.Transpose().RotateVector(texX); texX = material->rotMatrix.Transpose().RotateVector(texX); *textureVectorX = texX; texY = objectData.rotationMatrix.Transpose().RotateVector(texY); texY = material->rotMatrix.Transpose().RotateVector(texY); *textureVectorY = texY; } break; } case cMaterial::mappingCubic: { point /= material->textureScale; point -= material->textureCenter; CVector3 texX, texY; if (fabs(normalVector.x) > fabs(normalVector.y)) { if (fabs(normalVector.x) > fabs(normalVector.z)) { // x if (normalVector.x > 0) textureCoordinates = CVector2<double>(point.y, -point.z); else textureCoordinates = CVector2<double>(-point.y, -point.z); if (textureVectorX && textureVectorY) { if (normalVector.x > 0) { texX = CVector3(0.0, -1.0, 0.0); texY = CVector3(0.0, 0.0, 1.0); } else { texX = CVector3(0.0, 1.0, 0.0); texY = CVector3(0.0, 0.0, 1.0); } } } else { // z if (normalVector.z > 0) textureCoordinates = CVector2<double>(-point.x, point.y); else textureCoordinates = CVector2<double>(point.x, point.y); if (textureVectorX && textureVectorY) { if (normalVector.z > 0) { texX = CVector3(1.0, 0.0, 0.0); texY = CVector3(0.0, -1.0, 0.0); } else { texX = CVector3(-1.0, 0.0, 0.0); texY = CVector3(0.0, -1.0, 0.0); } } } } else { if (fabs(normalVector.y) > fabs(normalVector.z)) { // y if (normalVector.y > 0) textureCoordinates = CVector2<double>(-point.x, -point.z); else textureCoordinates = CVector2<double>(point.x, -point.z); if (textureVectorX && textureVectorY) { if (normalVector.y > 0) { texX = CVector3(1.0, 0.0, 0.0); texY = CVector3(0.0, 0.0, 1.0); } else { texX = CVector3(-1.0, 0.0, 0.0); texY = CVector3(0.0, 0.0, 1.0); } } } else { // z if (normalVector.z > 0) textureCoordinates = CVector2<double>(-point.x, point.y); else textureCoordinates = CVector2<double>(point.x, point.y); if (textureVectorX && textureVectorY) { if (normalVector.z > 0) { texX = CVector3(1.0, 0.0, 0.0); texY = CVector3(0.0, -1.0, 0.0); } else { texX = CVector3(-1.0, 0.0, 0.0); texY = CVector3(0.0, -1.0, 0.0); } } } } if (textureVectorX && textureVectorY) { texX = objectData.rotationMatrix.Transpose().RotateVector(texX); texX = material->rotMatrix.Transpose().RotateVector(texX); *textureVectorX = texX; texY = objectData.rotationMatrix.Transpose().RotateVector(texY); texY = material->rotMatrix.Transpose().RotateVector(texY); *textureVectorY = texY; } break; } } return textureCoordinates; }
// will be done later sRGBAfloat cRenderWorker::FakeLights(const sShaderInputData &input, sRGBAfloat *fakeSpec) { sRGBAfloat fakeLights; double delta = input.distThresh * params->smoothness; sFractalIn fractIn(input.point, params->minN, params->N, params->common, -1); sFractalOut fractOut; Compute<fractal::calcModeOrbitTrap>(*fractal, fractIn, &fractOut); double rr = fractOut.orbitTrapR; double fakeLight = params->fakeLightsIntensity / rr; double r = 1.0 / (rr + 1e-30); CVector3 deltax(delta, 0.0, 0.0); CVector3 deltay(0.0, delta, 0.0); CVector3 deltaz(0.0, 0.0, delta); fractIn.point = input.point + deltax; Compute<fractal::calcModeOrbitTrap>(*fractal, fractIn, &fractOut); double rx = 1.0 / (fractOut.orbitTrapR + 1e-30); fractIn.point = input.point + deltay; Compute<fractal::calcModeOrbitTrap>(*fractal, fractIn, &fractOut); double ry = 1.0 / (fractOut.orbitTrapR + 1e-30); fractIn.point = input.point + deltaz; Compute<fractal::calcModeOrbitTrap>(*fractal, fractIn, &fractOut); double rz = 1.0 / (fractOut.orbitTrapR + 1e-30); CVector3 fakeLightNormal; fakeLightNormal.x = r - rx; fakeLightNormal.y = r - ry; fakeLightNormal.z = r - rz; if (fakeLightNormal.x == 0 && fakeLightNormal.y == 0 && fakeLightNormal.z == 0) { fakeLightNormal.x = 0.0; } else { fakeLightNormal.Normalize(); } double fakeLight2 = fakeLight * input.normal.Dot(fakeLightNormal); if (fakeLight2 < 0) fakeLight2 = 0; fakeLights.R = fakeLight2; fakeLights.G = fakeLight2; fakeLights.B = fakeLight2; CVector3 half = fakeLightNormal - input.viewVector; half.Normalize(); double fakeSpecular = input.normal.Dot(half); if (fakeSpecular < 0.0) fakeSpecular = 0.0; double diffuse = 10.0 * (1.1 - input.material->diffussionTextureIntensity * (input.texDiffuse.R + input.texDiffuse.G + input.texDiffuse.B) / 3.0); fakeSpecular = pow(fakeSpecular, 30.0 / input.material->specularWidth / diffuse) / diffuse; if (fakeSpecular > 15.0) fakeSpecular = 15.0; fakeSpec->R = fakeSpecular; fakeSpec->G = fakeSpecular; fakeSpec->B = fakeSpecular; *fakeSpec = sRGBAfloat(); return fakeLights; }
sRGBAfloat cRenderWorker::LightShading( const sShaderInputData &input, const cLights::sLight *light, int number, sRGBAfloat *outSpecular) { sRGBAfloat shading; CVector3 d = light->position - input.point; double distance = d.Length(); // angle of incidence CVector3 lightVector = d; lightVector.Normalize(); double intensity = 100.0 * light->intensity / (distance * distance) / number; double shade = input.normal.Dot(lightVector); if (shade < 0) shade = 0; shade = (1.0 - input.material->shading) + shade * input.material->shading; shade = shade * intensity; if (shade > 500.0) shade = 500.0; // specular CVector3 half = lightVector - input.viewVector; half.Normalize(); double shade2 = input.normal.Dot(half); if (shade2 < 0.0) shade2 = 0.0; double diffuse = 10.0 * (1.1 - input.material->diffussionTextureIntensity * (input.texDiffuse.R + input.texDiffuse.G + input.texDiffuse.B) / 3.0); shade2 = pow(shade2, 30.0 / input.material->specularWidth / diffuse) / diffuse; shade2 *= intensity * input.material->specular; if (shade2 > 15.0) shade2 = 15.0; // calculate shadow if ((shade > 0.01 || shade2 > 0.01) && params->shadow) { double auxShadow = AuxShadow(input, distance, lightVector); shade *= auxShadow; shade2 *= auxShadow; } else { if (params->shadow) { shade = 0; shade2 = 0; } } shading.R = shade * light->colour.R / 65536.0; shading.G = shade * light->colour.G / 65536.0; shading.B = shade * light->colour.B / 65536.0; outSpecular->R = shade2 * light->colour.R / 65536.0; outSpecular->G = shade2 * light->colour.G / 65536.0; outSpecular->B = shade2 * light->colour.B / 65536.0; return shading; }
/*! * @brief 衝突検出と解決。 *@param[in] nextPosition 次の座標。 */ void EnemyTest::CollisionDetectAndResolve(CVector3 nextPosition) { //XZ平面を調べる。 { int loopCount = 0; while (true) { CVector3 addPos; addPos.Subtract(nextPosition, position); CVector3 posTmp = position; posTmp.y += radius + 0.2f; btTransform start, end; start.setIdentity(); end.setIdentity(); start.setOrigin(*(btVector3*)(&posTmp)); CVector3 newPos; SweepResultWall callback; callback.startPos = position; CVector3 addPosXZ = addPos; addPosXZ.y = 0.0f; if (addPosXZ.Length() > 0.0001f) { newPos.Add(posTmp, addPosXZ); end.setOrigin(btVector3(newPos.x, newPos.y, newPos.z)); PhysicsWorld().ConvexSweepTest((const btConvexShape*)collider.GetBody(), start, end, callback); } if (callback.isHit) { //当たった。 float t = fabsf(acosf(callback.hitNormal.Dot(CVector3::Up))); if (t >= CMath::PI * 0.3f) { //壁。 nextPosition.x = callback.hitPos.x; nextPosition.z = callback.hitPos.z; //半径分押し戻す。 CVector3 hitNormalXZ = callback.hitNormal; hitNormalXZ.y = 0.0f; hitNormalXZ.Normalize(); CVector3 t = hitNormalXZ; t.Scale(radius); nextPosition.Add(t); //続いて壁に沿って滑らせる。 t.Cross(hitNormalXZ, CVector3::Up); t.Normalize(); //押し戻しで動いた分は減算する。 CVector3 t2; t2.Subtract(nextPosition, position); t2.y = 0.0f; addPosXZ.Subtract(t2); t.Scale(t.Dot(addPosXZ)); nextPosition.Add(t); } } else { //どことも当たらないので終わり。 break; } loopCount++; if (loopCount == 5) { break; } } } //下方向を調べる。 { CVector3 addPos; addPos.Subtract(nextPosition, position); btTransform start, end; start.setIdentity(); end.setIdentity(); start.setOrigin(btVector3(position.x, position.y + radius, position.z)); CVector3 newPos; SweepResultGround callback; callback.startPos = position; if (addPos.y < 0.0f) { newPos = (*(CVector3*)&start.getOrigin()); newPos.y += addPos.y; end.setOrigin(btVector3(newPos.x, newPos.y, newPos.z)); PhysicsWorld().ConvexSweepTest((const btConvexShape*)collider.GetBody(), start, end, callback); } if (callback.isHit) { //当たった。 float t = fabsf(acosf(callback.hitNormal.Dot(CVector3::Up))); if (t < CMath::PI * 0.3f) { //地面。 CVector3 Circle; float x = 0.0f; float offset = 0.0f; //押し戻す量。 Circle = CVector3::Zero; Circle = position; Circle.y = callback.hitPos.y;//円の中心 CVector3 v; v.Subtract(Circle, callback.hitPos); x = v.Length();//物体の角とプレイヤーの間の横幅の距離が求まる。 offset = sqrt(max(0.0f, radius*radius - x*x));//yの平方根を求める。 moveSpeed.y = 0.0f; isJump = false; nextPosition.y = callback.hitPos.y + offset - radius; } } } position = nextPosition; }
void EnemyTest::Update() { CVector3 nextPosition = position; const float MOVE_SPEED = 5.0f; if (state == enStateRun || state == enStateStand) { if (Pad(0).IsTrigger(enButtonRB3)) { isPointLightOn = !isPointLightOn; } if (Pad(0).IsPress(enButtonA)) { //Aボタンが押された。 //車との距離を調べる。 CVector3 diff = g_car->GetPosition(); diff.Subtract(position); if (diff.Length() < 2.0f) { //車との距離が2m以内。 state = enState_RideOnCar; skinModel.SetShadowReceiverFlag(false); skinModel.SetShadowCasterFlag(false); g_car->SetRideOnFlag(true); g_camera->SetCar(g_car); return; } else if(!isJump){ //車との距離が離れていたらジャンプ。 moveSpeed.y = 8.0f; isJump = true; } } //走りか立ち状態の時。 CVector3 moveDirLocal; moveDirLocal.y = 0.0f; moveDirLocal.x = Pad(0).GetLStickXF(); moveDirLocal.z = Pad(0).GetLStickYF(); const CMatrix& mViewInv = g_camera->GetCamera().GetViewMatrixInv(); //カメラ空間から見た奥方向のベクトルを取得。 CVector3 cameraZ; cameraZ.x = mViewInv.m[2][0]; cameraZ.y = 0.0f; //Y軸いらない。 cameraZ.z = mViewInv.m[2][2]; cameraZ.Normalize(); //Y軸を打ち消しているので正規化する。 //カメラから見た横方向のベクトルを取得。 CVector3 cameraX; cameraX.x = mViewInv.m[0][0]; cameraX.y = 0.0f; //Y軸はいらない。 cameraX.z = mViewInv.m[0][2]; cameraX.Normalize(); //Y軸を打ち消しているので正規化する。 CVector3 moveDir; moveDir.x = cameraX.x * moveDirLocal.x + cameraZ.x * moveDirLocal.z; moveDir.y = 0.0f; //Y軸はいらない。 moveDir.z = cameraX.z * moveDirLocal.x + cameraZ.z * moveDirLocal.z; moveSpeed.x = moveDir.x * MOVE_SPEED; moveSpeed.z = moveDir.z * MOVE_SPEED; //Y方向には重力落下を加える。 const float GRAVITY = -18.8f; moveSpeed.y += GRAVITY * GameTime().GetFrameDeltaTime(); CVector3 addPos = moveSpeed; addPos.Scale(GameTime().GetFrameDeltaTime()); nextPosition.Add(addPos); if (moveDir.LengthSq() > 0.0001f) { rotation.SetRotation(CVector3::Up, atan2f(moveDir.x, moveDir.z)); //走り状態に遷移。 state = enStateRun; } else { //立ち状態。 state = enStateStand; } ShadowMap().SetLightTarget(position); CVector3 lightPos; lightPos.Add(position, toLightPos); ShadowMap().SetLightPosition(lightPos); //コリジョン検出と解決を行う。 CollisionDetectAndResolve(nextPosition); } else if (state == enState_RideOnCar) { ShadowMap().SetLightTarget(g_car->GetPosition()); CVector3 lightPos; lightPos.Add(g_car->GetPosition(), toLightPos); ShadowMap().SetLightPosition(lightPos); if (g_car->GetMoveSpeed().Length() < 0.1f) { //車が停止状態。 if (Pad(0).IsPress(enButtonB)) { //降車。 g_camera->SetCar(NULL); g_car->SetRideOnFlag(false); skinModel.SetShadowReceiverFlag(true); skinModel.SetShadowCasterFlag(true); position = g_car->GetPosition(); state = enStateStand; } } } skinModel.Update(position, rotation, CVector3::One); //ポイントライトの位置を更新。 UpdatePointLightPosition(); //アニメーションコントロール。 AnimationControl(); lastFrameState = state; }
void CSoundManager::FillCurrentBuffer( Float* a_CurrentBuffer, const Uint a_SoundChannels, const Uint a_SampleRate, const Uint a_SamplesInBuffer ) { m_SoundsCriticalSection.Enter(); m_SampleRate = a_SampleRate; //If this is the first time we enter create and memset the echo buffer if ( m_EchoBuffer == NULL ) { m_EchoBuffer = new Float[a_SamplesInBuffer * m_EchoCount ]; memset( m_EchoBuffer, 0, sizeof(Float) * a_SamplesInBuffer * m_EchoCount ); m_ReadPositionInEchoBuffer = m_SampleRate * ( ( m_EchoDelayMS / 1000.0f ) / 1.0f ); } //Calculate listener data m_ListenersCritcalSection.Enter(); CVector3 up = m_ActiveListener->GetUp(); CVector3 lookAtCrossUp = m_ActiveListener->GetDirection(); lookAtCrossUp = lookAtCrossUp.Cross( up ); lookAtCrossUp.Normalize(); CVector3 listenerPosition = m_ActiveListener->GetWorldPosition(); m_ListenersCritcalSection.Leave(); //Loop through sound to let them fill the buffer m_SoundIt = m_SoundsMap.begin(); while( m_SoundIt != m_SoundsMap.end() ) { if ( m_SoundIt->second->IsPlaying() == true ) { m_SoundIt->second->FillCurrentBuffer( a_SoundChannels, a_SampleRate, a_SamplesInBuffer, lookAtCrossUp, listenerPosition, m_GlobalAttenuation ); } m_SoundIt++; } Float* targetPointer = a_CurrentBuffer; Float* sourcePointer; //Brickwall max Float max = 0.0f; //Loop again now collecting the buffers and adding them into a final buffer m_SoundIt = m_SoundsMap.begin(); Float oneOverSize = 1.0f / m_SoundsMap.size(); Float value; while( m_SoundIt != m_SoundsMap.end() ) { targetPointer = a_CurrentBuffer; if ( m_SoundIt->second->IsPlaying() == true ) { sourcePointer = m_SoundIt->second->GetCurrentBuffer(); for ( Uint i = 0; i < a_SamplesInBuffer; ++i ) { //Multiply with globalvolume and the one-over ( kind of ugly to prevent clipping ) value = ( *sourcePointer ) * m_GlobalVolume; //Anti distortion if ( m_DistortFunction == AntiDistortNumChannels ) { value *= oneOverSize; } else if ( m_DistortFunction == AntiDistortMagicValue ) { value *= m_MagicValue; } *targetPointer += value; Float abs = fabs( *targetPointer ); if ( abs > max ) { max = abs; } sourcePointer++; targetPointer++; } } m_SoundIt++; } //Apply echo if ( m_EchoActive == true ) { targetPointer = a_CurrentBuffer; for ( Uint i = 0; i < a_SamplesInBuffer; ++i ) { //Write to the current buffer *targetPointer += ( m_EchoBuffer[m_ReadPositionInEchoBuffer++] ); //If we reach the end of buffer wrap around if ( m_ReadPositionInEchoBuffer >= ( a_SamplesInBuffer * m_EchoCount ) ) { m_ReadPositionInEchoBuffer = 0; } //Abs for echo Float abs = fabs( *targetPointer ); if ( abs > max ) { max = abs; } //Increment target point targetPointer++; //Write current buffer into echo buffer m_EchoBuffer[m_PositionInEchoBuffer++] = a_CurrentBuffer[i] * m_EchoDecay; if ( m_PositionInEchoBuffer >= ( a_SamplesInBuffer * m_EchoCount ) ) m_PositionInEchoBuffer = 0; } } //Brickwall Float oneOverMax = 1.0f / max; if ( m_DistortFunction == AntiDistortBrickWall ) for ( Uint i = 0; i < a_SamplesInBuffer; ++i ) { a_CurrentBuffer[i] *= oneOverMax; } m_SoundsCriticalSection.Leave(); }
//main render engine function called as multiple threads void cRenderWorker::doWork(void) { // here will be rendering thread QTextStream out(stdout); int width = image->GetWidth(); int height = image->GetHeight(); double aspectRatio = (double) width / height; PrepareMainVectors(); PrepareReflectionBuffer(); if (params->ambientOcclusionEnabled && params->ambientOcclusionMode == params::AOmodeMultipeRays) PrepareAOVectors(); //init of scheduler cScheduler *scheduler = threadData->scheduler; //start point for ray-marching CVector3 start = params->camera; scheduler->InitFirstLine(threadData->id, threadData->startLine); bool lastLineWasBroken = false; //main loop for y for (int ys = threadData->startLine; scheduler->ThereIsStillSomethingToDo(threadData->id); ys = scheduler->NextLine(threadData->id, ys, lastLineWasBroken)) { //skip if line is out of region if (ys < 0) break; if (ys < data->screenRegion.y1 || ys > data->screenRegion.y2) continue; //main loop for x for (int xs = 0; xs < width; xs += scheduler->GetProgressiveStep()) { //break if by coincidence this thread started rendering the same line as some other lastLineWasBroken = false; if (scheduler->ShouldIBreak(threadData->id, ys)) { lastLineWasBroken = true; break; } if (scheduler->GetProgressivePass() > 1 && xs % (scheduler->GetProgressiveStep() * 2) == 0 && ys % (scheduler->GetProgressiveStep() * 2) == 0) continue; //skip if pixel is out of region; if (xs < data->screenRegion.x1 || xs > data->screenRegion.x2) continue; //calculate point in image coordinate system CVector2<int> screenPoint(xs, ys); CVector2<double> imagePoint = data->screenRegion.transpose(data->imageRegion, screenPoint); imagePoint.x *= aspectRatio; //full dome shemisphere cut bool hemisphereCut = false; if (params->perspectiveType == params::perspFishEyeCut && imagePoint.Length() > 0.5 / params->fov) hemisphereCut = true; //calculate direction of ray-marching CVector3 viewVector = CalculateViewVector(imagePoint, params->fov, params->perspectiveType, mRot); //---------------- 1us ------------- //Ray marching CVector3 point; CVector3 startRay = start; sRGBAfloat resultShader; sRGBAfloat objectColour; CVector3 normal; double depth = 1e20; double opacity = 1.0; //raymarching loop (reflections) if (!hemisphereCut) //in fulldome mode, will not render pixels out of the fulldome { sRayRecursionIn recursionIn; sRayMarchingIn rayMarchingIn; CVector3 direction = viewVector; direction.Normalize(); rayMarchingIn.binaryEnable = true; rayMarchingIn.direction = direction; rayMarchingIn.maxScan = params->viewDistanceMax; rayMarchingIn.minScan = params->viewDistanceMin; rayMarchingIn.start = startRay; rayMarchingIn.invertMode = false; recursionIn.rayMarchingIn = rayMarchingIn; recursionIn.calcInside = false; recursionIn.resultShader = resultShader; recursionIn.objectColour = objectColour; sRayRecursionInOut recursionInOut; sRayMarchingInOut rayMarchingInOut; rayMarchingInOut.buffCount = &rayBuffer[0].buffCount; rayMarchingInOut.stepBuff = rayBuffer[0].stepBuff; recursionInOut.rayMarchingInOut = rayMarchingInOut; recursionInOut.rayIndex = 0; sRayRecursionOut recursionOut = RayRecursion(recursionIn, recursionInOut); resultShader = recursionOut.resultShader; objectColour = recursionOut.objectColour; depth = recursionOut.rayMarchingOut.depth; if (!recursionOut.found) depth = 1e20; opacity = recursionOut.fogOpacity; normal = recursionOut.normal; } sRGBfloat pixel2; pixel2.R = resultShader.R; pixel2.G = resultShader.G; pixel2.B = resultShader.B; unsigned short alpha = resultShader.A * 65535; unsigned short opacity16 = opacity * 65535; sRGB8 colour; colour.R = objectColour.R * 255; colour.G = objectColour.G * 255; colour.B = objectColour.B * 255; sRGBfloat normalFloat; if(image->GetImageOptional()->optionalNormal) { CVector3 normalRotated = mRotInv.RotateVector(normal); normalFloat.R = (1.0 + normalRotated.x) / 2.0; normalFloat.G = (1.0 + normalRotated.z) / 2.0; normalFloat.B = 1.0 - normalRotated.y; } for (int xx = 0; xx < scheduler->GetProgressiveStep(); ++xx) { for (int yy = 0; yy < scheduler->GetProgressiveStep(); ++yy) { image->PutPixelImage(screenPoint.x + xx, screenPoint.y + yy, pixel2); image->PutPixelColour(screenPoint.x + xx, screenPoint.y + yy, colour); image->PutPixelAlpha(screenPoint.x + xx, screenPoint.y + yy, alpha); image->PutPixelZBuffer(screenPoint.x + xx, screenPoint.y + yy, (float) depth); image->PutPixelOpacity(screenPoint.x + xx, screenPoint.y + yy, opacity16); if(image->GetImageOptional()->optionalNormal) image->PutPixelNormal(screenPoint.x + xx, screenPoint.y + yy, normalFloat); } } data->statistics.numberOfRenderedPixels++; } } //emit signal to main thread when finished emit finished(); return; }