Ejemplo n.º 1
0
void CreateTool::CreateSingleObject( const Vector3& translation, const Vector3& normal, bool checkValid )
{
	Matrix4 orientation;

	{
		HELIUM_EDITOR_SCENE_SCOPE_TIMER( "Finalize Instance Orientation" );
		FinalizeOrientation( orientation, translation, normal );
	}

	if ( checkValid )
	{
		float adjustedInstanceRadius = m_InstanceRadius / s_PaintDensity;
		float minDistance = 2.0f * adjustedInstanceRadius;
		float scale = minDistance / m_InstanceRadius;
		Matrix4 scaledOrientation( Scale( minDistance, minDistance, minDistance ) );
		scaledOrientation *= orientation;

		AlignedBox instanceBounds = m_InstanceBounds;
		instanceBounds.Transform( scaledOrientation );

		if ( !ValidPosition( instanceBounds, translation, minDistance ) )
		{
			return;
		}
	}

	if ( m_Instance.ReferencesObject() )
	{
		HELIUM_EDITOR_SCENE_SCOPE_TIMER( "Update Temporary Instance At Location" );
		m_Instance->SetObjectTransform( orientation );
		m_Instance->Evaluate( GraphDirections::Downstream );
	}
	else
	{
		HELIUM_EDITOR_SCENE_SCOPE_TIMER( "Place Temporary Instance At Location" );
		Place( orientation );
	}

	{
		HELIUM_EDITOR_SCENE_SCOPE_TIMER( "Add Instance To Scene" );
		AddToScene();
	}

	if ( m_Instance.ReferencesObject() )
	{
		HELIUM_EDITOR_SCENE_SCOPE_TIMER( "Update Temporary Instance At Location" );
		if ( m_PaintTimer.IsAlive() )
		{
			orientation *= Matrix4( Scale( 0.0f, 0.0f, 0.0f ) );
		}

		m_Instance->SetObjectTransform( orientation );
		m_Instance->Evaluate( GraphDirections::Downstream );
	}
}
Ejemplo n.º 2
0
	void debugBox( const AlignedBox &b, bool wire ) {
		vec3 move,scale;
		move = b.getCenter();
		scale = b.getSize();
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glTranslatef(move.x,move.y,move.z);
		glScalef(scale.x,scale.y,scale.z);
		debugCube(1.0,wire);
		glPopMatrix();
	}
Ejemplo n.º 3
0
bool Frustum::IntersectsBox(const AlignedBox& box, bool precise) const
{
    MATH_FUNCTION_TIMER();

    if ( fabs((box.maximum - box.minimum).Length()) < LinearIntersectionError )
    {
        return IntersectsPoint( box.Center() );
    }
    else
    {
        f32 m, n;
        Vector3 c = box.Center();
        Vector3 d = box.maximum - c;

        for (i32 i=0; i<6; i++)
        {
            const Plane& p = (*this)[i];

            m = (c.x * p.A()) + (c.y * p.B()) + (c.z * p.C()) + p.D();
            n = (d.x * abs(p.A())) + (d.y * abs(p.B())) + (d.z * abs(p.C()));

            if (m + n < 0)
            {
                return false;
            }
        }

        if ( precise )
        {
#pragma TODO("This precise test should be using separated axis testing instead of triangle decimation")
            V_Vector3 vertices;
            vertices.reserve(8);
            box.GetVertices(vertices);

            V_Vector3 triangleList;
            triangleList.reserve(36);
            AlignedBox::GetTriangulated(vertices, triangleList);

            for ( int i=0; i<36; i+=3 )
            {
                if ( IntersectsTriangle( triangleList[i], triangleList[i+1], triangleList[i+2] ) )
                {
                    return true;
                }
            }

            return false;
        }
    }

    return true;
}
Ejemplo n.º 4
0
bool LinePickVisitor::AddHitBox(const AlignedBox& box, Vector3& intersection)
{
	// allocate a hit
	PickHit* hit = AddHit();

	// the corner of the box we are closest to
	Vector3 corner = box.ClosestCorner(intersection);

	// transform values into world space
	m_CurrentWorldTransform.TransformVertex(corner);
	m_CurrentWorldTransform.TransformVertex(intersection);

	// set vertex in world space
	if (!HasFlags(PickFlags::IgnoreVertex))
	{
		hit->SetVertex(corner, (corner - intersection).Length());
	}

	// set intersection in world space (we use FLT_MAX for the distance since the distance is spacial)
	if (!HasFlags(PickFlags::IgnoreIntersection))
	{
		hit->SetIntersection(intersection);
	}

	return true;
}
Ejemplo n.º 5
0
			void simple_cube(Mesh<VertexT> & mesh, const AlignedBox<3> & box)
			{
				const std::size_t CUBE_3X2[] = {
					1, 0, 3, 2,
					3, 2, 7, 6,
					7, 6, 5, 4,
					4, 6, 6, 6, // Degenerate
					6, 2, 4, 0,
					4, 0, 5, 1,
					5, 1, 7, 3
				};

				const Vec3u K = 2;
				const std::size_t SIZE = sizeof(CUBE_3X2) / sizeof(std::size_t);

				mesh.vertices.resize(SIZE);
				mesh.indices.resize(SIZE);

				for (std::size_t c = 0; c < SIZE; c += 1) {
					//std::cout << "c: " << c << " = "  << K.distribute(c) << std::endl;
					Vector<3, bool> current_corner(K.distribute(c));

					mesh.vertices[c].position = box.corner(current_corner);
					mesh.indices[c] = CUBE_3X2[c];
				}
			}
Ejemplo n.º 6
0
bool LightingScene::motion (const MotionInput & input)
{
    AlignedBox<2> bounds = input.bounds();

    if (this->manager()->display_context()->cursor_mode() == CURSOR_NORMAL) {
        // This assumes the mouse position is changing:
        Vec2 relative_position = input.current_position().reduce() - bounds.origin();

        _point = (relative_position / bounds.size()) * 2 - 1;
    } else {
        // We are receiving relative changes to cursor position:
        _point += (input.motion().reduce() / 500.0);
    }

    _camera->process(input);

    //logger()->log(LOG_INFO, LogBuffer() << "Location: " << input.current_position() << " Motion: " << input.motion() << " Point: " << _point);

    return true;
}
Ejemplo n.º 7
0
bool FrustumPickVisitor::AddHitBox(const AlignedBox& box)
{
	// allocate a hit
	PickHit* hit = AddHit();

	// our intersection point is the center point (HACK)
	Vector3 intersection (box.Center());

	// transform values into world space
	m_CurrentWorldTransform.TransformVertex(intersection);

	// set intersection in world space (we use FLT_MAX for the distance since the distance is spacial)
	if (!HasFlags(PickFlags::IgnoreIntersection))
	{
		hit->SetIntersection(intersection);
	}

	return true;
}
Ejemplo n.º 8
0
void
Model::normalize(const Vector3f& centerOffset)
{
    AlignedBox<float, 3> bbox;

    for (vector<Mesh*>::const_iterator iter = meshes.begin(); iter != meshes.end(); iter++)
        bbox.extend((*iter)->getBoundingBox());

    Vector3f center = (bbox.min() + bbox.max()) * 0.5f + centerOffset;
    Vector3f extents = bbox.max() - bbox.min();
    float maxExtent = extents.maxCoeff();

    transform(-center, 2.0f / maxExtent);

    normalized = true;
}
Ejemplo n.º 9
0
Frustum::Frustum(const AlignedBox& b)
{
    V_Vector3 v;
    b.GetVertices(v);

    //top 3047
    top = Plane(v[3], (v[3] - v[0]).Cross(v[4] - v[0]));

    //bottom 6512
    bottom = Plane(v[6], (v[6] - v[5]).Vector3::Cross(v[1] - v[5]));

    //left 6237
    left = Plane(v[6], (v[6] - v[2]).Vector3::Cross(v[3] - v[2]));

    //right 1540
    right = Plane(v[1], (v[1] - v[5]).Cross(v[4] - v[5]));

    //front 2103
    front = Plane(v[2], (v[2] - v[1]).Cross(v[0] - v[1]));

    //back 5674
    back = Plane(v[5], (v[5] - v[6]).Cross(v[7] - v[6]));
}
Ejemplo n.º 10
0
bool Frustum::Contains(const AlignedBox& box) const
{
    MATH_FUNCTION_TIMER();

    V_Vector3 verts;
    box.GetVertices(verts);

    for (size_t i=0; i<verts.size(); i++)
    {
        // for each plane
        for (i32 j=0; j<6; j++)
        {
            const Plane& p = (*this)[j];

            // we need this vert to be above each plane
            if ((verts[i].x * p.A()) + (verts[i].y * p.B()) + (verts[i].z * p.C()) + p.D() < 0)
            {
                return false;
            }
        }
    }

    return true;
}
Ejemplo n.º 11
0
void Camera::Frame(const AlignedBox& box)
{
    SetPivot(box.Center());
    SetOffset((box.maximum - box.minimum).Length());
    Update(true);
}
Ejemplo n.º 12
0
		bool Frustum<NumericT>::intersects_with (const AlignedBox<3, NumericT> &b) const
		{
			return intersects_with(b.bounding_sphere());
		}
Ejemplo n.º 13
0
void Camera::frameBox( const AlignedBox& box ) {
   vector< Point3 > corners;
   for ( int i = 0; i < 8; ++i )
      corners.push_back( box.getCorner( i ) );
   framePoints( corners );
}
Ejemplo n.º 14
0
void Camera::framePoints( const vector< Point3 >& l, bool frameExactly ) {
   if ( l.empty() )
      return;
   Vector3 direction = (_target - _position).normalized();
   Vector3 right = direction ^ _up;

   // Transform each of the points to camera space,
   // and find the minimal bounding box containing them
   // that is aligned with camera space.
   // FIXME the projection we do here is orthogonal;
   // it ignores the perspective projection of the camera
   // that will make distant points appear closer to the line of sight.
   // Thus, the camera will not frame points as tightly as it could.
   AlignedBox box;
   vector< Point3 >::const_iterator it = l.begin();
   for ( ; it != l.end(); ++it ) {
      Vector3 v = (*it) - _position;
      box.bound( Point3( v * right, v * _up, v * direction ) );
   }

   // Translate the camera such
   // that the line of sight passes through the centre of the bounding box,
   // and the target point is at the centre of the bounding box.
   Point3 boxCentre = box.getCentre();
   Point3 newTarget = _position
      + right * boxCentre.x() + _up * boxCentre.y() + direction * boxCentre.z();
   Vector3 translation = newTarget - _target;
   _position += translation;
   _target = newTarget;

   // Next, dolly the camera forward (or backward)
   // such that all points are visible.
   // For each given point,
   // we compute the amount by which to dolly forward for that point,
   // and find the minimum of all such amounts
   // to use for the actual dolly.
   /*
      In the below diagram,
         "1" is the current position of the camera, which is pointing down
         "a" is the distance to the near plane
         "b" is half the width/height of the viewport
         "3" is a point we want to frame by dollying the camera forward
         "2" is the new location to place the camera to just frame "3"
         "?" is the distance to dolly forward, which we want to compute

                   |-b-|

                       1  -  -  -
                      /|  |  |  |
                     / |  a  |  |
                    /  |  |  |  |
                   /---|  -  ?  |
                  /    |     |  |
                 /     |     |  |
                /      |     |  c
               /       2     -  |
              /       /|     |  |
             /       / |     |  |
            /       /  |     e  |
           /       /   |     |  |
          /       /    |     |  |
         .-------3-----.     -  -

                 |--f--|

         |------d------|

      The two hypotenuses are parallel because we don't want to change
      the camera's field of view.
      We have
         a/b = c/d = e/f   (where a,b,c,f are known)
      and
         ? = c - e
           = c - f*a/b
   */

   float minDollyDelta = 0;
   bool minDollyDeltaInitialized = false;
   float min_c = 0;
   for ( it = l.begin(); it != l.end(); ++it ) {
      Vector3 v = (*it) - _position;
      float c = v * direction;

      if ( it == l.begin() ) min_c = c;
      else if ( c < min_c ) min_c = c;

      float f, dollyDelta;
      if ( _viewport_width > 0 ) {
         f = fabs( v * right );
         dollyDelta = c - f * _near_plane * 2 / _viewport_width;
         if ( minDollyDeltaInitialized ) {
            if ( dollyDelta < minDollyDelta )
               minDollyDelta = dollyDelta;
         }
         else {
            minDollyDelta = dollyDelta;
            minDollyDeltaInitialized = true;
         }
      }
      if ( _viewport_height > 0 ) {
         f = fabs( v * _up );
         dollyDelta = c - f * _near_plane * 2 / _viewport_height;
         if ( minDollyDeltaInitialized ) {
            if ( dollyDelta < minDollyDelta )
               minDollyDelta = dollyDelta;
         }
         else {
            minDollyDelta = dollyDelta;
            minDollyDeltaInitialized = true;
         }
      }
   }

   if ( ! frameExactly ) {
      // check that the dolly won't put some points
      // in front of the near plane
      if ( min_c - minDollyDelta < _near_plane )
         minDollyDelta = min_c - _near_plane;

      // fudge factor, to add a tiny margin around the points
      minDollyDelta -= 0.05f * _near_plane;
   }

   // perform the dolly
   _position += direction * minDollyDelta;

   if ( ( _target - _position ).length() <= _pushThreshold*_near_plane ) {
      // The target point is too close.
      _target = _position + direction * ( _pushThreshold*_near_plane );
   }

   // FIXME: should we check if some points are beyond the
   // far plane, and if so move the far plane further back ?
}
Ejemplo n.º 15
0
void
VectorMapLayer::renderTile(RenderContext& rc, const WorldGeometry* /* world */, const QuadtreeTile* tile) const
{
#ifndef VESTA_OGLES2
    rc.setVertexInfo(VertexSpec::PositionColor);

    Material simpleMaterial;
    simpleMaterial.setDiffuse(Spectrum(1.0f, 1.0f, 1.0f));
    simpleMaterial.setOpacity(1.0f);
    rc.bindMaterial(&simpleMaterial);

    float tileArc = float(PI) * tile->extent();
    Vector2f southwest = tile->southwest();

    SpherePatch box;
    box.west = float(PI) * southwest.x();
    box.east = box.west + tileArc;
    box.south = float(PI) * southwest.y();
    box.north = box.south + tileArc;

    AlignedBox<float, 2> bounds(Vector2f(box.west, box.south), Vector2f(box.east, box.north));

    for (vector<counted_ptr<MapElement> >::const_iterator iter = m_elements.begin(); iter != m_elements.end(); ++iter)
    {
        const MapElement* element = iter->ptr();
        bool tileContainsElement = false;

        if (element)
        {
            AlignedBox<float, 2> elementBox = element->bounds();
            if (!elementBox.isNull())
            {
                if (elementBox.min().x() < bounds.max().x() &&
                    elementBox.max().x() > bounds.min().x() &&
                    elementBox.min().y() < bounds.max().y() &&
                    elementBox.max().y() > bounds.min().y())
                {
                    tileContainsElement = true;
                }
            }
        }

        if (tileContainsElement)
        {
            Spectrum color = element->color();
            glColor4f(color.red(), color.green(), color.blue(), element->opacity());

            if (element->opacity() < 1.0f)
            {
                glEnable(GL_BLEND);
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            }
            else
            {
                glDisable(GL_BLEND);
            }

            element->render(box.west, box.south, box.east, box.north);
        }
    }

    glDisable(GL_BLEND);
#endif
}