Exemplo n.º 1
0
/// \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);
        }
    }
}
Exemplo n.º 2
0
/// \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);
        }
    }
}
Exemplo n.º 3
0
Color _renderPixel(const Scene &scene, const RenderParams &params, 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);
}
Exemplo n.º 4
0
void Task::toggleShaded()
{
    setShaded( !isShaded() );
}
Exemplo n.º 5
0
void PreviewClient::requestToggleShade()
{
    setShaded(!isShaded());
}