Ejemplo n.º 1
0
no_alias float BTri::getDistance(const vec3 &pos) const {
	int k = 2;
	for (int i = 0; i < 3; i++){
		float d = planeDistance(edgePlanes[i], pos);
		if (d < 0){
			// Project onto the line between the points
			vec3 dir = v[i] - v[k];
			float c = dot(dir, pos - v[k]) / dot(dir, dir);

			vec3 d;
			if (c >= 1){
				d = v[i];
			} else {
				d = v[k];
				if (c > 0) d += c * dir;
			}

			return length(pos - d);
		}

		k = i;
	}

	return fabsf(planeDistance(plane, pos));
}
Ejemplo n.º 2
0
no_alias bool BTri::isAbove(const vec3 &pos) const {
/*
	return (edgeNormals[0].x * pos.x + edgeNormals[0].y * pos.y + edgeNormals[0].z * pos.z >= edgeOffsets[0] &&
			edgeNormals[1].x * pos.x + edgeNormals[1].y * pos.y + edgeNormals[1].z * pos.z >= edgeOffsets[1] &&
			edgeNormals[2].x * pos.x + edgeNormals[2].y * pos.y + edgeNormals[2].z * pos.z >= edgeOffsets[2]);
*/
/*
	return (edgePlanes[0].x * pos.x + edgePlanes[0].y * pos.y + edgePlanes[0].z * pos.z >= -edgePlanes[0].w &&
			edgePlanes[1].x * pos.x + edgePlanes[1].y * pos.y + edgePlanes[1].z * pos.z >= -edgePlanes[1].w &&
			edgePlanes[2].x * pos.x + edgePlanes[2].y * pos.y + edgePlanes[2].z * pos.z >= -edgePlanes[2].w);
*/
	return (planeDistance(edgePlanes[0], pos) >= 0 && planeDistance(edgePlanes[1], pos) >= 0 && planeDistance(edgePlanes[2], pos) >= 0);
}
Ejemplo n.º 3
0
no_alias vec3 planeHit(const vec3 &v0, const vec3 &v1, const vec4 &plane){
	vec3 dir = v1 - v0;
	float d = planeDistance(plane, v0);
	vec3 pos = v0 - (d / dot((vec3 &) plane, dir)) * dir;

	return pos;
}
Ejemplo n.º 4
0
no_alias bool BTri::intersects(const vec3 &v0, const vec3 &v1) const {
	vec3 dir = v0 - v1;
//	float k = (dot(normal, v0) + offset) / dot(normal, dir);
	float k = planeDistance(plane, v0) / dot(plane.xyz(), dir);

	if (k < 0 || k > 1) return false;

	vec3 pos = v0 - k * dir;

	for (unsigned int i = 0; i < 3; i++){
		if (planeDistance(edgePlanes[i], pos) < 0){
//		if (dot(edgeNormals[i], pos) < edgeOffsets[i]){
			return false;
		}
	}
	return true;
}
Ejemplo n.º 5
0
inline void findRoads(const Sequence &s) {
  unsigned int curr, currLink, next;
  unsigned int roadStart, roadStartLink;
  double d, hMax, length;
  bool lowSlope, roadOn = 0;

  curr     = s.m_head;
  currLink = s.m_headLink;
  for (; curr != s.m_tail; s.next(curr, currLink)) {
    next = s.m_graphHolder->getNode(curr).getLink(currLink).getNext();

    d = planeDistance(*s.m_graphHolder->getNode(curr),
                      *s.m_graphHolder->getNode(next));
    lowSlope =
        fabs(s.m_graphHolder->getNode(curr).getLink(currLink)->getSlope()) <
                roadsMaxSlope
            ? 1
            : 0;

    // Entering event in a *possibile* road axis
    if (!roadOn && lowSlope) {
      length        = 0;
      hMax          = s.m_graphHolder->getNode(curr)->z;
      roadStart     = curr;
      roadStartLink = currLink;
    }

    // Exit event from a          """
    else if (roadOn && !lowSlope && (length > hMax))
      // Then sign ROAD the sequence from roadStart to curr.
      for (; roadStart != curr; s.next(roadStart, roadStartLink))
        s.m_graphHolder->node(roadStart)
            .link(roadStartLink)
            ->setAttribute(SkeletonArc::ROAD);

    // Now update vars
    if (lowSlope) {
      length += d;
      if (hMax < s.m_graphHolder->getNode(next)->z)
        hMax = s.m_graphHolder->getNode(next)->z;
    }

    roadOn = lowSlope;
  }

  // At sequence end, force an exit event
  if (roadOn && (length > hMax))
    for (; roadStart != curr; s.next(roadStart, roadStartLink))
      s.m_graphHolder->node(roadStart)
          .link(roadStartLink)
          ->setAttribute(SkeletonArc::ROAD);
}
Ejemplo n.º 6
0
no_alias void BNode::getDistance(const vec3 &pos, float &minDist) const {
	float d = planeDistance(tri.plane, pos);

	float dist = tri.getDistance(pos);
	if (dist < minDist){
		minDist = dist;
	}
	
	if (back && d < minDist){
		back->getDistance(pos, minDist);		
	}

	if (front && -d < minDist){
		front->getDistance(pos, minDist);
	}
}
Ejemplo n.º 7
0
no_alias bool BNode::pushSphere(vec3 &pos, const float radius) const {
	float d = planeDistance(tri.plane, pos);

	bool pushed = false;
	if (fabsf(d) < radius){
		if (tri.isAbove(pos)){
//			pos += (radius - d) * tri.normal; 
			pos += (radius - d) * tri.plane.xyz();
			pushed = true;
		}
	}

	if (front != NULL && d > -radius) pushed |= front->pushSphere(pos, radius);
	if (back  != NULL && d <  radius) pushed |= back ->pushSphere(pos, radius);

	return pushed;
}
Ejemplo n.º 8
0
no_alias bool BSP::isInOpenSpace(const vec3 &pos) const {
	if (top != NULL){

		BNode *node = top;
		while (true){
			float d = planeDistance(node->tri.plane, pos);

			if (d > 0){
				if (node->front){
					node = node->front;
				} else return true;
			} else {
				if (node->back){
					node = node->back;
				} else return false;
			}
		}
	}

	return false;
}
Ejemplo n.º 9
0
void BNode::build(Array <BTri> &tris, const int splitCost, const int balCost, const float epsilon){
	uint index = 0;
	int minScore = 0x7FFFFFFF;

	for (uint i = 0; i < tris.getCount(); i++){
		int score = 0;
		int diff = 0;
		for (uint k = 0; k < tris.getCount(); k++){
			uint neg = 0, pos = 0;
			for (uint j = 0; j < 3; j++){
				float dist = planeDistance(tris[i].plane, tris[k].v[j]);
				if (dist < -epsilon) neg++; else
				if (dist >  epsilon) pos++;
			}
			if (pos){
				if (neg) score += splitCost; else diff++;
			} else {
				if (neg) diff--; else diff++;
			}
		}
		score += balCost * abs(diff);
		if (score < minScore){
			minScore = score;
			index = i;
		}
	}

	tri = tris[index];
	tris.fastRemove(index);

	Array <BTri> backTris;
	Array <BTri> frontTris;
	for (uint i = 0; i < tris.getCount(); i++){

		uint neg = 0, pos = 0;
		for (uint j = 0; j < 3; j++){
			float dist = planeDistance(tri.plane, tris[i].v[j]);
            if (dist < -epsilon) neg++; else
			if (dist >  epsilon) pos++;
		}

		if (neg){
			if (pos){
				BTri newTris[3];
				int nPos, nNeg;
				tris[i].split(newTris, nPos, nNeg, tri.plane, epsilon);
				for (int i = 0; i < nPos; i++){
					frontTris.add(newTris[i]);
				}
				for (int i = 0; i < nNeg; i++){
					backTris.add(newTris[nPos + i]);
				}
			} else {
				backTris.add(tris[i]);
			}
		} else {
			frontTris.add(tris[i]);
		}
	}
	tris.reset();

	if (backTris.getCount() > 0){
		back = new BNode;
		back->build(backTris, splitCost, balCost, epsilon);
	} else back = NULL;

	if (frontTris.getCount() > 0){
		front = new BNode;
		front->build(frontTris, splitCost, balCost, epsilon);
	} else front = NULL;
}
Ejemplo n.º 10
0
void BTri::split(BTri *dest, int &nPos, int &nNeg, const vec4 &plane, const float epsilon) const {
	float d[3];
	for (int i = 0; i < 3; i++){
		d[i] = planeDistance(plane, v[i]);
	}

	int first  = 2;
	int second = 0;
	while (!(d[second] > epsilon && d[first] <= epsilon)){
		first = second;
		second++;
	}

	// Positive triangles
	nPos = 0;
	vec3 h = planeHit(v[first], v[second], plane);
	do {
		first = second;
		second++;
		if (second >= 3) second = 0;

		dest->v[0] = h;
		dest->v[1] = v[first];
		if (d[second] > epsilon){
			dest->v[2] = v[second];
		} else {
			dest->v[2] = h = planeHit(v[first], v[second], plane);
		}

		dest->data = data;
		dest->finalize();
		dest++;
		nPos++;
	} while (d[second] > epsilon);

	// Skip zero area triangle
	if (fabsf(d[second]) <= epsilon){
		first = second;
		second++;
		if (second >= 3) second = 0;
	}

	// Negative triangles
	nNeg = 0;
	do {
		first = second;
		second++;
		if (second >= 3) second = 0;

		dest->v[0] = h;
		dest->v[1] = v[first];
		if (d[second] < -epsilon){
			dest->v[2] = v[second];
		} else {
			dest->v[2] = planeHit(v[first], v[second], plane);
		}

		dest->data = data;
		dest->finalize();
		dest++;
		nNeg++;
	} while (d[second] < -epsilon);
}
Ejemplo n.º 11
0
no_alias BTri *BNode::intersectsCached(const vec3 &v0, const vec3 &v1, const vec3 &dir) const {
#if 0
	float d0 = planeDistance(tri.plane, v0);
	float d1 = planeDistance(tri.plane, v1);

	vec3 pos;

	if (d0 > 0){
		if (d1 <= 0){
			pos = v0 - (d0 / dot((vec3 &) tri.plane, dir)) * dir;
		}

		if (front != NULL){
			BTri *tri;
			if (d1 <= 0){
				tri = front->intersectsCached(v0, pos, dir);
			} else {
				tri = front->intersectsCached(v0, v1, dir);
			}
			if (tri) return tri;
		}

		if (d1 <= 0){
			if (tri.isAbove(pos)) return (BTri *) &tri;
			if (back != NULL){
				BTri *tri = back->intersectsCached(pos, v1, dir);
				if (tri) return tri;
			}
		}
	} else {
		if (d1 > 0){
			pos = v0 - (d0 / dot((vec3 &) tri.plane, dir)) * dir;
		}
		if (back != NULL){
			BTri *tri;
			if (d1 > 0){
				tri = back->intersectsCached(v0, pos, dir);
			} else {
				tri = back->intersectsCached(v0, v1, dir);
			}
			if (tri) return tri;
		}
		if (d1 > 0){
			if (tri.isAbove(pos)) return (BTri *) &tri;
			if (front != NULL){
				BTri *tri = front->intersectsCached(pos, v1, dir);
				if (tri) return tri;
			}
		}
	}

#else

	float d = planeDistance(tri.plane, v0);

	if (d > 0){
		if (front != NULL){
			BTri *tri = front->intersectsCached(v0, v1, dir);
			if (tri) return tri;
		}
		if (planeDistance(tri.plane, v1) < 0){
			vec3 pos = v0 - (d / dot(tri.plane.xyz(), dir)) * dir;
			if (tri.isAbove(pos)) return (BTri *) &tri;
			if (back != NULL){
				BTri *tri = back->intersectsCached(v0, v1, dir);
				if (tri) return tri;
			}
		}
	} else {
		if (back != NULL){
			BTri *tri = back->intersectsCached(v0, v1, dir);
			if (tri) return tri;
		}
		if (planeDistance(tri.plane, v1) > 0){
			vec3 pos = v0 - (d / dot(tri.plane.xyz(), dir)) * dir;
			if (tri.isAbove(pos)) return (BTri *) &tri;
			if (front != NULL){
				BTri *tri = front->intersectsCached(v0, v1, dir);
				if (tri) return tri;
			}
		}
	}
#endif

	return NULL;
}
Ejemplo n.º 12
0
no_alias bool BNode::intersects(const vec3 &v0, const vec3 &v1, const vec3 &dir, vec3 *point, const BTri **triangle) const {
#if 0
	float d0 = planeDistance(tri.plane, v0);
	float d1 = planeDistance(tri.plane, v1);

	vec3 pos;
	if (d0 > 0){
		if (d1 <= 0){
			pos = v0 - (d0 / dot(tri.plane.xyz(), dir)) * dir;
		}

		if (front != NULL && front->intersects(v0, (d1 <= 0)? pos : v1, dir, point, triangle)) return true;

		if (d1 <= 0){
			if (tri.isAbove(pos)){
				if (point) *point = pos;
				if (triangle) *triangle = &tri;
				return true;
			}
			if (back != NULL && back->intersects(pos, v1, dir, point, triangle)) return true;
		}
	} else {
		if (d1 > 0){
			pos = v0 - (d0 / dot(tri.plane.xyz(), dir)) * dir;
		}

		if (back != NULL && back->intersects(v0, (d1 > 0)? pos : v1, dir, point, triangle)) return true;

		if (d1 > 0){
			if (tri.isAbove(pos)){
				if (point) *point = pos;
				if (triangle) *triangle = &tri;
				return true;
			}
			if (front != NULL && front->intersects(pos, v1, dir, point, triangle)) return true;
		}
	}

#else
	float d = planeDistance(tri.plane, v0);

	if (d > 0){
		if (front != NULL && front->intersects(v0, v1, dir, point, triangle)) return true;
		if (planeDistance(tri.plane, v1) < 0){
			vec3 pos = v0 - (d / dot(tri.plane.xyz(), dir)) * dir;
			if (tri.isAbove(pos)){
				if (point) *point = pos;
				if (triangle) *triangle = &tri;
				return true;
			}
			if (back != NULL && back->intersects(v0, v1, dir, point, triangle)) return true;
		}
	} else {
		if (back != NULL && back->intersects(v0, v1, dir, point, triangle)) return true;
		if (planeDistance(tri.plane, v1) > 0){
			vec3 pos = v0 - (d / dot(tri.plane.xyz(), dir)) * dir;
			if (tri.isAbove(pos)){
				if (point) *point = pos;
				if (triangle) *triangle = &tri;
				return true;
			}
			if (front != NULL && front->intersects(v0, v1, dir, point, triangle)) return true;
		}
	}
#endif

	return false;
}
Ejemplo n.º 13
0
void renderDrawVoxel(Voxel *voxel, int frustCull, Vector center, float size, unsigned short maxDrawDepth) {
    int i;
    float distance;
    if (frustCull) {
        int count = 0;
        for (i = 0; i < 6; i++) {
            distance = planeDistance(renderEnv.scene.camera.frustrum[5 - i], center);
            if (distance < -size) {
                return;
            }
            if (distance >= size) {
                count++;
            }
        }

        if (count == 6) {
            frustCull = 0;
        }
    } else {
        distance = planeDistance(renderEnv.scene.camera.frustrum[0], center);
    }

    unsigned short depth = voxelGetDepth(voxel);
    if (depth == VOXEL_DISPLAY_VOXEL_DEPTH) {
        // This should be moved to a background thread ... or something similar.
        if (voxelIsDisplayUpdateRequired(voxel)) {
            voxelUpdateDisplay(
                voxel,
                center,
                size,
                maxDrawDepth
            );
        }

        i = 0;
        if (distance > renderEnv.highMediumDetailBorder * renderEnv.scene.camera.farDist) {
            i++;
            if (distance > renderEnv.mediumLowDetailBorder * renderEnv.scene.camera.farDist) {
                i++;
            }
        }
        glCallList(voxelGetDisplayList(voxel) + i);
    } else if (depth < VOXEL_DISPLAY_VOXEL_DEPTH) {
        float half = size / 2.0f;
        float quarter = size / 4.0f;
        for (i = 0; i < voxel->childCount; i++) {
            switch (voxelGetPosition(voxel->children[i])) {
                case 0:
                    renderDrawVoxel(voxel->children[i], frustCull, vectorLiteral(center.x - quarter, center.y - quarter, center.z - quarter), half, maxDrawDepth);
                    break;

                case 1:
                    renderDrawVoxel(voxel->children[i], frustCull, vectorLiteral(center.x - quarter, center.y - quarter, center.z + quarter), half, maxDrawDepth);
                    break;

                case 2:
                    renderDrawVoxel(voxel->children[i], frustCull, vectorLiteral(center.x - quarter, center.y + quarter, center.z - quarter), half, maxDrawDepth);
                    break;

                case 3:
                    renderDrawVoxel(voxel->children[i], frustCull, vectorLiteral(center.x - quarter, center.y + quarter, center.z + quarter), half, maxDrawDepth);
                    break;

                case 4:
                    renderDrawVoxel(voxel->children[i], frustCull, vectorLiteral(center.x + quarter, center.y - quarter, center.z - quarter), half, maxDrawDepth);
                    break;

                case 5:
                    renderDrawVoxel(voxel->children[i], frustCull, vectorLiteral(center.x + quarter, center.y - quarter, center.z + quarter), half, maxDrawDepth);
                    break;

                case 6:
                    renderDrawVoxel(voxel->children[i], frustCull, vectorLiteral(center.x + quarter, center.y + quarter, center.z - quarter), half, maxDrawDepth);
                    break;

                case 7:
                    renderDrawVoxel(voxel->children[i], frustCull, vectorLiteral(center.x + quarter, center.y + quarter, center.z + quarter), half, maxDrawDepth);
                    break;

                default:
                    break;
            }
        }
    }
}