/// \brief Set the BasePoint value at a given base point coordinate. /// /// Set the BasePoint value for the given coordinate on the base /// point grid. /// If inserting this BasePoint completes the set of points required /// to define one or more Segment objects which were not yet defined, /// new Segment objects are created. If this replaces a point for one /// or more Segment objects that were already defined, the contents of /// those Segment objects are invalidated. /// @param x coordinate on the base point grid. /// @param y coordinate on the base point grid. /// @param z BasePoint value to be used at the given coordinate. void Terrain::setBasePoint(int x, int y, const BasePoint& z) { m_basePoints[x][y] = z; bool pointIsSet[3][3]; BasePoint existingPoint[3][3]; for(int i = x - 1, ri = 0; i < x + 2; ++i, ++ri) { for(int j = y - 1, rj = 0; j < y + 2; ++j, ++rj) { pointIsSet[ri][rj] = getBasePoint(i, j, existingPoint[ri][rj]); } } for(int i = x - 1, ri = 0; i < x + 1; ++i, ++ri) { for(int j = y - 1, rj = 0; j < y + 1; ++j, ++rj) { Segment * s = getSegment(i, j); if (s == 0) { bool complete = pointIsSet[ri][rj] && pointIsSet[ri + 1][rj + 1] && pointIsSet[ri + 1][rj] && pointIsSet[ri][rj + 1]; if (!complete) { continue; } s = new Segment(i * m_res, j * m_res, m_res); Matrix<2, 2, BasePoint> & cp = s->getControlPoints(); float min = existingPoint[ri][rj].height(); float max = existingPoint[ri][rj].height(); for(unsigned int k = 0; k < 2; ++k) { for(unsigned int l = 0; l < 2; ++l) { cp(k, l) = existingPoint[ri + k][rj + l]; min = std::min(cp(k, l).height(), min); max = std::max(cp(k, l).height(), max); } } s->setMinMax(min, max); Effectorstore::iterator I = m_effectors.begin(); Effectorstore::iterator Iend = m_effectors.end(); for (; I != Iend; ++I) { I->first->addToSegment(*s); } // apply shaders last, after all other data is in place if (isShaded()) { addSurfaces(*s); } m_segments[i][j] = s; continue; } s->setCornerPoint(ri ? 0 : 1, rj ? 0 : 1, z); } } }
/// \brief Set the BasePoint value at a given base point coordinate. /// /// Set the BasePoint value for the given coordinate on the base /// point grid. /// If inserting this BasePoint completes the set of points required /// to define one or more Segment objects which were not yet defined, /// new Segment objects are created. If this replaces a point for one /// or more Segment objects that were already defined, the contents of /// those Segment objects are invalidated. /// @param x coordinate on the base point grid. /// @param z coordinate on the base point grid. /// @param y BasePoint value to be used at the given coordinate. void Terrain::setBasePoint(int x, int z, const BasePoint& y) { m_basePoints[x][z] = y; bool pointIsSet[3][3]; BasePoint existingPoint[3][3]; for(int i = x - 1, ri = 0; i < x + 2; ++i, ++ri) { for(int j = z - 1, rj = 0; j < z + 2; ++j, ++rj) { pointIsSet[ri][rj] = getBasePoint(i, j, existingPoint[ri][rj]); } } for(int i = x - 1, ri = 0; i < x + 1; ++i, ++ri) { for(int j = z - 1, rj = 0; j < z + 1; ++j, ++rj) { Segment * s = getSegmentAtIndex(i, j); if (s == 0) { bool complete = pointIsSet[ri][rj] && pointIsSet[ri + 1][rj + 1] && pointIsSet[ri + 1][rj] && pointIsSet[ri][rj + 1]; if (!complete) { continue; } s = new Segment(i * m_res, j * m_res, m_res); Matrix<2, 2, BasePoint> & cp = s->getControlPoints(); for(unsigned int k = 0; k < 2; ++k) { for(unsigned int l = 0; l < 2; ++l) { cp(k, l) = existingPoint[ri + k][rj + l]; } } for (auto& entry : m_terrainMods) { const TerrainMod* terrainMod = std::get<0>(entry.second); if (terrainMod->checkIntersects(*s)) { s->updateMod(entry.first, terrainMod); } } // apply shaders last, after all other data is in place if (isShaded()) { addSurfaces(*s); } m_segments[i][j] = s; continue; } s->setCornerPoint(ri ? 0 : 1, rj ? 0 : 1, y); } } }
Color _renderPixel(const Scene &scene, const RenderParams ¶ms, const Ray &ray, ObjectId prevObjectID, int depth, float rIndex) { ObjectId objectID; Vec3 pos, norm; Material *m; bool isInside = false; if (!findNearestObject(scene, params, ray, prevObjectID, false, objectID, pos, norm, &m, isInside)) { return scene.bgColor; } Color texture = { 1.0, 1.0, 1.0 }; if (m->texFunc && objectID.type == TRIANGLE) { const Triangle &obj = scene.triangles[objectID.index]; Vec3 f1 = obj.vertex[0] - pos; Vec3 f2 = obj.vertex[1] - pos; Vec3 f3 = obj.vertex[2] - pos; float a = glm::length(glm::cross(obj.vertex[0] - obj.vertex[1], obj.vertex[1] - obj.vertex[2])); float a1 = glm::length(glm::cross(f2, f3)) / a; float a2 = glm::length(glm::cross(f3, f1)) / a; float a3 = glm::length(glm::cross(f1, f2)) / a; texture = m->texFunc(obj.texCoord[0] * a1 + obj.texCoord[1] * a2 + obj.texCoord[2] * a3); } Color c = scene.bgColor * m->ambientFactor * texture; Vec3 reflectionDir = glm::normalize(glm::reflect(ray.dir, norm)); for (const Light &light : scene.lights) { Vec3 lightDir; if (light.type == LT_POINT) { lightDir = glm::normalize(light.position - pos); } else if (light.type == LT_DIRECTIONAL) { lightDir = -light.position; } else if (light.type == LT_SPOT) { lightDir = glm::normalize(light.position - pos); float p = glm::dot(-lightDir, light.spotDir); if (p < light.spotCutoff) continue; } float s = glm::dot(norm, lightDir); if (s > 0.0f && !isShaded(scene, params, { pos, lightDir }, objectID)) { Color diffuse(s * light.intensity * texture); c += diffuse * light.color * m->diffuseFactor; } float t = glm::dot(lightDir, reflectionDir); if (t > 0.0f && !isShaded(scene, params, { pos, reflectionDir }, objectID)) { Color specular = Color(powf(t, m->shininess) * light.intensity); c += specular * light.color * m->specularFactor; } } if (depth < params.depthLimit) { c += _renderPixel(scene, params, { pos, reflectionDir }, objectID, depth + 1, rIndex) * m->reflectionFactor; if (m->refract) { float n = rIndex / m->refraction; Vec3 N = norm; if (isInside) N *= -1; float cosI = glm::dot(N, ray.dir); float cosT2 = 1.0f - n * n * (1.0f - cosI * cosI); Color r; if (cosT2 > 0.0f) { Vec3 refractionDir = n * ray.dir + (n * cosI - sqrtf(cosT2)) * N; // For refraction we don't exclude current object r = _renderPixel(scene, params, { pos + refractionDir * 1e-5f, refractionDir }, {}, depth + 1, m->refraction) * m->refractionFactor; } c = c * (1 - m->refractionFactor) + r; } } return glm::clamp(c, 0.0f, 1.0f); }
void Task::toggleShaded() { setShaded( !isShaded() ); }
void PreviewClient::requestToggleShade() { setShaded(!isShaded()); }