Beispiel #1
0
/// \brief Keep the value of \p infinity as small as possible to improve precision in Winding_Clip.
void Winding_createInfinite(FixedWinding& winding, const Plane3& plane, double infinity)
{
  double max = -infinity;
  int x = -1;
  for (int i=0 ; i<3; i++)
  {
    double d = fabs(plane.normal()[i]);
    if (d > max)
    {
      x = i;
      max = d;
    }
  }
  if(x == -1)
  {
    globalErrorStream() << "invalid plane\n";
    return;
  }
    
  DoubleVector3 vup = g_vector3_identity;  
  switch (x)
  {
  case 0:
  case 1:
    vup[2] = 1;
    break;    
  case 2:
    vup[0] = 1;
    break;    
  }


  vector3_add(vup, vector3_scaled(plane.normal(), -vector3_dot(vup, plane.normal())));
  vector3_normalise(vup);
    
  DoubleVector3 org = vector3_scaled(plane.normal(), plane.dist());
  
  DoubleVector3 vright = vector3_cross(vup, plane.normal());
  
  vector3_scale(vup, infinity);
  vector3_scale(vright, infinity);

  // project a really big  axis aligned box onto the plane
  
  DoubleLine r1, r2, r3, r4;
  r1.origin = vector3_added(vector3_subtracted(org, vright), vup);
  r1.direction = vector3_normalised(vright);
  winding.push_back(FixedWindingVertex(r1.origin, r1, c_brush_maxFaces));
  r2.origin = vector3_added(vector3_added(org, vright), vup);
  r2.direction = vector3_normalised(vector3_negated(vup));
  winding.push_back(FixedWindingVertex(r2.origin, r2, c_brush_maxFaces));
  r3.origin = vector3_subtracted(vector3_added(org, vright), vup);
  r3.direction = vector3_normalised(vector3_negated(vright));
  winding.push_back(FixedWindingVertex(r3.origin, r3, c_brush_maxFaces));
  r4.origin = vector3_subtracted(vector3_subtracted(org, vright), vup);
  r4.direction = vector3_normalised(vup);
  winding.push_back(FixedWindingVertex(r4.origin, r4, c_brush_maxFaces));
}
scene::INodePtr BrushDef3Parser::parse(parser::DefTokeniser& tok) const
{
	// Create a new brush
	scene::INodePtr node = GlobalBrushCreator().createBrush();

	// Cast the node, this must succeed
	IBrushNodePtr brushNode = boost::dynamic_pointer_cast<IBrushNode>(node);
	assert(brushNode != NULL);

	IBrush& brush = brushNode->getIBrush();

	tok.assertNextToken("{");

	// Parse face tokens until a closing brace is encountered
	while (1)
	{
		std::string token = tok.nextToken();

		// Token should be either a "(" (start of face) or "}" (end of brush)
		if (token == "}")
		{
			break; // end of brush
		}
		else if (token == "(") // FACE
		{
			// Construct a plane and parse its values
			Plane3 plane;

			plane.normal().x() = string::to_float(tok.nextToken());
			plane.normal().y() = string::to_float(tok.nextToken());
			plane.normal().z() = string::to_float(tok.nextToken());
			plane.dist() = -string::to_float(tok.nextToken()); // negate d

			tok.assertNextToken(")");

			// Parse TexDef
			Matrix4 texdef;
			tok.assertNextToken("(");

			tok.assertNextToken("(");
			texdef.xx() = string::to_float(tok.nextToken());
			texdef.yx() = string::to_float(tok.nextToken());
			texdef.tx() = string::to_float(tok.nextToken());
			tok.assertNextToken(")");

			tok.assertNextToken("(");
			texdef.xy() = string::to_float(tok.nextToken());
			texdef.yy() = string::to_float(tok.nextToken());
			texdef.ty() = string::to_float(tok.nextToken());
			tok.assertNextToken(")");

			tok.assertNextToken(")");

			// Parse Shader
			std::string shader = tok.nextToken();

			// Parse Flags (usually each brush has all faces detail or all faces structural)
			IBrush::DetailFlag flag = static_cast<IBrush::DetailFlag>(
				string::convert<std::size_t>(tok.nextToken(), IBrush::Structural));
			brush.setDetailFlag(flag);

			// Ignore the other two flags
			tok.skipTokens(2);

			// Finally, add the new face to the brush
			/*IFace& face = */brush.addFace(plane, texdef, shader);
		}
		else {
			std::string text = (boost::format(_("BrushDef3Parser: invalid token '%s'")) % token).str();
			throw parser::ParseException(text);
		}
	}

	// Final outer "}"
	tok.assertNextToken("}");

	return node;
}
Beispiel #3
0
// Get a transformed copy of this frustum
Frustum Frustum::getTransformedBy(const Matrix4& matrix) const
{
    // greebo: DR's Plane3 is seriuosly hampered by its internal representation
    // which is nx,ny,nz,dist instead of a,b,c,d. This causes a lot of confusion
    // and makes it necessary to invert the dist() member each time before
    // applying a transformation matrix.

    Plane3 rightTemp = Plane3(right.normal(), -right.dist()).transform(matrix);
    Plane3 leftTemp = Plane3(left.normal(), -left.dist()).transform(matrix);
    Plane3 topTemp = Plane3(top.normal(), -top.dist()).transform(matrix);
    Plane3 bottomTemp = Plane3(bottom.normal(), -bottom.dist()).transform(matrix);
    Plane3 backTemp = Plane3(back.normal(), -back.dist()).transform(matrix);
    Plane3 frontTemp = Plane3(front.normal(), -front.dist()).transform(matrix);

    rightTemp.dist() = -rightTemp.dist();
    leftTemp.dist() = -leftTemp.dist();
    topTemp.dist() = -topTemp.dist();
    bottomTemp.dist() = -bottomTemp.dist();
    backTemp.dist() = -backTemp.dist();
    frontTemp.dist() = -frontTemp.dist();

    return Frustum(
        rightTemp,
        leftTemp,
        bottomTemp,
        topTemp,
        backTemp,
        frontTemp
    );
}
Beispiel #4
0
/// \brief Returns the infinite line that is the intersection of \p plane and \p other.
inline DoubleLine plane3_intersect_plane3(const Plane3& plane, const Plane3& other)
{
  DoubleLine line;
  line.direction = vector3_cross(plane.normal(), other.normal());
  switch(vector3_largest_absolute_component_index(line.direction))
  {
  case 0:
    line.origin.x() = 0;
    line.origin.y() = (-other.dist() * plane.normal().z() - -plane.dist() * other.normal().z()) / line.direction.x();
    line.origin.z() = (-plane.dist() * other.normal().y() - -other.dist() * plane.normal().y()) / line.direction.x();
    break;
  case 1:
    line.origin.x() = (-plane.dist() * other.normal().z() - -other.dist() * plane.normal().z()) / line.direction.y();
    line.origin.y() = 0;
    line.origin.z() = (-other.dist() * plane.normal().x() - -plane.dist() * other.normal().x()) / line.direction.y();
    break;
  case 2:
    line.origin.x() = (-other.dist() * plane.normal().y() - -plane.dist() * other.normal().y()) / line.direction.z();
    line.origin.y() = (-plane.dist() * other.normal().x() - -other.dist() * plane.normal().x()) / line.direction.z();
    line.origin.z() = 0;
    break;
  default:
    break;
  }

  return line;
}
Beispiel #5
0
inline double plane3_distance_to_point(const Plane3& plane, const Vector3& point)
{
  return vector3_dot(point, plane.normal()) - plane.dist();
}