void SimplePathGraph::read_old ( Iff & iff )
{
	clear();

	// ----------

	iff.enterChunk(TAG_PNOD);
	{
		FloorLocator loc;

		while(iff.getChunkLengthLeft())
		{
			loc.read_0000(iff);

			m_nodes->push_back( PathNode(loc.getPosition_p()) );
		}
	}
	iff.exitChunk(TAG_PNOD);

	iff.enterChunk(TAG_PEDG);
	{
		while(iff.getChunkLengthLeft())
		{
			int a = iff.read_int32();
			int b = iff.read_int32();

			m_edges->push_back( PathEdge(a,b) );
			m_edges->push_back( PathEdge(b,a) );
		}
	}
	iff.exitChunk(TAG_PEDG);

	// ----------

	buildIndexTables();

#ifdef _DEBUG

	if(ConfigSharedCollision::getBuildDebugData())
	{
		buildDebugData();
	}

#endif
}
//----------------------------- GetPath ------------------------------------
//
//  called by an agent after it has been notified that a search has terminated
//  successfully. The method extracts the path from m_pCurrentSearch, adds
//  additional edges appropriate to the search type and returns it as a list of
//  PathEdges.
//-----------------------------------------------------------------------------
CActor_PathPlanner::Path CActor_PathPlanner::GetPath()
{
  assert( m_pCurrentSearch && "<CActor_PathPlanner::GetPathAsNodes>: no current search" );

  Path path = m_pCurrentSearch->GetPathAsPathEdges();

  int closest = GetClosestNodeToPosition( m_pOwner->Pos() );

  path.push_front( PathEdge( m_pOwner->Pos(),
                             GetNodePosition( closest ),
                             NavGraphEdge::normal ) );

  //if the bot requested a path to a location then an edge leading to the
  //destination must be added
  if ( m_pCurrentSearch->GetType()
      == Graph_SearchTimeSliced < EdgeType >::AStar ) {

    int idx =
        m_pOwner->World()->GetCellSpace()->PositionToIndex( m_vDestinationPos );
    if ( invalid_node_index
        != m_pOwner->World()->GetNavGraph().GetNode( idx ).Index() ) {

      path.push_back( PathEdge( path.back().Destination(),
                                m_vDestinationPos,
                                NavGraphEdge::normal ) );
    }
  }

  //smooth paths if required
  if ( script->GetBool( "SmoothPathsQuick" ) ) {
    SmoothPathEdgesQuick( path );
  }

  if ( script->GetBool( "SmoothPathsPrecise" ) ) {
    SmoothPathEdgesPrecise( path );
  }

  return path;
}
//----------------------------- GetPath ------------------------------------
//
//  called by an agent after it has been notified that a search has terminated
//  successfully. The method extracts the path from m_pCurrentSearch, adds
//  additional edges appropriate to the search type and returns it as a list of
//  PathEdges.
//-----------------------------------------------------------------------------
Raven_PathPlanner::Path Raven_PathPlanner::GetPath()
{
  assert (m_pCurrentSearch && 
          "<Raven_PathPlanner::GetPathAsNodes>: no current search");

  Path path =  m_pCurrentSearch->GetPathAsPathEdges();

  int closest = GetClosestNodeToPosition(m_pOwner->Pos());

  path.push_front(PathEdge(m_pOwner->Pos(),
                            GetNodePosition(closest),
                            NavGraphEdge::normal));

  
  //if the bot requested a path to a location then an edge leading to the
  //destination must be added
  if (m_pCurrentSearch->GetType() == Graph_SearchTimeSliced<EdgeType>::AStar)
  {   
    path.push_back(PathEdge(path.back().Destination(),
                            m_vDestinationPos,
                            NavGraphEdge::normal));
  }

  //smooth paths if required
  if (UserOptions->m_bSmoothPathsQuick)
  {
    SmoothPathEdgesQuick(path);
  }

  if (UserOptions->m_bSmoothPathsPrecise)
  {
    SmoothPathEdgesPrecise(path);
  }

  return path;
}
Beispiel #4
0
bool PathVertex::sampleNextVertex(const TraceableScene &scene, TraceBase &tracer, TraceState &state, bool adjoint,
        PathVertex *prev, PathEdge *prevEdge, PathVertex &next, PathEdge &nextEdge)
{
    Vec3f weight;
    float pdf;

    switch (_type) {
    case EmitterVertex: {
        EmitterRecord &record = _record.emitter;

        if (_sampler.emitter->isInfinite()) {
            weight = record.point.weight;
            pdf = record.point.pdf;
        } else {
            if (!_sampler.emitter->sampleDirection(state.sampler, record.point, record.direction))
                return false;

            weight = record.direction.weight;
            pdf = record.direction.pdf;
        }

        state.ray = Ray(record.point.p, record.direction.d);
        break;
    } case CameraVertex: {
        CameraRecord &record = _record.camera;
        if (!_sampler.camera->sampleDirection(state.sampler, record.point, record.pixel, record.direction))
            return false;

        weight = record.direction.weight;
        pdf = record.direction.pdf;

        state.ray = Ray(record.point.p, record.direction.d);
        state.ray.setPrimaryRay(true);
        break;
    } case SurfaceVertex: {
        SurfaceRecord &record = _record.surface;

        if (record.info.primitive->isInfinite())
            return false;

        Vec3f scatterWeight(1.0f);
        Vec3f emission(0.0f);
        bool scattered = tracer.handleSurface(record.event, record.data, record.info,
                state.medium, state.bounce, adjoint, false, state.ray,
                scatterWeight, emission, state.wasSpecular, state.mediumState);
        if (!scattered)
            return false;

        if (record.event.sampledLobe.isForward())
            prev->_pdfBackward = record.event.pdf;
        else
            prev->_pdfBackward = _sampler.bsdf->pdf(record.event.makeFlippedQuery());
        _dirac = record.event.sampledLobe.isPureSpecular();
        _forward = record.event.sampledLobe.isForward();
        // Technically, we could connect to these kinds of vertices (e.g. BSDF with transparency),
        // but this creates so much headache for back-propagating the PDFs that we're just not
        // going to bother
        if (_forward)
            _connectable = false;
        weight = record.event.weight;
        pdf = record.event.pdf;

        break;
    } case MediumVertex: {
        MediumRecord &record = _record.medium;

        if (!record.mediumSample.phase->sample(state.sampler, state.ray.dir(), record.phaseSample))
            return false;

        prev->_pdfBackward = record.mediumSample.phase->pdf(-record.phaseSample.w, -state.ray.dir());

        state.ray = state.ray.scatter(record.mediumSample.p, record.phaseSample.w, 0.0f);
        state.ray.setPrimaryRay(false);

        weight = record.phaseSample.weight;
        pdf = record.phaseSample.pdf;

        break;
    } default:
        return false;
    }

    SurfaceRecord surfaceRecord;
    bool didHit = scene.intersect(state.ray, surfaceRecord.data, surfaceRecord.info);

    bool hitSurface;
    float edgePdfForward;
    float edgePdfBackward;
    MediumRecord mediumRecord;
    if (state.medium) {
        if (!state.medium->sampleDistance(state.sampler, state.ray, state.mediumState, mediumRecord.mediumSample))
            return false;
        if (mediumRecord.mediumSample.t < 1e-6f)
            return false;
        hitSurface = mediumRecord.mediumSample.exited;
        edgePdfForward = mediumRecord.mediumSample.pdf;
        Ray reverseRay(mediumRecord.mediumSample.p, -state.ray.dir(), 0.0f, mediumRecord.mediumSample.t);
        edgePdfBackward = state.medium->pdf(state.sampler, reverseRay, onSurface());
        weight *= mediumRecord.mediumSample.weight;
        if (hitSurface && !didHit)
            return false;
    } else {
        hitSurface = true;
        edgePdfForward = 1.0f;
        edgePdfBackward = 1.0f;
    }

    if (!hitSurface) {
        mediumRecord.wi = state.ray.dir();
        next = PathVertex(mediumRecord.mediumSample.phase, mediumRecord, _throughput*weight);
        next._medium = state.medium;
        state.bounce++;
        nextEdge = PathEdge(*this, next, edgePdfForward, edgePdfBackward);
        next._pdfForward = pdf;

        return true;
    } else if (didHit) {
        surfaceRecord.event = tracer.makeLocalScatterEvent(surfaceRecord.data, surfaceRecord.info, state.ray, &state.sampler);

        next = PathVertex(surfaceRecord.info.bsdf, surfaceRecord, _throughput*weight);
        next._medium = state.medium;
        next.pointerFixup();
        state.bounce++;
        nextEdge = PathEdge(*this, next, edgePdfForward, edgePdfBackward);
        next._pdfForward = pdf;

        return true;
    } else if (!adjoint && scene.intersectInfinites(state.ray, surfaceRecord.data, surfaceRecord.info)) {
        next = PathVertex(surfaceRecord.info.bsdf, surfaceRecord, _throughput*weight);
        next._medium = state.medium;
        state.bounce++;
        nextEdge = PathEdge(state.ray.dir(), 1.0f, 1.0f, edgePdfForward, edgePdfBackward);
        next._pdfForward = pdf;

        return true;
    } else {
        return false;
    }
}