示例#1
0
/**
 * Parses Options and OZs from See You task file
 * @param reader.  Points to first line of task after task "Waypoint list" line
 * @param task_info Loads this with CU task options info
 * @param turnpoint_infos Loads this with CU task tp info
 */
static void
ParseCUTaskDetails(FileLineReader &reader, SeeYouTaskInformation *task_info,
                   SeeYouTurnpointInformation turnpoint_infos[])
{
  // Read options/observation zones
  TCHAR params_buffer[1024];
  const TCHAR *params[20];
  TCHAR *line;
  int TPIndex = 0;
  const unsigned int max_params = ARRAY_SIZE(params);
  while ((line = reader.ReadLine()) != nullptr &&
         line[0] != _T('\"') && line[0] != _T(',')) {
    const size_t n_params = ExtractParameters(line, params_buffer,
                                              params, max_params, true);

    if (StringIsEqual(params[0], _T("Options"))) {
      // Options line found
      ParseOptions(task_info, params, n_params);

    } else if (StringIsEqual(params[0], _T("ObsZone"), 7)) {
      // Observation zone line found
      if (_tcslen(params[0]) <= 8)
        continue;

      TPIndex = ParseOZs(turnpoint_infos, params, n_params);
      if (TPIndex == 0)
        task_info->max_start_altitude = turnpoint_infos[TPIndex].max_altitude;
    }
  } // end while
}
示例#2
0
bool
WaypointReaderOzi::ParseLine(const TCHAR *line, Waypoints &way_points)
{
  if (line[0] == '\0')
    return true;

  // Ignore first four header lines
  if (ignore_lines > 0) {
    --ignore_lines;
    return true;
  }

  TCHAR ctemp[255];
  const TCHAR *params[20];
  static constexpr unsigned int max_params = ARRAY_SIZE(params);
  size_t n_params;

  if (_tcslen(line) >= ARRAY_SIZE(ctemp))
    /* line too long for buffer */
    return false;

  // Get fields
  n_params = ExtractParameters(line, ctemp, params, max_params, true, _T('"'));

  // Check if the basic fields are provided
  if (n_params < 15)
    return false;

  GeoPoint location;
  // Latitude (e.g. 5115.900N)
  if (!ParseAngle(params[2], location.latitude))
    return false;

  // Longitude (e.g. 00715.900W)
  if (!ParseAngle(params[3], location.longitude))
    return false;

  location.Normalize(); // ensure longitude is within -180:180

  Waypoint new_waypoint = factory.Create(location);

  long value;
  new_waypoint.original_id = (ParseNumber(params[0], value) ? value : 0);

  if (!ParseString(params[1], new_waypoint.name))
    return false;

  if (ParseNumber(params[14], value) && value != -777)
    new_waypoint.elevation = Units::ToSysUnit(value, Unit::FEET);
  else if (!factory.FallbackElevation(new_waypoint))
    return false;

  // Description (Characters 35-44)
  ParseString(params[11], new_waypoint.comment);

  way_points.Append(std::move(new_waypoint));
  return true;
}
示例#3
0
/*
 * Same as ExtractParameters, but also validate the length of
 * the string and the NMEA checksum.
 */
size_t NMEAParser::ValidateAndExtract(const TCHAR *src, TCHAR *dst, size_t dstsz, TCHAR **arr, size_t arrsz)
{
  int len = _tcslen(src);

  if (len <= 6 || len >= (int) dstsz)
    return 0;
  if (!NMEAChecksum(src))
    return 0;

  return ExtractParameters(src, dst, arr, arrsz);
}
示例#4
0
        // Create blocks from tags.
        void PopulateBlocks(const std::vector<RichTextTag>& tags)
        {
            // Create blocks using factories.
            for (const RichTextTag& tag : tags) {
                RichText::TAG_PARAMS params;
                // Extract the parameters from params_string to the tag_params map.
                ExtractParameters(tag.tag_params, params);

                BlockControl* block = FactoryMap()[tag.tag]->CreateFromTag(tag.tag, params, tag.content, m_font, m_color, m_format);
                if (block) {
                    m_owner->AttachChild(block);
                    m_blocks.push_back(block);
                }
            }

            DoLayout();
        }
示例#5
0
bool
WaypointReaderSeeYou::ParseLine(const TCHAR* line, Waypoints &waypoints)
{
  enum {
    iName = 0,
    iLatitude = 3,
    iLongitude = 4,
    iElevation = 5,
    iStyle = 6,
    iRWDir = 7,
    iRWLen = 8,
    iFrequency = 9,
    iDescription = 10,
  };

  if (first) {
    first = false;

    /* skip first line if it doesn't begin with a quotation character
       (usually the field order line) */
    if (line[0] != _T('\"'))
      return true;
  }

  // If (end-of-file or comment)
  if (StringIsEmpty(line) ||
      StringStartsWith(line, _T("*")))
    // -> return without error condition
    return true;

  TCHAR ctemp[4096];
  if (_tcslen(line) >= ARRAY_SIZE(ctemp))
    /* line too long for buffer */
    return false;

  // If task marker is reached ignore all following lines
  if (StringStartsWith(line, _T("-----Related Tasks-----")))
    ignore_following = true;
  if (ignore_following)
    return true;

  // Get fields
  const TCHAR *params[20];
  size_t n_params = ExtractParameters(line, ctemp, params,
                                      ARRAY_SIZE(params), true, _T('"'));

  // Check if the basic fields are provided
  if (iName >= n_params ||
      iLatitude >= n_params ||
      iLongitude >= n_params)
    return false;

  GeoPoint location;

  // Latitude (e.g. 5115.900N)
  if (!ParseAngle(params[iLatitude], location.latitude, true))
    return false;

  // Longitude (e.g. 00715.900W)
  if (!ParseAngle(params[iLongitude], location.longitude, false))
    return false;

  location.Normalize(); // ensure longitude is within -180:180

  Waypoint new_waypoint = factory.Create(location);

  // Name (e.g. "Some Turnpoint")
  if (*params[iName] == _T('\0'))
    return false;
  new_waypoint.name = params[iName];

  // Elevation (e.g. 458.0m)
  /// @todo configurable behaviour
  if ((iElevation >= n_params ||
      !ParseAltitude(params[iElevation], new_waypoint.elevation)) &&
      !factory.FallbackElevation(new_waypoint))
    return false;

  // Style (e.g. 5)
  if (iStyle < n_params)
    ParseStyle(params[iStyle], new_waypoint.type);

  new_waypoint.flags.turn_point = true;

  // Frequency & runway direction/length (for airports and landables)
  // and description (e.g. "Some Description")
  if (new_waypoint.IsLandable()) {
    if (iFrequency < n_params)
      new_waypoint.radio_frequency = RadioFrequency::Parse(params[iFrequency]);

    // Runway length (e.g. 546.0m)
    double rwlen = -1;
    if (iRWLen < n_params && ParseDistance(params[iRWLen], rwlen) &&
        rwlen > 0)
      new_waypoint.runway.SetLength(uround(rwlen));

    if (iRWDir < n_params && *params[iRWDir]) {
      TCHAR *end;
      int direction =_tcstol(params[iRWDir], &end, 10);
      if (end == params[iRWDir] || direction < 0 || direction > 360 ||
          (direction == 0 && rwlen <= 0))
        direction = -1;
      else if (direction == 360)
        direction = 0;
      if (direction >= 0)
        new_waypoint.runway.SetDirectionDegrees(direction);
    }
  }

  if (iDescription < n_params) {
    /*
     * This convention was introduced by the OpenAIP
     * project (http://www.openaip.net/), since no waypoint type
     * exists for thermal hotspots.
     */
    if (StringStartsWith(params[iDescription], _T("Hotspot")))
      new_waypoint.type = Waypoint::Type::THERMAL_HOTSPOT;

    new_waypoint.comment = params[iDescription];
  }

  waypoints.Append(std::move(new_waypoint));
  return true;
}
示例#6
0
bool
WaypointReaderWinPilot::ParseLine(const TCHAR *line, Waypoints &waypoints)
{
  TCHAR ctemp[4096];
  const TCHAR *params[20];
  static constexpr unsigned int max_params = ARRAY_SIZE(params);
  size_t n_params;

  // If (end-of-file)
  if (line[0] == '\0')
    // -> return without error condition
    return true;

  // If comment
  if (line[0] == _T('*')) {
    if (first) {
      first = false;
      welt2000_format = (_tcsstr(line, _T("WRITTEN BY WELT2000")) != nullptr);
    }

    // -> return without error condition
    return true;
  }

  if (_tcslen(line) >= ARRAY_SIZE(ctemp))
    /* line too long for buffer */
    return false;

  GeoPoint location;

  // Get fields
  n_params = ExtractParameters(line, ctemp, params, max_params, true);
  if (n_params < 6)
    return false;

  // Latitude (e.g. 51:15.900N)
  if (!ParseAngle(params[1], location.latitude, true))
    return false;

  // Longitude (e.g. 00715.900W)
  if (!ParseAngle(params[2], location.longitude, false))
    return false;
  location.Normalize(); // ensure longitude is within -180:180

  Waypoint new_waypoint = factory.Create(location);

  // Name (e.g. KAMPLI)
  if (*params[5] == _T('\0'))
    return false;
  new_waypoint.name=params[5];

  // Altitude (e.g. 458M)
  /// @todo configurable behaviour
  if (!ParseAltitude(params[3], new_waypoint.elevation) &&
      !factory.FallbackElevation(new_waypoint))
    return false;

  if (n_params > 6) {
    // Description (e.g. 119.750 Airport)
    new_waypoint.comment=params[6];
    if (welt2000_format)
      ParseRunwayDirection(params[6], new_waypoint.runway);
  }

  // Waypoint Flags (e.g. AT)
  ParseFlags(params[4], new_waypoint);

  waypoints.Append(std::move(new_waypoint));
  return true;
}
示例#7
0
VOID CRenoCommandFrame::OnReceive(INT nErrorCode,LPSTR buffer,ULONG received)
{
	// TODO Write better error handling code here, maybe we do not have to panic on every error code
	if(nErrorCode)
	{
		// Write the error message
		PrintFormat(TEXT("* Error occurred during receive. Error code %d\r\n"),nErrorCode);

		// Make sure we disconnect
		CRenoCommandFrame::OnReceive(nErrorCode,buffer,received);

		return;
	}

	ASSERT(buffer);

	// Get the size of the translate buffer
	INT messageSize = MultiByteToWideChar(CP_UTF8,NULL,buffer,received,NULL,NULL);

	// Create the buffer that will hold the translated message
	LPTSTR message = new TCHAR[messageSize + 1];
	ASSERT(message);

	// Translate the buffer
	messageSize = MultiByteToWideChar(CP_UTF8,NULL,buffer,received,message,messageSize);

	// Terminate the buffer
	message[messageSize] = NULL;

	CStringPtrArray messageElements;

	// Split the message buffer into individual messages
	SplitMessage(message,messageElements);

	// Do not need the translated buffer anymore
	delete[] message;

	// Process output
	for(LONG i = 0; i < messageElements.GetCount(); ++i)
	{
		// TODO Remove any unsupported characters
		//for(LONG j = 0; j < messageElements[i].GetLength(); ++j)
		//	if(!_ismbcprint(messageElements[i].GetAt(j)))
		//		messageElements[i].SetAt(j,TEXT('\v'));

		// Process the message element
		ULONG position = 0;

		CString prefix;

		// Is there a prefix
		if(messageElements[i].GetAt(0) == TEXT(':'))
		{
			// Extract the prefix
			prefix = messageElements[i].Mid(1, messageElements[i].Find(TEXT(' ')) - 1);
			position += prefix.GetLength() + 2;
		}

		CString command;

		// Are there any parameters after the command
		if(messageElements[i].Find(TEXT(' '), position))
		{
			// Extract the command
			command = messageElements[i].Mid(position, messageElements[i].Find(TEXT(' '), position) - position);
			position += command.GetLength() + 1;
		}
		else
		{
			// The whole element is just a command
			command = messageElements[i].Mid(position);
			position += command.GetLength();
		}

		CStringPtrArray parameterElements;

		// Extract parameters
		ExtractParameters(messageElements[i].GetBuffer() + position, parameterElements);

		// Find the reply handler
		const RENO_REPLY* replyMap = GetReplyMap();
		ASSERT(replyMap);

		for(ULONG j = 0; replyMap[j].command ; ++j)
		{
			if(!_wcsicmp(replyMap[j].command,command) || !_wcsicmp(replyMap[j].command,TEXT("*")))
			{
				// Execute the handler and stop further searching
				(this->*replyMap[j].handler)(prefix,command,parameterElements);
				break;
			}
		}
	}
}
示例#8
0
bool
WaypointReaderSeeYou::ParseLine(const TCHAR* line, const unsigned linenum,
                              Waypoints &waypoints)
{
  enum {
    iName = 0,
    iLatitude = 3,
    iLongitude = 4,
    iElevation = 5,
    iStyle = 6,
    iRWDir = 7,
    iRWLen = 8,
    iFrequency = 9,
    iDescription = 10,
  };

  if (linenum == 0)
    ignore_following = false;

  // If (end-of-file or comment)
  if (StringIsEmpty(line) ||
      StringStartsWith(line, _T("**")) ||
      StringStartsWith(line, _T("*")))
    // -> return without error condition
    return true;

  TCHAR ctemp[4096];
  if (_tcslen(line) >= ARRAY_SIZE(ctemp))
    /* line too long for buffer */
    return false;

  // Skip first line if it doesn't begin with a quotation character
  // (usually the field order line)
  if (linenum == 0 && line[0] != _T('\"'))
    return true;

  // If task marker is reached ignore all following lines
  if (_tcsstr(line, _T("-----Related Tasks-----")) == line)
    ignore_following = true;
  if (ignore_following)
    return true;

  // Get fields
  const TCHAR *params[20];
  size_t n_params = ExtractParameters(line, ctemp, params,
                                      ARRAY_SIZE(params), true, _T('"'));

  // Check if the basic fields are provided
  if (iName >= n_params ||
      iLatitude >= n_params ||
      iLongitude >= n_params)
    return false;

  Waypoint new_waypoint;

  // Latitude (e.g. 5115.900N)
  if (!ParseAngle(params[iLatitude], new_waypoint.location.latitude, true))
    return false;

  // Longitude (e.g. 00715.900W)
  if (!ParseAngle(params[iLongitude], new_waypoint.location.longitude, false))
    return false;

  new_waypoint.location.Normalize(); // ensure longitude is within -180:180

  new_waypoint.file_num = file_num;
  new_waypoint.original_id = 0;

  // Name (e.g. "Some Turnpoint")
  if (*params[iName] == _T('\0'))
    return false;
  new_waypoint.name = params[iName];

  // Elevation (e.g. 458.0m)
  /// @todo configurable behaviour
  if ((iElevation >= n_params ||
      !ParseAltitude(params[iElevation], new_waypoint.elevation)) &&
      !CheckAltitude(new_waypoint))
    return false;

  // Style (e.g. 5)
  if (iStyle < n_params)
    ParseStyle(params[iStyle], new_waypoint.type);

  new_waypoint.flags.turn_point = true;

  // Frequency & runway direction/length (for airports and landables)
  // and description (e.g. "Some Description")
  if (new_waypoint.IsLandable()) {
    if (iFrequency < n_params)
      new_waypoint.radio_frequency = RadioFrequency::Parse(params[iFrequency]);

    // Runway length (e.g. 546.0m)
    fixed rwlen = fixed_minus_one;
    if (iRWLen < n_params && ParseDistance(params[iRWLen], rwlen) &&
        positive(rwlen))
      new_waypoint.runway.SetLength(uround(rwlen));

    if (iRWDir < n_params && *params[iRWDir]) {
      TCHAR *end;
      int direction =_tcstol(params[iRWDir], &end, 10);
      if (end == params[iRWDir] || direction < 0 || direction > 360 ||
          (direction == 0 && !positive(rwlen)))
        direction = -1;
      else if (direction == 360)
        direction = 0;
      if (direction >= 0)
        new_waypoint.runway.SetDirectionDegrees(direction);
    }
  }

  if (iDescription < n_params)
    new_waypoint.comment = params[iDescription];

  waypoints.Append(new_waypoint);
  return true;
}
static void
TestExtractParameters()
{
    TCHAR buffer[1024];
    const TCHAR *params[64];
    unsigned n;

    // test basic functionality

    n = ExtractParameters(_T(""), buffer, params, 64);
    ok1(n == 1);
    ok1(StringIsEqual(params[0], _T("")));

    n = ExtractParameters(_T("foo"), buffer, params, 64);
    ok1(n == 1);
    ok1(StringIsEqual(params[0], _T("foo")));

    n = ExtractParameters(_T("foo,bar"), buffer, params, 64);
    ok1(n == 2);
    ok1(StringIsEqual(params[0], _T("foo")));
    ok1(StringIsEqual(params[1], _T("bar")));

    n = ExtractParameters(_T("foo,bar"), buffer, params, 1);
    ok1(n == 1);
    ok1(StringIsEqual(params[0], _T("foo")));

    n = ExtractParameters(_T("foo,bar,"), buffer, params, 64);
    ok1(n == 3);
    ok1(StringIsEqual(params[0], _T("foo")));
    ok1(StringIsEqual(params[1], _T("bar")));
    ok1(StringIsEqual(params[2], _T("")));

    n = ExtractParameters(_T("foo,bar,,"), buffer, params, 64);
    ok1(n == 4);
    ok1(StringIsEqual(params[0], _T("foo")));
    ok1(StringIsEqual(params[1], _T("bar")));
    ok1(StringIsEqual(params[2], _T("")));
    ok1(StringIsEqual(params[3], _T("")));


    // with qoutes but no quote handling

    n = ExtractParameters(_T("\"foo,comma\",\"bar\""), buffer, params, 64);
    ok1(n == 3);
    ok1(StringIsEqual(params[0], _T("\"foo")));
    ok1(StringIsEqual(params[1], _T("comma\"")));
    ok1(StringIsEqual(params[2], _T("\"bar\"")));


    // quote handling

    n = ExtractParameters(_T("\"\""),
                          buffer, params, 64, false, _T('"'));
    ok1(n == 1);
    ok1(StringIsEqual(params[0], _T("")));

    n = ExtractParameters(_T("\"\"\""),
                          buffer, params, 64, false, _T('"'));
    ok1(n == 1);
    ok1(StringIsEqual(params[0], _T("\"")));

    n = ExtractParameters(_T("\"\"\"\""),
                          buffer, params, 64, false, _T('"'));
    ok1(n == 1);
    ok1(StringIsEqual(params[0], _T("\"")));

    n = ExtractParameters(_T("\"foo,comma\",\"bar\""),
                          buffer, params, 64, false, _T('"'));
    ok1(n == 2);
    ok1(StringIsEqual(params[0], _T("foo,comma")));
    ok1(StringIsEqual(params[1], _T("bar")));


    // no quotes, whitespace removal

    n = ExtractParameters(_T("foo bar"), buffer, params, 64, true);
    ok1(n == 1);
    ok1(StringIsEqual(params[0], _T("foo bar")));

    n = ExtractParameters(_T("foo , bar, baz"), buffer, params, 64, true);
    ok1(n == 3);
    ok1(StringIsEqual(params[0], _T("foo")));
    ok1(StringIsEqual(params[1], _T("bar")));
    ok1(StringIsEqual(params[2], _T("baz")));

    n = ExtractParameters(_T(" foo  ,  bar  , baz "), buffer, params, 64, true);
    ok1(n == 3);
    ok1(StringIsEqual(params[0], _T("foo")));
    ok1(StringIsEqual(params[1], _T("bar")));
    ok1(StringIsEqual(params[2], _T("baz")));

    n = ExtractParameters(_T(" foo\"  , \" bar \"  , \"baz "),
                          buffer, params, 64, true);
    ok1(n == 3);
    ok1(StringIsEqual(params[0], _T("foo\"")));
    ok1(StringIsEqual(params[1], _T("\" bar \"")));
    ok1(StringIsEqual(params[2], _T("\"baz")));

    // quote handling, whitespace removal

    n = ExtractParameters(_T("\"foo \" , \" bar\", \" baz\""),
                          buffer, params, 64, true, _T('"'));
    ok1(n == 3);
    ok1(StringIsEqual(params[0], _T("foo ")));
    ok1(StringIsEqual(params[1], _T(" bar")));
    ok1(StringIsEqual(params[2], _T(" baz")));

    n = ExtractParameters(_T(" \" foo  \"  ,  \"  bar  \"  , \" baz \" "),
                          buffer, params, 64, true, _T('"'));
    ok1(n == 3);
    ok1(StringIsEqual(params[0], _T(" foo  ")));
    ok1(StringIsEqual(params[1], _T("  bar  ")));
    ok1(StringIsEqual(params[2], _T(" baz ")));

    n = ExtractParameters(_T("\"foo\",\"\",\"bar\""), buffer, params, 64,
                          true, _T('"'));
    ok1(n == 3);
    ok1(StringIsEqual(params[0], _T("foo")));
    ok1(StringIsEqual(params[1], _T("")));
    ok1(StringIsEqual(params[2], _T("bar")));

    // missing end quote
    n = ExtractParameters(_T("\"foo, bar"), buffer, params, 64,
                          true, _T('"'));
    ok1(n == 1);
    ok1(StringIsEqual(params[0], _T("foo, bar")));

    // embedded quotes and commas
    n = ExtractParameters(_T("\"foo, \"bar\"\""), buffer, params, 64,
                          true, _T('"'));
    ok1(n == 1);
    ok1(StringIsEqual(params[0], _T("foo, \"bar\"")));

    n = ExtractParameters(_T("\"foo, \"\"bar\"\"\""), buffer, params, 64,
                          true, _T('"'));
    ok1(n == 1);
    ok1(StringIsEqual(params[0], _T("foo, \"bar\"")));
}
示例#10
0
OrderedTask*
TaskFileSeeYou::GetTask(const TaskBehaviour &task_behaviour,
                        const Waypoints *waypoints, unsigned index) const
{
  // Create FileReader for reading the task
  FileLineReader reader(path, IgnoreError(), Charset::AUTO);
  if (reader.error())
    return nullptr;

  // Read waypoints from the CUP file
  Waypoints file_waypoints;
  {
    const WaypointFactory factory(WaypointOrigin::NONE);
    WaypointReaderSeeYou waypoint_file(factory);
    NullOperationEnvironment operation;
    waypoint_file.Parse(file_waypoints, reader, operation);
  }
  file_waypoints.Optimise();

  if (!reader.Rewind())
    return nullptr;

  TCHAR *line = AdvanceReaderToTask(reader, index);
  if (line == nullptr)
    return nullptr;

  // Read waypoint list
  // e.g. "Club day 4 Racing task","085PRI","083BOJ","170D_K","065SKY","0844YY", "0844YY"
  //       TASK NAME              , TAKEOFF, START  , TP1    , TP2    , FINISH ,  LANDING
  TCHAR waypoints_buffer[1024];
  const TCHAR *wps[30];
  size_t n_waypoints = ExtractParameters(line, waypoints_buffer, wps, 30,
                                         true, _T('"'));

  // Some versions of StrePla append a trailing ',' without a following
  // WP name resulting an empty last entry. Remove it from the results
  if (n_waypoints > 0 && wps[n_waypoints - 1][0] == _T('\0'))
    n_waypoints --;

  // At least taskname and takeoff, start, finish and landing points are needed
  if (n_waypoints < 5)
    return nullptr;

  // Remove taskname, start point and landing point from count
  n_waypoints -= 3;

  SeeYouTaskInformation task_info;
  SeeYouTurnpointInformation turnpoint_infos[30];
  WaypointPtr waypoints_in_task[30];

  ParseCUTaskDetails(reader, &task_info, turnpoint_infos);

  OrderedTask *task = new OrderedTask(task_behaviour);
  task->SetFactory(task_info.wp_dis ?
                    TaskFactoryType::RACING : TaskFactoryType::AAT);
  AbstractTaskFactory& fact = task->GetFactory();
  const TaskFactoryType factType = task->GetFactoryType();

  OrderedTaskSettings beh = task->GetOrderedTaskSettings();
  if (factType == TaskFactoryType::AAT) {
    beh.aat_min_time = task_info.task_time;
  }
  if (factType == TaskFactoryType::AAT ||
      factType == TaskFactoryType::RACING) {
    beh.start_constraints.max_height = (unsigned)task_info.max_start_altitude;
    beh.start_constraints.max_height_ref = AltitudeReference::MSL;
  }
  task->SetOrderedTaskSettings(beh);

  // mark task waypoints.  Skip takeoff and landing point
  for (unsigned i = 0; i < n_waypoints; i++) {
    auto file_wp = file_waypoints.LookupName(wps[i + 2]);
    if (file_wp == nullptr)
      return nullptr;

    // Try to find waypoint by name
    auto wp = waypoints->LookupName(file_wp->name);

    // If waypoint by name found and closer than 10m to the original
    if (wp != nullptr &&
        wp->location.DistanceS(file_wp->location) <= fixed(10)) {
      // Use this waypoint for the task
      waypoints_in_task[i] = wp;
      continue;
    }

    // Try finding the closest waypoint to the original one
    wp = waypoints->GetNearest(file_wp->location, fixed(10));

    // If closest waypoint found and closer than 10m to the original
    if (wp != nullptr &&
        wp->location.DistanceS(file_wp->location) <= fixed(10)) {
      // Use this waypoint for the task
      waypoints_in_task[i] = wp;
      continue;
    }

    // Use the original waypoint
    waypoints_in_task[i] = file_wp;
  }

  //now create TPs and OZs
  for (unsigned i = 0; i < n_waypoints; i++) {

    ObservationZonePoint* oz = CreateOZ(turnpoint_infos[i], i, n_waypoints,
                                        waypoints_in_task, factType);
    assert(waypoints_in_task[i]);
    OrderedTaskPoint *pt = CreatePoint(i, n_waypoints,
                                       WaypointPtr(waypoints_in_task[i]),
                                       fact, oz, factType);

    if (pt != nullptr)
      fact.Append(*pt, false);

    delete pt;
  }
  return task;
}
示例#11
0
//*********************************************************************************
// Read OBJ file from disk
//
SCENE *ReadOBJFile(const char *sFileName, bool bGenerateMissingNormals)
{
	FILE *pScene;
	char pcLine[512], pcMaterialLib[MAX_PATH], pcMaterialName[64];
	const char *pcArgs;
	TAG_NAME Tag;
	SCENE *pS = NULL;
	unsigned int i, j;
	float fL;
	VERTEX FaceCenter, AB, AC, N;

	//--- Check parameters

	if (!sFileName)
		return(NULL);

	//--- Open scene file

	//pScene = fopen(sFileName, "r");

	fopen_s(&pScene, sFileName, "r");

	if (!pScene)
		return(NULL);

	//--- Create scene object

	pS = new SCENE;
	if (!pS)
		goto Exit;

	pS->pObjects = NULL;
	pS->u32ObjectsCount = 0;

	pS->pVertices = NULL;
	pS->u32VerticesCount = 0;
		
	pS->pNormals = NULL;
	pS->u32NormalsCount = 0;

	pS->pUV = NULL;
	pS->u32UVCount = 0;

	pS->pFaces = NULL;
	pS->u32FacesCount = 0;

	pS->pMaterials = NULL;
	pS->u32MaterialsCount = 0;

	//--- Parse scene file, first pass

	while (fgets(pcLine, sizeof(pcLine), pScene))
	{
		//--- Parse file line

		pcArgs = TokenizeFileLine(pcLine, &Tag);

		//--- Process file line

		switch (Tag)
		{
		case TAGNAME_VERTEX:
			//--- Count vertex

			++pS->u32VerticesCount;
			break;

		case TAGNAME_NORMAL:
			//--- Count normal

			++pS->u32NormalsCount;
			break;

		case TAGNAME_TEXTURECOORDS:
			//--- Count UV pair

			++pS->u32UVCount;
			break;

		case TAGNAME_FACE3:
			//--- Count face

			++pS->u32FacesCount;
			break;

		case TAGNAME_FACE4:
			//--- Count 2 faces

			pS->u32FacesCount += 2;
			break;

		case TAGNAME_OBJECT:
			//--- Count object

			++pS->u32ObjectsCount;
			break;

		case TAGNAME_MATLIB:
			//--- Parse materials library

			ExtractParameters(Tag, pcArgs, pcMaterialLib);
			ParseMaterialLibrary(pS, sFileName, pcMaterialLib, TRUE);
			break;
		}
	}

	if (!pS->u32VerticesCount || !pS->u32FacesCount)
	{
		ReleaseScene(pS);
		pS = NULL;
		goto Exit;
	}

	//--- Allocate scene buffers

	if (bGenerateMissingNormals && (pS->u32NormalsCount == 0))
		pS->u32NormalsCount = pS->u32VerticesCount;
	else
		bGenerateMissingNormals = false;
	
	pS->pVertices = new VERTEX[pS->u32VerticesCount + pS->u32NormalsCount];
	if (!pS->pVertices)
	{
		ReleaseScene(pS);
		pS = NULL;
		goto Exit;
	}

	if (pS->u32NormalsCount)
		pS->pNormals = pS->pVertices + pS->u32VerticesCount;
	else
		pS->pNormals = NULL;

	if (pS->u32UVCount)
	{
		pS->pUV = new TEXTURE_COORDS[pS->u32UVCount];
		if (!pS->pUV)
		{
			ReleaseScene(pS);
			pS = NULL;
			goto Exit;
		}
	}

	pS->pFaces = new FACE[pS->u32FacesCount];
	if (!pS->pFaces)
	{
		ReleaseScene(pS);
		pS = NULL;
		goto Exit;
	}

	pS->pMaterials = new MATERIAL[pS->u32MaterialsCount];
	if (!pS->pMaterials)
	{
		ReleaseScene(pS);
		pS = NULL;
		goto Exit;
	}
	memset(pS->pMaterials, 0, sizeof(MATERIAL)*pS->u32MaterialsCount);

	//--- Init objects table

	pS->pObjects = new OBJECT[pS->u32ObjectsCount+1];
	if (!pS->pObjects)
	{
		ReleaseScene(pS);
		pS = NULL;
		goto Exit;
	}

	pS->pObjects[0].u32FirstFace = 0;
	pS->pObjects[0].u32FacesCount = 0;
	pS->pObjects[0].u32Material = 0xFFFFFFFF;

	for (i=0; i<=pS->u32ObjectsCount; ++i)
	{
		memset(&pS->pObjects[i].Center, 0, sizeof(pS->pObjects[i].Center));

		memset(pS->pObjects[i].pfMatrix, 0, sizeof(pS->pObjects[i].pfMatrix));
		pS->pObjects[i].pfMatrix[0] = pS->pObjects[i].pfMatrix[5] = pS->pObjects[i].pfMatrix[10] = pS->pObjects[i].pfMatrix[15] = 1;
	}

	//--- Reparse scene file

	pS->u32VerticesCount = pS->u32NormalsCount = pS->u32UVCount = pS->u32FacesCount = pS->u32ObjectsCount = pS->u32MaterialsCount = 0;

	fseek(pScene, 0, SEEK_SET);
	while (fgets(pcLine, sizeof(pcLine), pScene))
	{
		//--- Parse file line

		pcArgs = TokenizeFileLine(pcLine, &Tag);

		//--- Process file line

		switch (Tag)
		{
		case TAGNAME_VERTEX:
			//--- Retrieve vertex position

			ExtractParameters(Tag, pcArgs, &pS->pVertices[pS->u32VerticesCount++]);
			break;

		case TAGNAME_NORMAL:
			//--- Retrieve vertex normal

			ExtractParameters(Tag, pcArgs, &pS->pNormals[pS->u32NormalsCount++]);
			break;

		case TAGNAME_TEXTURECOORDS:
			//--- Retrieve UV coordinates

			ExtractParameters(Tag, pcArgs, &pS->pUV[pS->u32UVCount++]);
			break;

		case TAGNAME_FACE3:
			//--- Retrieve face description

			ExtractParameters(Tag, pcArgs, &pS->pFaces[pS->u32FacesCount++]);
			(pS->pObjects[pS->u32ObjectsCount].u32FacesCount)++;

			assert(!pS->u32NormalsCount || pS->pFaces[pS->u32FacesCount-1].pu32Normals[0] < pS->u32NormalsCount);
			assert(!pS->u32NormalsCount || pS->pFaces[pS->u32FacesCount-1].pu32Normals[1] < pS->u32NormalsCount);
			assert(!pS->u32NormalsCount || pS->pFaces[pS->u32FacesCount-1].pu32Normals[2] < pS->u32NormalsCount);

			assert(!pS->u32UVCount || pS->pFaces[pS->u32FacesCount-1].pu32UV[0] < pS->u32UVCount);
			assert(!pS->u32UVCount || pS->pFaces[pS->u32FacesCount-1].pu32UV[1] < pS->u32UVCount);
			assert(!pS->u32UVCount || pS->pFaces[pS->u32FacesCount-1].pu32UV[2] < pS->u32UVCount);
			break;

		case TAGNAME_FACE4:
			//--- Retrieve faces description

			ExtractParameters(Tag, pcArgs, &pS->pFaces[pS->u32FacesCount]);
			pS->u32FacesCount += 2;
			pS->pObjects[pS->u32ObjectsCount].u32FacesCount += 2;

			assert(!pS->u32NormalsCount || pS->pFaces[pS->u32FacesCount-1].pu32Normals[0] < pS->u32NormalsCount);
			assert(!pS->u32NormalsCount || pS->pFaces[pS->u32FacesCount-1].pu32Normals[1] < pS->u32NormalsCount);
			assert(!pS->u32NormalsCount || pS->pFaces[pS->u32FacesCount-1].pu32Normals[2] < pS->u32NormalsCount);

			assert(!pS->u32UVCount || pS->pFaces[pS->u32FacesCount-1].pu32UV[0] < pS->u32UVCount);
			assert(!pS->u32UVCount || pS->pFaces[pS->u32FacesCount-1].pu32UV[1] < pS->u32UVCount);
			assert(!pS->u32UVCount || pS->pFaces[pS->u32FacesCount-1].pu32UV[2] < pS->u32UVCount);

			assert(!pS->u32NormalsCount || pS->pFaces[pS->u32FacesCount-2].pu32Normals[0] < pS->u32NormalsCount);
			assert(!pS->u32NormalsCount || pS->pFaces[pS->u32FacesCount-2].pu32Normals[1] < pS->u32NormalsCount);
			assert(!pS->u32NormalsCount || pS->pFaces[pS->u32FacesCount-2].pu32Normals[2] < pS->u32NormalsCount);

			assert(!pS->u32UVCount || pS->pFaces[pS->u32FacesCount-2].pu32UV[0] < pS->u32UVCount);
			assert(!pS->u32UVCount || pS->pFaces[pS->u32FacesCount-2].pu32UV[1] < pS->u32UVCount);
			assert(!pS->u32UVCount || pS->pFaces[pS->u32FacesCount-2].pu32UV[2] < pS->u32UVCount);
			break;

		case TAGNAME_OBJECT:
			//--- Switch to next object

			pS->u32ObjectsCount++;
			pS->pObjects[pS->u32ObjectsCount].u32FirstFace = pS->u32FacesCount;
			pS->pObjects[pS->u32ObjectsCount].u32FacesCount = 0;

			//--- Retrieve material parameters

			ExtractParameters(Tag, pcArgs, pcMaterialName);

			//--- Look for material

			pS->pObjects[pS->u32ObjectsCount].u32Material = 0;
			for (; pS->pObjects[pS->u32ObjectsCount].u32Material<pS->u32MaterialsCount; pS->pObjects[pS->u32ObjectsCount].u32Material++)
			{
				if (!_stricmp(pS->pMaterials[pS->pObjects[pS->u32ObjectsCount].u32Material].pcName, pcMaterialName))
					break;
			}
	
			if (pS->pObjects[pS->u32ObjectsCount].u32Material >= pS->u32MaterialsCount)
				pS->pObjects[pS->u32ObjectsCount].u32Material = 0xFFFFFFFF;
			break;

		case TAGNAME_MATLIB:
			//--- Parse materials library

			ExtractParameters(Tag, pcArgs, pcMaterialLib);
			ParseMaterialLibrary(pS, sFileName, pcMaterialLib, FALSE);
			break;
		}
	}

	pS->u32ObjectsCount++;

	//--- Initialize normals

	if (bGenerateMissingNormals)
	{
		pS->u32NormalsCount = pS->u32VerticesCount;

		for (i=0; i<pS->u32NormalsCount; ++i)
			pS->pNormals[i].fX = pS->pNormals[i].fY = pS->pNormals[i].fZ = 0;

		for (i=0; i<pS->u32FacesCount; ++i)
		{
			//--- Update normals indices

			pS->pFaces[i].pu32Normals[0] = pS->pFaces[i].pu32Vertices[0];
			pS->pFaces[i].pu32Normals[1] = pS->pFaces[i].pu32Vertices[1];
			pS->pFaces[i].pu32Normals[2] = pS->pFaces[i].pu32Vertices[2];

			//--- Compute face normal

			AB.fX = pS->pVertices[pS->pFaces[i].pu32Vertices[1]].fX - pS->pVertices[pS->pFaces[i].pu32Vertices[0]].fX;
			AB.fY = pS->pVertices[pS->pFaces[i].pu32Vertices[1]].fY - pS->pVertices[pS->pFaces[i].pu32Vertices[0]].fY;
			AB.fZ = pS->pVertices[pS->pFaces[i].pu32Vertices[1]].fZ - pS->pVertices[pS->pFaces[i].pu32Vertices[0]].fZ;

			AC.fX = pS->pVertices[pS->pFaces[i].pu32Vertices[2]].fX - pS->pVertices[pS->pFaces[i].pu32Vertices[0]].fX;
			AC.fY = pS->pVertices[pS->pFaces[i].pu32Vertices[2]].fY - pS->pVertices[pS->pFaces[i].pu32Vertices[0]].fY;
			AC.fZ = pS->pVertices[pS->pFaces[i].pu32Vertices[2]].fZ - pS->pVertices[pS->pFaces[i].pu32Vertices[0]].fZ;

			N.fX = AB.fY*AC.fZ - AC.fY*AB.fZ;
			N.fY = AC.fX*AB.fZ - AB.fX*AC.fZ;
			N.fZ = AB.fX*AC.fY - AC.fX*AB.fY;

			//--- Normalize

			fL = sqrtf(N.fX*N.fX + N.fY*N.fY + N.fZ*N.fZ);
			if (fL > 0)
			{
				fL = 1.f/fL;
				N.fX *= fL;
				N.fY *= fL;
				N.fZ *= fL;
			}

			//--- Store for contribution to face's vertices

			pS->pNormals[pS->pFaces[i].pu32Normals[0]].fX += N.fX;
			pS->pNormals[pS->pFaces[i].pu32Normals[0]].fY += N.fY;
			pS->pNormals[pS->pFaces[i].pu32Normals[0]].fZ += N.fZ;

			pS->pNormals[pS->pFaces[i].pu32Normals[1]].fX += N.fX;
			pS->pNormals[pS->pFaces[i].pu32Normals[1]].fY += N.fY;
			pS->pNormals[pS->pFaces[i].pu32Normals[1]].fZ += N.fZ;

			pS->pNormals[pS->pFaces[i].pu32Normals[2]].fX += N.fX;
			pS->pNormals[pS->pFaces[i].pu32Normals[2]].fY += N.fY;
			pS->pNormals[pS->pFaces[i].pu32Normals[2]].fZ += N.fZ;
		}
	
		//--- Renormalize

		for (i=0; i<pS->u32NormalsCount; ++i)
		{
			fL = sqrtf(pS->pNormals[i].fX*pS->pNormals[i].fX + pS->pNormals[i].fY*pS->pNormals[i].fY + pS->pNormals[i].fZ*pS->pNormals[i].fZ);
			if (fL > 0)
			{
				fL = 1.f/fL;
				pS->pNormals[i].fX *= fL;
				pS->pNormals[i].fY *= fL;
				pS->pNormals[i].fZ *= fL;
			}
		}
	}

	//--- Compute centers for all objects

	for (i=0; i<pS->u32ObjectsCount; ++i)
	{
		for (j=0; j<pS->pObjects[i].u32FacesCount; ++j)
		{
			//--- Compute face center

			FaceCenter.fX = pS->pVertices[pS->pFaces[pS->pObjects[i].u32FirstFace + j].pu32Vertices[0]].fX;
			FaceCenter.fX+= pS->pVertices[pS->pFaces[pS->pObjects[i].u32FirstFace + j].pu32Vertices[1]].fX;
			FaceCenter.fX += pS->pVertices[pS->pFaces[pS->pObjects[i].u32FirstFace + j].pu32Vertices[2]].fX;

			FaceCenter.fY = pS->pVertices[pS->pFaces[pS->pObjects[i].u32FirstFace + j].pu32Vertices[0]].fY;
			FaceCenter.fY += pS->pVertices[pS->pFaces[pS->pObjects[i].u32FirstFace + j].pu32Vertices[1]].fY;
			FaceCenter.fY += pS->pVertices[pS->pFaces[pS->pObjects[i].u32FirstFace + j].pu32Vertices[2]].fY;

			FaceCenter.fZ = pS->pVertices[pS->pFaces[pS->pObjects[i].u32FirstFace + j].pu32Vertices[0]].fZ;
			FaceCenter.fZ += pS->pVertices[pS->pFaces[pS->pObjects[i].u32FirstFace + j].pu32Vertices[1]].fZ;
			FaceCenter.fZ += pS->pVertices[pS->pFaces[pS->pObjects[i].u32FirstFace + j].pu32Vertices[2]].fZ;

			pS->pObjects[i].Center.fX += FaceCenter.fX/3;
			pS->pObjects[i].Center.fY += FaceCenter.fY/3;
			pS->pObjects[i].Center.fZ += FaceCenter.fZ/3;
		}

		pS->pObjects[i].Center.fX /= pS->pObjects[i].u32FacesCount;
		pS->pObjects[i].Center.fY /= pS->pObjects[i].u32FacesCount;
		pS->pObjects[i].Center.fZ /= pS->pObjects[i].u32FacesCount;
	}

Exit:

	//--- Close scene file

	fclose(pScene);

	return(pS);
}
示例#12
0
//*********************************************************************************
// Parse materials library file
//
static void ParseMaterialLibrary(SCENE *pS, const char *sSceneFile, const char *sMatLib, BOOL bParseOnly)
{
	FILE *pMat;
	char pcLine[512], pcPath[MAX_PATH], *pcPtr;
	const char *pcArgs;
	TAG_NAME Tag;

	if (!sMatLib)
		return;

	//--- Extract base path

	strcpy_s(pcPath, sSceneFile);
	pcPtr = pcPath + strlen(pcPath)-1;
	while ((pcPtr > pcPath) && (*(pcPtr-1) != '\\') && (*(pcPtr-1) != '/') && (*(pcPtr-1) != ':'))
		--pcPtr;

	*pcPtr = 0;
	strcat_s(pcPath, sMatLib);

	pcPtr = pcPath;
	while (*pcPtr)
	{
		if (*pcPtr == '/')
			*pcPtr = '\\';
		
		pcPtr++;
	}

	//--- Open scene file

	fopen_s(&pMat, pcPath, "r");
	if (!pMat)
		return;

	//--- Parse scene file, first pass

	while (fgets(pcLine, sizeof(pcLine), pMat))
	{
		//--- Parse file line

		pcArgs = TokenizeFileLine(pcLine, &Tag);

		//--- Process file line

		switch (Tag)
		{
		case TAGNAME_MATERIAL:
			//--- Retrieve new material name

			if (!bParseOnly)
			{
				ExtractParameters(Tag, pcArgs, pS->pMaterials[pS->u32MaterialsCount].pcName);

				pS->pMaterials[pS->u32MaterialsCount].pfAmbient[0] = pS->pMaterials[pS->u32MaterialsCount].pfAmbient[1] = pS->pMaterials[pS->u32MaterialsCount].pfAmbient[2] = pS->pMaterials[pS->u32MaterialsCount].pfAmbient[3] = 0;
				pS->pMaterials[pS->u32MaterialsCount].pfDiffuse[0] = pS->pMaterials[pS->u32MaterialsCount].pfDiffuse[1] = pS->pMaterials[pS->u32MaterialsCount].pfDiffuse[2] = 0;
				pS->pMaterials[pS->u32MaterialsCount].pfDiffuse[3] = 1;
				pS->pMaterials[pS->u32MaterialsCount].pfSpecular[0] = pS->pMaterials[pS->u32MaterialsCount].pfSpecular[1] = pS->pMaterials[pS->u32MaterialsCount].pfSpecular[2] = pS->pMaterials[pS->u32MaterialsCount].pfSpecular[3] = 0;
				pS->pMaterials[pS->u32MaterialsCount].pfEmission[0] = pS->pMaterials[pS->u32MaterialsCount].pfEmission[1] = pS->pMaterials[pS->u32MaterialsCount].pfEmission[2] = pS->pMaterials[pS->u32MaterialsCount].pfEmission[3] = 0;
				pS->pMaterials[pS->u32MaterialsCount].fShininess = 128;
				pS->pMaterials[pS->u32MaterialsCount].pcTextureFile[0] = 0;
				pS->pMaterials[pS->u32MaterialsCount].pDiffuse = NULL;
				pS->pMaterials[pS->u32MaterialsCount].u32RenderFlags = 0;
			}

			pS->u32MaterialsCount++;
			break;

		case TAGNAME_OPACITY:
			//--- Retrieve opacity properties

			if (bParseOnly)
				break;

			ExtractParameters(Tag, pcArgs, &pS->pMaterials[pS->u32MaterialsCount-1].pfDiffuse[3]);
			break;

		case TAGNAME_SHININESS:
			//--- Retrieve shininess properties

			if (bParseOnly)
				break;

			ExtractParameters(Tag, pcArgs, &pS->pMaterials[pS->u32MaterialsCount-1].fShininess);
			if (pS->pMaterials[pS->u32MaterialsCount-1].fShininess < 1)
				pS->pMaterials[pS->u32MaterialsCount-1].fShininess = 1;
			else if (pS->pMaterials[pS->u32MaterialsCount-1].fShininess > 128)
				pS->pMaterials[pS->u32MaterialsCount-1].fShininess = 128;
			break;

		case TAGNAME_ILLUMINATION:
			//--- Retrieve lighting properties

			if (bParseOnly)
				break;

			ExtractParameters(Tag, pcArgs, &pS->pMaterials[pS->u32MaterialsCount-1].u32RenderFlags);
			break;

		case TAGNAME_AMBIENT:
			//--- Retrieve ambient properties

			if (bParseOnly)
				break;

			ExtractParameters(Tag, pcArgs, pS->pMaterials[pS->u32MaterialsCount-1].pfAmbient);
			break;

		case TAGNAME_DIFFUSE:
			//--- Retrieve diffuse properties

			if (bParseOnly)
				break;

			ExtractParameters(Tag, pcArgs, pS->pMaterials[pS->u32MaterialsCount-1].pfDiffuse);
			break;

		case TAGNAME_SPECULAR:
			//--- Retrieve specular properties

			if (bParseOnly)
				break;

			ExtractParameters(Tag, pcArgs, pS->pMaterials[pS->u32MaterialsCount-1].pfSpecular);
			break;

		case TAGNAME_EMISSION:
			//--- Retrieve emission properties

			if (bParseOnly)
				break;

			ExtractParameters(Tag, pcArgs, pS->pMaterials[pS->u32MaterialsCount-1].pfEmission);
			break;

		case TAGNAME_TEXTURE:
			//--- Retrieve texture filename

			if (bParseOnly)
				break;

			ExtractParameters(Tag, pcArgs, pS->pMaterials[pS->u32MaterialsCount-1].pcTextureFile);

			//--- Extract base path

			strcpy_s(pcPath, sSceneFile);
			pcPtr = pcPath + strlen(pcPath)-1;
			while ((pcPtr > pcPath) && (*(pcPtr-1) != '\\') && (*(pcPtr-1) != '/') && (*(pcPtr-1) != ':'))
				--pcPtr;

			*pcPtr = 0;
			strcat_s(pcPath, pS->pMaterials[pS->u32MaterialsCount-1].pcTextureFile);

			pcPtr = pcPath;
			while (*pcPtr)
			{
				if (*pcPtr == '/')
					*pcPtr = '\\';
				
				pcPtr++;
			}

			//--- Load texture file

			pS->pMaterials[pS->u32MaterialsCount-1].pDiffuse = ReadTGA(pcPath);
			break;
		}
	}

	//-- Close library file

	fclose(pMat);
}