Esempio n. 1
0
PathTraversalState Path::traversalStateAtLength(float length, bool& success) const
{
    PathTraversalState traversalState(PathTraversalState::Action::VectorAtLength, length);
    apply(&traversalState, pathLengthApplierFunction);
    success = traversalState.success();
    return traversalState;
}
Esempio n. 2
0
float Path::normalAngleAtLength(float length, bool& ok)
{
    PathTraversalState traversalState(PathTraversalState::TraversalNormalAngleAtLength);
    traversalState.m_desiredLength = length;
    apply(&traversalState, pathLengthApplierFunction);
    ok = traversalState.m_success;
    return traversalState.m_normalAngle;
}
Esempio n. 3
0
FloatPoint Path::pointAtLength(float length, bool& ok) const
{
    PathTraversalState traversalState(PathTraversalState::TraversalPointAtLength);
    traversalState.m_desiredLength = length;
    apply(&traversalState, pathLengthApplierFunction);
    ok = traversalState.m_success;
    return traversalState.m_current;
}
Esempio n. 4
0
float Path::normalAngleAtLength(float length, bool& ok) const
{
    PathTraversalState traversalState(PathTraversalState::TraversalNormalAngleAtLength);
    traversalState.m_desiredLength = length ? length : std::numeric_limits<float>::epsilon();
    apply(&traversalState, pathLengthApplierFunction);
    ok = traversalState.m_success;
    return traversalState.m_normalAngle;
}
Esempio n. 5
0
float Path::length() const
{
    PathTraversalState traversalState(PathTraversalState::Action::TotalLength);

    apply([&traversalState](const PathElement& element) {
        traversalState.processPathElement(element);
    });

    return traversalState.totalLength();
}
Esempio n. 6
0
PathTraversalState Path::traversalStateAtLength(float length, bool& success) const
{
    PathTraversalState traversalState(PathTraversalState::Action::VectorAtLength, length);

    apply([&traversalState](const PathElement& element) {
        traversalState.processPathElement(element);
    });

    success = traversalState.success();
    return traversalState;
}
bool getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream& stream, float length, unsigned& pathSeg)
{
    if (stream.isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::Action::SegmentAtLength);
    SVGPathTraversalStateBuilder builder(traversalState, length);

    SVGPathByteStreamSource source(stream);
    bool ok = SVGPathParser::parse(source, builder);
    pathSeg = builder.pathSegmentIndex();
    return ok;
}
bool getTotalLengthOfSVGPathByteStream(const SVGPathByteStream& stream, float& totalLength)
{
    if (stream.isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::Action::TotalLength);

    SVGPathTraversalStateBuilder builder(traversalState);

    SVGPathByteStreamSource source(stream);
    bool ok = SVGPathParser::parse(source, builder);
    totalLength = builder.totalLength();
    return ok;
}
bool getPointAtLengthOfSVGPathByteStream(const SVGPathByteStream& stream, float length, SVGPoint& point)
{
    if (stream.isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::Action::VectorAtLength);

    SVGPathTraversalStateBuilder builder(traversalState, length);

    SVGPathByteStreamSource source(stream);
    bool ok = SVGPathParser::parse(source, builder);
    point = builder.currentPoint();
    return ok;
}
unsigned SVGPathSegList::getPathSegAtLength(float)
{
    // FIXME : to be useful this will need to support non-normalized SVGPathSegLists
    ExceptionCode ec = 0;
    int len = numberOfItems();
    // FIXME: Eventually this will likely move to a "path applier"-like model, until then PathTraversalState is less useful as we could just use locals
    PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength);
    for (int i = 0; i < len; ++i) {
        SVGPathSeg* segment = getItem(i, ec).get();
        float segmentLength = 0;
        switch (segment->pathSegType()) {
        case SVGPathSeg::PATHSEG_MOVETO_ABS:
        {
            SVGPathSegMovetoAbs* moveTo = static_cast<SVGPathSegMovetoAbs*>(segment);
            segmentLength = traversalState.moveTo(FloatPoint(moveTo->x(), moveTo->y()));
            break;
        }
        case SVGPathSeg::PATHSEG_LINETO_ABS:
        {
            SVGPathSegLinetoAbs* lineTo = static_cast<SVGPathSegLinetoAbs*>(segment);
            segmentLength = traversalState.lineTo(FloatPoint(lineTo->x(), lineTo->y()));
            break;
        }
        case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS:
        {
            SVGPathSegCurvetoCubicAbs* curveTo = static_cast<SVGPathSegCurvetoCubicAbs*>(segment);
            segmentLength = traversalState.cubicBezierTo(FloatPoint(curveTo->x1(), curveTo->y1()),
                                      FloatPoint(curveTo->x2(), curveTo->y2()),
                                      FloatPoint(curveTo->x(), curveTo->y()));
            break;
        }
        case SVGPathSeg::PATHSEG_CLOSEPATH:
            segmentLength = traversalState.closeSubpath();
            break;
        default:
            ASSERT(false); // FIXME: This only works with normalized/processed path data.
            break;
        }
        traversalState.m_totalLength += segmentLength;
        if ((traversalState.m_action == PathTraversalState::TraversalSegmentAtLength)
            && (traversalState.m_totalLength > traversalState.m_desiredLength)) {
            return traversalState.m_segmentIndex;
        }
        traversalState.m_segmentIndex++;
    }
    
    return 0; // The SVG spec is unclear as to what to return when the distance is not on the path    
}
Esempio n. 11
0
bool SVGPathParserFactory::getSVGPathSegAtLengthFromSVGPathSegList(SVGPathSegList* pathSegList, float length, unsigned long& pathSeg)
{
    ASSERT(pathSegList);
    if (!pathSegList->numberOfItems())
        return false; 

    PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength);
    SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);

    OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(pathSegList);
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
    pathSeg = builder->pathSegmentIndex();
    parser->cleanup();
    return ok;
}
bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream* stream, float length, FloatPoint& point)
{
    ASSERT(stream);
    if (stream->isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::TraversalPointAtLength);
    SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);

    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
    point = builder->currentPoint();
    parser->cleanup();
    return ok;
}
bool SVGPathParserFactory::getTotalLengthOfSVGPathByteStream(SVGPathByteStream* stream, float& totalLength)
{
    ASSERT(stream);
    if (stream->isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::TraversalTotalLength);
    SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, 0);

    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
    totalLength = builder->totalLength();
    parser->cleanup();
    return ok;
}
bool SVGPathParserFactory::getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream* stream, float length, unsigned& pathSeg)
{
    ASSERT(stream);
    if (stream->isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength);
    SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);

    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
    pathSeg = builder->pathSegmentIndex();
    parser->cleanup();
    return ok;
}
Esempio n. 15
0
bool getTotalLengthOfSVGPathByteStream(const SVGPathByteStream* stream, float& totalLength)
{
    ASSERT(stream);
    if (stream->isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::TraversalTotalLength);
    SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, 0);

    SVGPathByteStreamSource source(stream);
    SVGPathParser* parser = globalSVGPathParser(&source, builder);
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
    totalLength = builder->totalLength();
    parser->cleanup();
    return ok;
}
Esempio n. 16
0
bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream* stream, float length, SVGPoint& point)
{
    ASSERT(stream);
    if (stream->isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::Action::VectorAtLength);
    SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);

    auto source = std::make_unique<SVGPathByteStreamSource>(stream);
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
    point = builder->currentPoint();
    parser->cleanup();
    return ok;
}
Esempio n. 17
0
bool getTotalLengthOfSVGPathByteStream(SVGPathByteStream* stream, float& totalLength)
{
    ASSERT(stream);
    if (stream->isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::Action::TotalLength);
    SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, 0);

    auto source = std::make_unique<SVGPathByteStreamSource>(stream);
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
    totalLength = builder->totalLength();
    parser->cleanup();
    return ok;
}
Esempio n. 18
0
bool getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream* stream, float length, unsigned& pathSeg)
{
    ASSERT(stream);
    if (stream->isEmpty())
        return false;

    PathTraversalState traversalState(PathTraversalState::Action::SegmentAtLength);
    SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);

    auto source = std::make_unique<SVGPathByteStreamSource>(stream);
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
    pathSeg = builder->pathSegmentIndex();
    parser->cleanup();
    return ok;
}
Esempio n. 19
0
float SVGPathQuery::getTotalLength() const
{
    SVGPathTraversalState traversalState(PathTraversalState::TraversalTotalLength);
    executeQuery(m_pathByteStream, traversalState);
    return traversalState.totalLength();
}
Esempio n. 20
0
float Path::length() const
{
    PathTraversalState traversalState(PathTraversalState::TraversalTotalLength);
    apply(&traversalState, pathLengthApplierFunction);
    return traversalState.m_totalLength;
}
Esempio n. 21
0
unsigned SVGPathQuery::getPathSegIndexAtLength(float length) const
{
    SVGPathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength, length);
    executeQuery(m_pathByteStream, traversalState);
    return traversalState.segmentIndex();
}
Esempio n. 22
0
FloatPoint SVGPathQuery::getPointAtLength(float length) const
{
    SVGPathTraversalState traversalState(PathTraversalState::TraversalPointAtLength, length);
    executeQuery(m_pathByteStream, traversalState);
    return traversalState.computedPoint();
}
Esempio n. 23
0
void SceneManager::_renderScene( SceneRenderState* state, U32 objectMask, SceneZoneSpace* baseObject, U32 baseZone )
{
   AssertFatal( this == gClientSceneGraph, "SceneManager::_buildSceneGraph - Only the client scenegraph can support this call!" );

   PROFILE_SCOPE( SceneGraph_batchRenderImages );

   // In the editor, override the type mask for diffuse passes.

   if( gEditingMission && state->isDiffusePass() )
      objectMask = EDITOR_RENDER_TYPEMASK;

   // Update the zoning state and traverse zones.

   if( getZoneManager() )
   {
      // Update.

      getZoneManager()->updateZoningState();

      // If zone culling isn't disabled, traverse the
      // zones now.

      if( !state->getCullingState().disableZoneCulling() )
      {
         // Find the start zone if we haven't already.

         if( !baseObject )
         {
            getZoneManager()->findZone( state->getCameraPosition(), baseObject, baseZone );
            AssertFatal( baseObject != NULL, "SceneManager::_renderScene - findZone() did not return an object" );
         }

         // Traverse zones starting in base object.

         SceneTraversalState traversalState( &state->getCullingState() );
         PROFILE_START( Scene_traverseZones );
         baseObject->traverseZones( &traversalState, baseZone );
         PROFILE_END();

         // Set the scene render box to the area we have traversed.

         state->setRenderArea( traversalState.getTraversedArea() );
      }
   }

   // Set the query box for the container query.  Never
   // make it larger than the frustum's AABB.  In the editor,
   // always query the full frustum as that gives objects
   // the opportunity to render editor visualizations even if
   // they are otherwise not in view.

   if( !state->getFrustum().getBounds().isOverlapped( state->getRenderArea() ) )
   {
      // This handles fringe cases like flying backwards into a zone where you
      // end up pretty much standing on a zone border and looking directly into
      // its "walls".  In that case the traversal area will be behind the frustum
      // (remember that the camera isn't where visibility starts, it's the near
      // distance).

      return;
   }

   Box3F queryBox = state->getFrustum().getBounds();
   if( !gEditingMission )
   {
      queryBox.minExtents.setMax( state->getRenderArea().minExtents );
      queryBox.maxExtents.setMin( state->getRenderArea().maxExtents );
   }

   PROFILE_START( Scene_cullObjects );

   //TODO: We should split the codepaths here based on whether the outdoor zone has visible space.
   //    If it has, we should use the container query-based path.
   //    If it hasn't, we should fill the object list directly from the zone lists which will usually
   //       include way fewer objects.
   
   // Gather all objects that intersect the scene render box.

   mBatchQueryList.clear();
   getContainer()->findObjectList( queryBox, objectMask, &mBatchQueryList );

   // Cull the list.

   U32 numRenderObjects = state->getCullingState().cullObjects(
      mBatchQueryList.address(),
      mBatchQueryList.size(),
      !state->isDiffusePass() ? SceneCullingState::CullEditorOverrides : 0 // Keep forced editor stuff out of non-diffuse passes.
   );

   //HACK: If the control object is a Player and it is not in the render list, force
   // it into it.  This really should be solved by collision bounds being separate from
   // object bounds; only because the Player class is using bounds not encompassing
   // the actual player object is it that we have this problem in the first place.
   // Note that we are forcing the player object into ALL passes here but such
   // is the power of proliferation of things done wrong.

   GameConnection* connection = GameConnection::getConnectionToServer();
   if( connection )
   {
      Player* player = dynamic_cast< Player* >( connection->getControlObject() );
      if( player )
      {
         mBatchQueryList.setSize( numRenderObjects );
         if( !mBatchQueryList.contains( player ) )
         {
            mBatchQueryList.push_back( player );
            numRenderObjects ++;
         }
      }
   }

   PROFILE_END();

   // Render the remaining objects.

   PROFILE_START( Scene_renderObjects );
   state->renderObjects( mBatchQueryList.address(), numRenderObjects );
   PROFILE_END();

   // Render bounding boxes, if enabled.

   if( smRenderBoundingBoxes && state->isDiffusePass() )
   {
      GFXDEBUGEVENT_SCOPE( Scene_renderBoundingBoxes, ColorI::WHITE );

      GameBase* cameraObject = 0;
      if( connection )
         cameraObject = connection->getCameraObject();

      GFXStateBlockDesc desc;
      desc.setFillModeWireframe();
      desc.setZReadWrite( true, false );

      for( U32 i = 0; i < numRenderObjects; ++ i )
      {
         SceneObject* object = mBatchQueryList[ i ];

         // Skip global bounds object.
         if( object->isGlobalBounds() )
            continue;

         // Skip camera object as we're viewing the scene from it.
         if( object == cameraObject )
            continue;

         const Box3F& worldBox = object->getWorldBox();
         GFX->getDrawUtil()->drawObjectBox(
            desc,
            Point3F( worldBox.len_x(), worldBox.len_y(), worldBox.len_z() ),
            worldBox.getCenter(),
            MatrixF::Identity,
            ColorI::WHITE
         );
      }
   }
}