<commit_before>/* Copyright 2009 SPARTA, Inc., dba Cobham Analytic Solutions
 *
 * This file is part of WATCHER.
 *
 *     WATCHER is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Affero General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     WATCHER is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Affero General Public License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Watcher.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * Use Google's libkml to out a KML file based upon the current network topology.
 * @author michael.elkins@cobham.com
 */

#define CUSTOM_ICON // use non-default icon for nodes

// libkml
#include "kml/convenience/convenience.h"
#include "kml/engine.h"
#include "kml/dom.h"

#include "libwatcher/watcherGraph.h"

#include <boost/lexical_cast.hpp>

using kmldom::ChangePtr;
using kmldom::CreatePtr;
using kmldom::CoordinatesPtr;
using kmldom::DocumentPtr;
using kmldom::FeaturePtr;
using kmldom::FolderPtr;
using kmldom::IconStyleIconPtr;
using kmldom::IconStylePtr;
using kmldom::KmlFactory;
using kmldom::KmlPtr;
using kmldom::LabelStylePtr;
using kmldom::LineStringPtr;
using kmldom::LineStylePtr;
using kmldom::MultiGeometryPtr;
using kmldom::PlacemarkPtr;
using kmldom::PointPtr;
using kmldom::StylePtr;
using kmldom::UpdatePtr;
using kmlengine::KmlFile;
using kmlengine::KmlFilePtr;

using namespace watcher;

namespace {

#ifdef CUSTOM_ICON
/*
 * Keep a mapping to the random Icon associated with a particular node so that the
 * same icon is used between invocations of write_kml().
 */
typedef std::map<NodeIdentifier, std::string> NodeIconMap ;
typedef NodeIconMap::iterator NodeIconMapIterator ;
NodeIconMap nodeIconMap;

const std::string BASE_ICON_URL = "http://maps.google.com/mapfiles/kml/shapes/";

// interesting icons for placemarks
const char *ICONS[] = {
    "cabs.png",
    "bus.png",
    "rail.png",
    "truck.png",
    "airports.png",
    "ferry.png",
    "heliport.png",
    "tram.png",
    "sailing.png"
};

// template to get the number of items in an array
template <typename T, int N> size_t sizeof_array( T (&)[N] ) { return N; }

void icon_setup(KmlFactory* kmlFac, DocumentPtr document)
{
    // set up styles for each icon we use, using the icon name as the id
    for (size_t i = 0; i < sizeof_array(ICONS); ++i) {
        IconStyleIconPtr icon(kmlFac->CreateIconStyleIcon());
        std::string url(BASE_ICON_URL + ICONS[i]);
        icon->set_href(url.c_str());

        IconStylePtr iconStyle(kmlFac->CreateIconStyle());
        iconStyle->set_icon(icon);

        StylePtr style(kmlFac->CreateStyle());
        style->set_iconstyle(iconStyle);
        style->set_id(ICONS[i]);

        document->add_styleselector(style);
    }
}

/*
 * For testing purposes, randomly select an interesting icon to replace the default yellow pushpin.
 * In order to use the same icon between invocations of write_kml(), a map is used to store the icon
 * selected.
 */
void set_node_icon(const WatcherGraphNode& node, PlacemarkPtr ptr)
{
    std::string styleUrl;
    NodeIconMapIterator it = nodeIconMap.find(node.nodeId);
    if (it == nodeIconMap.end()) {
        styleUrl = std::string("#") + ICONS[ random() % sizeof_array(ICONS) ];
        nodeIconMap[node.nodeId] = styleUrl;
    } else
        styleUrl = it->second;
    ptr->set_styleurl(styleUrl);
}
#endif // CUSTOM_ICON

void output_nodes(KmlFactory* kmlFac, const WatcherGraph& graph, FolderPtr folder)
{
    // iterate over all nodes in the graph
    WatcherGraph::vertexIterator vi, vend;
    for (tie(vi, vend) = vertices(graph.theGraph); vi != vend; ++vi) {
        const WatcherGraphNode &node = graph.theGraph[*vi];

        PlacemarkPtr ptr = kmlFac->CreatePlacemark();
        std::string ip(node.nodeId.to_string());
        ptr->set_name(ip); // textual label, can be html
        //ptr->set_id(ip); // internal label for locating object in the DOM tree

        // set the location
        ptr->set_geometry(kmlconvenience::CreatePointLatLon(node.gpsData->y, node.gpsData->x));

        /*
        //target id is required when changing some attribute of a feature already in the dom
        ptr->set_targetid("node0");
        */

#ifdef CUSTOM_ICON
        set_node_icon(node, ptr);
#endif

        folder->add_feature(ptr);//add to DOM
    }
}

/*
 * Convert a watcher color to the KML format.
 */
std::string watcher_color_to_kml(const watcher::Color& color)
{
    char buf[sizeof("aabbggrr")];
    sprintf(buf, "%02x%02x%02x%02x", color.a, color.b, color.g, color.r);
    return std::string(buf);
}

void output_edges(KmlFactory* kmlFac, const WatcherGraph& graph, DocumentPtr document, FolderPtr folder)
{
    WatcherGraph::edgeIterator ei, eend;
    unsigned int count = 0;
    bool has_style = false;

    for (tie(ei, eend) = edges(graph.theGraph); ei != eend; ++ei, ++count) {
        const WatcherGraphEdge &edge = graph.theGraph[*ei];
        const WatcherGraphNode &node1 = graph.theGraph[source(*ei, graph.theGraph)];
        const WatcherGraphNode &node2 = graph.theGraph[target(*ei, graph.theGraph)];

        CoordinatesPtr coords = kmlFac->CreateCoordinates();
        coords->add_latlng(node1.gpsData->y, node1.gpsData->x);
        coords->add_latlng(node2.gpsData->y, node2.gpsData->x);

        LineStringPtr lineString = kmlFac->CreateLineString();
        lineString->set_coordinates(coords);

        CoordinatesPtr pointCoords(kmlFac->CreateCoordinates());
        //place label at the midpoint on the line between the two nodes
        pointCoords->add_latlng((node1.gpsData->y + node2.gpsData->y)/2,(node1.gpsData->x + node2.gpsData->x)/2);

        PointPtr point(kmlFac->CreatePoint());
        point->set_coordinates(pointCoords);

        /*
         * Google Earth doesn't allow a label to be attached to something without a Point, so
         * we need to create a container with the LineString and the Point at which to attach
         * the label/icon.
         */
        MultiGeometryPtr multiGeo(kmlFac->CreateMultiGeometry());
        multiGeo->add_geometry(lineString);
        multiGeo->add_geometry(point);

        PlacemarkPtr ptr = kmlFac->CreatePlacemark();
        ptr->set_geometry(multiGeo);

        // WatcherGraphEdge supports multiple labels per edge, but GE only supports one, so just use the first label in the list
        LabelDisplayInfoPtr labelDisplayInfo(edge.labels.front());
        if (labelDisplayInfo) {
            ptr->set_name(labelDisplayInfo->labelText);
        }

        // WatcherGraph only has a single style per layer, so we stash the value somewhere instead of creating multiple styles
        if (!has_style) {
            LineStylePtr lineStyle(kmlFac->CreateLineStyle());
            lineStyle->set_color(watcher_color_to_kml(edge.displayInfo->color));
            lineStyle->set_width(edge.displayInfo->width);

            IconStylePtr iconStyle(kmlFac->CreateIconStyle());
            iconStyle->set_scale(0); // scale to 0 should mean hide it?

            StylePtr style(kmlFac->CreateStyle());
            style->set_id("edge-style");
            style->set_linestyle(lineStyle);
            style->set_iconstyle(iconStyle);

            if (labelDisplayInfo) {
                LabelStylePtr labelStyle(kmlFac->CreateLabelStyle());
                labelStyle->set_color(watcher_color_to_kml(labelDisplayInfo->foregroundColor));
                style->set_labelstyle(labelStyle);
            }

            document->add_styleselector(style);
            has_style = true;
        }

        ptr->set_styleurl("#edge-style");

        folder->add_feature(ptr);//add to DOM
    }
}

} // end namespace

void write_kml(const WatcherGraph& graph, const std::string& outputFile)
{
    // libkml boilerplate
    KmlFactory* kmlFac(kmldom::KmlFactory::GetFactory());
    KmlPtr kml(kmlFac->CreateKml());

    /*
     * create initial DOM tree.  As nodes appear, they get added to the tree.
     * As nodes move, we update the position attribute
     * in the DOM, and regenerate the KML file.
     */
    DocumentPtr document(kmlFac->CreateDocument());
    kml->set_feature(document);

    FolderPtr folder(kmlFac->CreateFolder());
    folder->set_name("Watcher");
    document->add_feature(folder);

#ifdef CUSTOM_ICON
    icon_setup(kmlFac, document);
#endif // CUSTOM_ICON
    output_nodes(kmlFac, graph, folder);
    output_edges(kmlFac, graph, document, folder);

    kmlbase::File::WriteStringToFile(kmldom::SerializePretty(kml), outputFile);
}
<commit_msg>remove commented out code<commit_after>/* Copyright 2009 SPARTA, Inc., dba Cobham Analytic Solutions
 *
 * This file is part of WATCHER.
 *
 *     WATCHER is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Affero General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     WATCHER is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Affero General Public License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Watcher.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * Use Google's libkml to out a KML file based upon the current network topology.
 * @author michael.elkins@cobham.com
 */

#define CUSTOM_ICON // use non-default icon for nodes

// libkml
#include "kml/convenience/convenience.h"
#include "kml/engine.h"
#include "kml/dom.h"

#include "libwatcher/watcherGraph.h"

#include <boost/lexical_cast.hpp>

using kmldom::ChangePtr;
using kmldom::CreatePtr;
using kmldom::CoordinatesPtr;
using kmldom::DocumentPtr;
using kmldom::FeaturePtr;
using kmldom::FolderPtr;
using kmldom::IconStyleIconPtr;
using kmldom::IconStylePtr;
using kmldom::KmlFactory;
using kmldom::KmlPtr;
using kmldom::LabelStylePtr;
using kmldom::LineStringPtr;
using kmldom::LineStylePtr;
using kmldom::MultiGeometryPtr;
using kmldom::PlacemarkPtr;
using kmldom::PointPtr;
using kmldom::StylePtr;
using kmldom::UpdatePtr;
using kmlengine::KmlFile;
using kmlengine::KmlFilePtr;

using namespace watcher;

namespace {

#ifdef CUSTOM_ICON
/*
 * Keep a mapping to the random Icon associated with a particular node so that the
 * same icon is used between invocations of write_kml().
 */
typedef std::map<NodeIdentifier, std::string> NodeIconMap ;
typedef NodeIconMap::iterator NodeIconMapIterator ;
NodeIconMap nodeIconMap;

const std::string BASE_ICON_URL = "http://maps.google.com/mapfiles/kml/shapes/";

// interesting icons for placemarks
const char *ICONS[] = {
    "cabs.png",
    "bus.png",
    "rail.png",
    "truck.png",
    "airports.png",
    "ferry.png",
    "heliport.png",
    "tram.png",
    "sailing.png"
};

// template to get the number of items in an array
template <typename T, int N> size_t sizeof_array( T (&)[N] ) { return N; }

void icon_setup(KmlFactory* kmlFac, DocumentPtr document)
{
    // set up styles for each icon we use, using the icon name as the id
    for (size_t i = 0; i < sizeof_array(ICONS); ++i) {
        IconStyleIconPtr icon(kmlFac->CreateIconStyleIcon());
        std::string url(BASE_ICON_URL + ICONS[i]);
        icon->set_href(url.c_str());

        IconStylePtr iconStyle(kmlFac->CreateIconStyle());
        iconStyle->set_icon(icon);

        StylePtr style(kmlFac->CreateStyle());
        style->set_iconstyle(iconStyle);
        style->set_id(ICONS[i]);

        document->add_styleselector(style);
    }
}

/*
 * For testing purposes, randomly select an interesting icon to replace the default yellow pushpin.
 * In order to use the same icon between invocations of write_kml(), a map is used to store the icon
 * selected.
 */
void set_node_icon(const WatcherGraphNode& node, PlacemarkPtr ptr)
{
    std::string styleUrl;
    NodeIconMapIterator it = nodeIconMap.find(node.nodeId);
    if (it == nodeIconMap.end()) {
        styleUrl = std::string("#") + ICONS[ random() % sizeof_array(ICONS) ];
        nodeIconMap[node.nodeId] = styleUrl;
    } else
        styleUrl = it->second;
    ptr->set_styleurl(styleUrl);
}
#endif // CUSTOM_ICON

void output_nodes(KmlFactory* kmlFac, const WatcherGraph& graph, FolderPtr folder)
{
    // iterate over all nodes in the graph
    WatcherGraph::vertexIterator vi, vend;
    for (tie(vi, vend) = vertices(graph.theGraph); vi != vend; ++vi) {
        const WatcherGraphNode &node = graph.theGraph[*vi];

        PlacemarkPtr ptr = kmlFac->CreatePlacemark();
        std::string ip(node.nodeId.to_string());
        ptr->set_name(ip); // textual label, can be html

        // set the location
        ptr->set_geometry(kmlconvenience::CreatePointLatLon(node.gpsData->y, node.gpsData->x));

        //target id is required when changing some attribute of a feature already in the dom
        //ptr->set_targetid("node0");

#ifdef CUSTOM_ICON
        set_node_icon(node, ptr);
#endif

        folder->add_feature(ptr);//add to DOM
    }
}

/*
 * Convert a watcher color to the KML format.
 */
std::string watcher_color_to_kml(const watcher::Color& color)
{
    char buf[sizeof("aabbggrr")];
    sprintf(buf, "%02x%02x%02x%02x", color.a, color.b, color.g, color.r);
    return std::string(buf);
}

void output_edges(KmlFactory* kmlFac, const WatcherGraph& graph, DocumentPtr document, FolderPtr folder)
{
    WatcherGraph::edgeIterator ei, eend;
    unsigned int count = 0;
    bool has_style = false;

    for (tie(ei, eend) = edges(graph.theGraph); ei != eend; ++ei, ++count) {
        const WatcherGraphEdge &edge = graph.theGraph[*ei];
        const WatcherGraphNode &node1 = graph.theGraph[source(*ei, graph.theGraph)];
        const WatcherGraphNode &node2 = graph.theGraph[target(*ei, graph.theGraph)];

        CoordinatesPtr coords = kmlFac->CreateCoordinates();
        coords->add_latlng(node1.gpsData->y, node1.gpsData->x);
        coords->add_latlng(node2.gpsData->y, node2.gpsData->x);

        LineStringPtr lineString = kmlFac->CreateLineString();
        lineString->set_coordinates(coords);

        CoordinatesPtr pointCoords(kmlFac->CreateCoordinates());
        //place label at the midpoint on the line between the two nodes
        pointCoords->add_latlng((node1.gpsData->y + node2.gpsData->y)/2,(node1.gpsData->x + node2.gpsData->x)/2);

        PointPtr point(kmlFac->CreatePoint());
        point->set_coordinates(pointCoords);

        /*
         * Google Earth doesn't allow a label to be attached to something without a Point, so
         * we need to create a container with the LineString and the Point at which to attach
         * the label/icon.
         */
        MultiGeometryPtr multiGeo(kmlFac->CreateMultiGeometry());
        multiGeo->add_geometry(lineString);
        multiGeo->add_geometry(point);

        PlacemarkPtr ptr = kmlFac->CreatePlacemark();
        ptr->set_geometry(multiGeo);

        // WatcherGraphEdge supports multiple labels per edge, but GE only supports one, so just use the first label in the list
        LabelDisplayInfoPtr labelDisplayInfo(edge.labels.front());
        if (labelDisplayInfo) {
            ptr->set_name(labelDisplayInfo->labelText);
        }

        // WatcherGraph only has a single style per layer, so we stash the value somewhere instead of creating multiple styles
        if (!has_style) {
            LineStylePtr lineStyle(kmlFac->CreateLineStyle());
            lineStyle->set_color(watcher_color_to_kml(edge.displayInfo->color));
            lineStyle->set_width(edge.displayInfo->width);

            IconStylePtr iconStyle(kmlFac->CreateIconStyle());
            iconStyle->set_scale(0); // scale to 0 should mean hide it?

            StylePtr style(kmlFac->CreateStyle());
            style->set_id("edge-style");
            style->set_linestyle(lineStyle);
            style->set_iconstyle(iconStyle);

            if (labelDisplayInfo) {
                LabelStylePtr labelStyle(kmlFac->CreateLabelStyle());
                labelStyle->set_color(watcher_color_to_kml(labelDisplayInfo->foregroundColor));
                style->set_labelstyle(labelStyle);
            }

            document->add_styleselector(style);
            has_style = true;
        }

        ptr->set_styleurl("#edge-style");

        folder->add_feature(ptr);//add to DOM
    }
}

} // end namespace

void write_kml(const WatcherGraph& graph, const std::string& outputFile)
{
    // libkml boilerplate
    KmlFactory* kmlFac(kmldom::KmlFactory::GetFactory());
    KmlPtr kml(kmlFac->CreateKml());

    /*
     * create initial DOM tree.  As nodes appear, they get added to the tree.
     * As nodes move, we update the position attribute
     * in the DOM, and regenerate the KML file.
     */
    DocumentPtr document(kmlFac->CreateDocument());
    kml->set_feature(document);

    FolderPtr folder(kmlFac->CreateFolder());
    folder->set_name("Watcher");
    document->add_feature(folder);

#ifdef CUSTOM_ICON
    icon_setup(kmlFac, document);
#endif // CUSTOM_ICON
    output_nodes(kmlFac, graph, folder);
    output_edges(kmlFac, graph, document, folder);

    kmlbase::File::WriteStringToFile(kmldom::SerializePretty(kml), outputFile);
}
<|endoftext|>


<commit_before>#include "./camera.h"
#include <Eigen/Geometry>
#include <math.h>

#include <iostream>

Camera::Camera()
  : origin(0.0f, 0.0f, 0.0f), position(0.0f, 0.0f, 1.0f),
    direction(0.0f, 0.0f, -1.0f), up(0.0f, 1.0f, 0.0f), radius(1.0f),
    azimuth(1.5f * M_PI), declination(0.0f)
{
  projection = createProjection(fieldOfView, aspectRatio, nearPlane, farPlane);
  // projection = createOrthographicProjection(aspectRatio, nearPlane,
  // farPlane);

  update();
}

Camera::Camera(Eigen::Matrix4f viewMatrix, Eigen::Matrix4f projectionMatrix,
               Eigen::Vector3f origin)
  : projection(projectionMatrix), view(viewMatrix), origin(origin)
{
  setPosDirUpFrom(viewMatrix);

  radius = (position - origin).norm();

  Eigen::Vector3f diff = (position - origin) / radius;
  setAnglesFormUnitVector(diff);
}

Camera::~Camera()
{
}

Eigen::Matrix4f Camera::createProjection(float fov, float aspectRatio,
                                         float nearPlane, float farPlane)
{
  float tanHalfFovy = tan(fov / 2.0f);
  Eigen::Matrix4f result = Eigen::Matrix4f::Zero();
  result(0, 0) = 1.0f / (aspectRatio * tanHalfFovy);
  result(1, 1) = 1.0f / (tanHalfFovy);
  result(2, 2) = -(farPlane + nearPlane) / (farPlane - nearPlane);
  result(3, 2) = -1.0f;
  result(2, 3) = -(2.0f * farPlane * nearPlane) / (farPlane - nearPlane);

  return result;
}

Eigen::Matrix4f Camera::createOrthographicProjection(float aspectRatio,
                                                     float nearPlane,
                                                     float farPlane)
{
  float diff = farPlane - nearPlane;
  Eigen::Matrix4f result = Eigen::Matrix4f::Zero();
  result(0, 0) = 2.0f;
  result(1, 1) = 2.0f * aspectRatio;
  result(2, 2) = 1.0f / diff;
  result(2, 3) = -nearPlane / diff;
  result(3, 3) = 1.0f;

  return result;
}

void Camera::moveForward(float distance)
{
  position += distance * direction;
  update();
}

void Camera::moveBackward(float distance)
{
  position -= distance * direction;
  update();
}

void Camera::strafe(float distance)
{
  auto right = direction.cross(up);
  position += distance * right;
  origin += distance * right;
  update();
}

void Camera::strafeLeft(float distance)
{
  strafe(-distance);
}

void Camera::strafeRight(float distance)
{
  strafe(distance);
}

void Camera::moveVertical(float distance)
{
  position += distance * up;
  origin += distance * up;
  update();
}

void Camera::changeAzimuth(float deltaAngle)
{
  azimuth += deltaAngle;
  update();
}

void Camera::changeDeclination(float deltaAngle)
{
  declination += deltaAngle;
  update();
}

void Camera::changeRadius(float deltaRadius)
{
  radius += deltaRadius;
  position = origin + (position - origin).normalized() * radius;
  update();
}

void Camera::update()
{
  radius = (origin - position).norm();
  position = origin +
             Eigen::Vector3f(cos(azimuth) * cos(declination), sin(declination),
                             sin(azimuth) * cos(declination)) *
                 radius;
  direction = (origin - position).normalized();
  float upDeclination = declination - static_cast<float>(M_PI / 2.0);
  up = -Eigen::Vector3f(cos(azimuth) * cos(upDeclination), sin(upDeclination),
                        sin(azimuth) * cos(upDeclination)).normalized();

  auto n = direction.normalized();
  auto u = up.cross(n).normalized();
  auto v = n.cross(u);
  auto e = position;

  view << u.x(), u.y(), u.z(), u.dot(e), v.x(), v.y(), v.z(), v.dot(e), n.x(),
      n.y(), n.z(), n.dot(e), 0, 0, 0, 1;
}

Eigen::Matrix4f Camera::getViewMatrix() const
{
  return view;
}

Eigen::Matrix4f Camera::getProjectionMatrix() const
{
  return projection;
}

Eigen::Vector3f Camera::getPosition() const
{
  return position;
}

Eigen::Vector3f Camera::getOrigin() const
{
  return origin;
}

float Camera::getRadius() const
{
  return (position - origin).norm();
}

void Camera::resize(float width, float height)
{
  aspectRatio = width / height;
  projection = createProjection(fieldOfView, aspectRatio, 0.1f, 100.0f);
}

void Camera::updateNearAndFarPlanes(float nearPlane, float farPlane)
{
  this->nearPlane = nearPlane;
  this->farPlane = farPlane;

  projection = createProjection(fieldOfView, aspectRatio, nearPlane, farPlane);
}

float Camera::getNearPlane()
{
  return this->nearPlane;
}

float Camera::getFarPlane()
{
  return this->farPlane;
}

void Camera::setOrigin(Eigen::Vector3f origin)
{
  this->origin = origin;
  Eigen::Vector3f diff = (position - this->origin).normalized();

  declination = asin(diff.y());
  azimuth = -acos(diff.x() / cos(declination));
  update();
}

bool Camera::needsResizing()
{
  return aspectRatio == 0.0f;
}

void Camera::startAnimation(Eigen::Matrix4f viewMatrix, float duration)
{
  animationTime = 0.0f;
  animationDuration = duration;

  animationStartPosition = position;
  animationEndPosition = -viewMatrix.inverse().col(3).head<3>();

  animationStartRotation = view.block<3, 3>(0, 0);
  animationEndRotation = viewMatrix.block<3, 3>(0, 0);
}

void Camera::updateAnimation(double frameTime)
{
  if (animationDuration == 0.0f)
    return;

  animationTime += frameTime;
  float factor = animationTime / animationDuration;
  if (animationTime > animationDuration)
  {
    factor = 1;
    animationDuration = 0.0f;
  }

  Eigen::Vector3f diff =
      factor * (animationEndPosition - animationStartPosition);

  Eigen::Vector3f newPosition = animationStartPosition + diff;
  Eigen::Vector3f originDiff = newPosition - position;
  position = newPosition;

  auto rotation = animationStartRotation.slerp(factor, animationEndRotation);
  Eigen::Matrix3f rotationMatrix = rotation.toRotationMatrix();

  std::cout << "originDiff norm: " << originDiff.norm() << std::endl;
  direction = rotationMatrix.col(2);
  origin = originDiff.norm() * direction;
  up = rotationMatrix.col(1);

  radius = (position - origin).norm();

  Eigen::Vector3f lookAt = (position - origin) / radius;
  setAnglesFormUnitVector(lookAt);

  update();
}

void Camera::setPosDirUpFrom(Eigen::Matrix4f viewMatrix)
{
  position = -viewMatrix.inverse().col(3).head<3>();
  direction = viewMatrix.col(2).head<3>();
  up = viewMatrix.col(1).head<3>();
}

void Camera::setAnglesFormUnitVector(Eigen::Vector3f diff)
{
  declination = asin(diff.y());
  /*
  if (diff.x() < 0)
  {
    declination = M_PI - declination;
  }
  azimuth = atan2(diff.x(), diff.z());
  */

  azimuth = -acos(diff.x() / cos(declination));
}

<commit_msg>Calculate angles in default constructor.<commit_after>#include "./camera.h"
#include <Eigen/Geometry>
#include <math.h>

#include <iostream>

Camera::Camera()
  : origin(0.0f, 0.0f, 0.0f), position(0.0f, 0.0f, 1.0f),
    direction(0.0f, 0.0f, -1.0f), up(0.0f, 1.0f, 0.0f), radius(1.0f)
{
  projection = createProjection(fieldOfView, aspectRatio, nearPlane, farPlane);
  // projection = createOrthographicProjection(aspectRatio, nearPlane,
  // farPlane);

  Eigen::Vector3f diff = (position - origin) / radius;
  setAnglesFormUnitVector(diff);

  update();
}

Camera::Camera(Eigen::Matrix4f viewMatrix, Eigen::Matrix4f projectionMatrix,
               Eigen::Vector3f origin)
  : projection(projectionMatrix), view(viewMatrix), origin(origin)
{
  setPosDirUpFrom(viewMatrix);

  radius = (position - origin).norm();

  Eigen::Vector3f diff = (position - origin) / radius;
  setAnglesFormUnitVector(diff);
}

Camera::~Camera()
{
}

Eigen::Matrix4f Camera::createProjection(float fov, float aspectRatio,
                                         float nearPlane, float farPlane)
{
  float tanHalfFovy = tan(fov / 2.0f);
  Eigen::Matrix4f result = Eigen::Matrix4f::Zero();
  result(0, 0) = 1.0f / (aspectRatio * tanHalfFovy);
  result(1, 1) = 1.0f / (tanHalfFovy);
  result(2, 2) = -(farPlane + nearPlane) / (farPlane - nearPlane);
  result(3, 2) = -1.0f;
  result(2, 3) = -(2.0f * farPlane * nearPlane) / (farPlane - nearPlane);

  return result;
}

Eigen::Matrix4f Camera::createOrthographicProjection(float aspectRatio,
                                                     float nearPlane,
                                                     float farPlane)
{
  float diff = farPlane - nearPlane;
  Eigen::Matrix4f result = Eigen::Matrix4f::Zero();
  result(0, 0) = 2.0f;
  result(1, 1) = 2.0f * aspectRatio;
  result(2, 2) = 1.0f / diff;
  result(2, 3) = -nearPlane / diff;
  result(3, 3) = 1.0f;

  return result;
}

void Camera::moveForward(float distance)
{
  position += distance * direction;
  update();
}

void Camera::moveBackward(float distance)
{
  position -= distance * direction;
  update();
}

void Camera::strafe(float distance)
{
  auto right = direction.cross(up);
  position += distance * right;
  origin += distance * right;
  update();
}

void Camera::strafeLeft(float distance)
{
  strafe(-distance);
}

void Camera::strafeRight(float distance)
{
  strafe(distance);
}

void Camera::moveVertical(float distance)
{
  position += distance * up;
  origin += distance * up;
  update();
}

void Camera::changeAzimuth(float deltaAngle)
{
  azimuth += deltaAngle;
  update();
}

void Camera::changeDeclination(float deltaAngle)
{
  declination += deltaAngle;
  update();
}

void Camera::changeRadius(float deltaRadius)
{
  radius += deltaRadius;
  position = origin + (position - origin).normalized() * radius;
  update();
}

void Camera::update()
{
  radius = (origin - position).norm();
  position = origin +
             Eigen::Vector3f(cos(azimuth) * cos(declination), sin(declination),
                             sin(azimuth) * cos(declination)) *
                 radius;
  direction = (origin - position).normalized();
  float upDeclination = declination - static_cast<float>(M_PI / 2.0);
  up = -Eigen::Vector3f(cos(azimuth) * cos(upDeclination), sin(upDeclination),
                        sin(azimuth) * cos(upDeclination)).normalized();

  auto n = direction.normalized();
  auto u = up.cross(n).normalized();
  auto v = n.cross(u);
  auto e = position;

  view << u.x(), u.y(), u.z(), u.dot(e), v.x(), v.y(), v.z(), v.dot(e), n.x(),
      n.y(), n.z(), n.dot(e), 0, 0, 0, 1;
}

Eigen::Matrix4f Camera::getViewMatrix() const
{
  return view;
}

Eigen::Matrix4f Camera::getProjectionMatrix() const
{
  return projection;
}

Eigen::Vector3f Camera::getPosition() const
{
  return position;
}

Eigen::Vector3f Camera::getOrigin() const
{
  return origin;
}

float Camera::getRadius() const
{
  return (position - origin).norm();
}

void Camera::resize(float width, float height)
{
  aspectRatio = width / height;
  projection = createProjection(fieldOfView, aspectRatio, 0.1f, 100.0f);
}

void Camera::updateNearAndFarPlanes(float nearPlane, float farPlane)
{
  this->nearPlane = nearPlane;
  this->farPlane = farPlane;

  projection = createProjection(fieldOfView, aspectRatio, nearPlane, farPlane);
}

float Camera::getNearPlane()
{
  return this->nearPlane;
}

float Camera::getFarPlane()
{
  return this->farPlane;
}

void Camera::setOrigin(Eigen::Vector3f origin)
{
  this->origin = origin;
  Eigen::Vector3f diff = (position - this->origin).normalized();

  declination = asin(diff.y());
  azimuth = -acos(diff.x() / cos(declination));
  update();
}

bool Camera::needsResizing()
{
  return aspectRatio == 0.0f;
}

void Camera::startAnimation(Eigen::Matrix4f viewMatrix, float duration)
{
  animationTime = 0.0f;
  animationDuration = duration;

  animationStartPosition = position;
  animationEndPosition = -viewMatrix.inverse().col(3).head<3>();

  animationStartRotation = view.block<3, 3>(0, 0);
  animationEndRotation = viewMatrix.block<3, 3>(0, 0);
}

void Camera::updateAnimation(double frameTime)
{
  if (animationDuration == 0.0f)
    return;

  animationTime += frameTime;
  float factor = animationTime / animationDuration;
  if (animationTime > animationDuration)
  {
    factor = 1;
    animationDuration = 0.0f;
  }

  Eigen::Vector3f diff =
      factor * (animationEndPosition - animationStartPosition);

  Eigen::Vector3f newPosition = animationStartPosition + diff;
  Eigen::Vector3f originDiff = newPosition - position;
  position = newPosition;

  auto rotation = animationStartRotation.slerp(factor, animationEndRotation);
  Eigen::Matrix3f rotationMatrix = rotation.toRotationMatrix();

  std::cout << "originDiff norm: " << originDiff.norm() << std::endl;
  direction = rotationMatrix.col(2);
  origin = originDiff.norm() * direction;
  up = rotationMatrix.col(1);

  radius = (position - origin).norm();

  Eigen::Vector3f lookAt = (position - origin) / radius;
  setAnglesFormUnitVector(lookAt);

  update();
}

void Camera::setPosDirUpFrom(Eigen::Matrix4f viewMatrix)
{
  position = -viewMatrix.inverse().col(3).head<3>();
  direction = viewMatrix.col(2).head<3>();
  up = viewMatrix.col(1).head<3>();
}

void Camera::setAnglesFormUnitVector(Eigen::Vector3f diff)
{
  declination = asin(diff.y());
  /*
  if (diff.x() < 0)
  {
    declination = M_PI - declination;
  }
  azimuth = atan2(diff.x(), diff.z());
  */

  azimuth = -acos(diff.x() / cos(declination));
}

<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2018 Advanced Micro Devices, Inc.
* Copyright (c) 2018 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief VK_KHR_driver_properties tests
*//*--------------------------------------------------------------------*/

#include "vktApiDriverPropertiesTests.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkKnownDriverIds.inl"

using namespace vk;

namespace vkt
{
namespace api
{
namespace
{

enum TestType
{
	TEST_TYPE_DRIVER_ID_MATCH			= 0,
	TEST_TYPE_NAME_IS_NOT_EMPTY,
	TEST_TYPE_NAME_ZERO_TERMINATED,
	TEST_TYPE_INFO_ZERO_TERMINATED,
	TEST_TYPE_VERSION,
};

static const VkConformanceVersion knownConformanceVersions[] =
{
#ifndef CTS_USES_VULKANSC
	makeConformanceVersion(1, 3, 3, 1),
	makeConformanceVersion(1, 3, 3, 0),
	makeConformanceVersion(1, 3, 2, 0),
	makeConformanceVersion(1, 3, 1, 1),
	makeConformanceVersion(1, 3, 1, 0),
	makeConformanceVersion(1, 3, 0, 0),
	makeConformanceVersion(1, 2, 8, 0),
	makeConformanceVersion(1, 2, 7, 2),
	makeConformanceVersion(1, 2, 7, 1),
	makeConformanceVersion(1, 2, 7, 0),
	makeConformanceVersion(1, 2, 6, 2),
	makeConformanceVersion(1, 2, 6, 1),
	makeConformanceVersion(1, 2, 6, 0),
	makeConformanceVersion(1, 2, 5, 2),
	makeConformanceVersion(1, 2, 5, 1),
	makeConformanceVersion(1, 2, 5, 0),
	makeConformanceVersion(1, 2, 4, 1),
	makeConformanceVersion(1, 2, 4, 0),
	makeConformanceVersion(1, 2, 3, 3),
	makeConformanceVersion(1, 2, 3, 2),
	makeConformanceVersion(1, 2, 3, 1),
	makeConformanceVersion(1, 2, 3, 0),
	makeConformanceVersion(1, 2, 2, 2),
	makeConformanceVersion(1, 2, 2, 1),
	makeConformanceVersion(1, 2, 2, 0),
	makeConformanceVersion(1, 2, 1, 2),
	makeConformanceVersion(1, 2, 1, 1),
	makeConformanceVersion(1, 2, 1, 0),
	makeConformanceVersion(1, 2, 0, 2),
	makeConformanceVersion(1, 2, 0, 1),
	makeConformanceVersion(1, 2, 0, 0),
	makeConformanceVersion(1, 1, 6, 3),
	makeConformanceVersion(1, 1, 6, 2),
	makeConformanceVersion(1, 1, 6, 1),
	makeConformanceVersion(1, 1, 6, 0),
	makeConformanceVersion(1, 1, 5, 2),
	makeConformanceVersion(1, 1, 5, 1),
	makeConformanceVersion(1, 1, 5, 0),
	makeConformanceVersion(1, 1, 4, 3),
	makeConformanceVersion(1, 1, 4, 2),
	makeConformanceVersion(1, 1, 4, 1),
	makeConformanceVersion(1, 1, 4, 0),
	makeConformanceVersion(1, 1, 3, 3),
	makeConformanceVersion(1, 1, 3, 2),
	makeConformanceVersion(1, 1, 3, 1),
	makeConformanceVersion(1, 1, 3, 0),
#else
	makeConformanceVersion(1, 0, 1, 0),
	makeConformanceVersion(1, 0, 0, 0),
#endif // CTS_USES_VULKANSC
};

DE_INLINE bool isNullTerminated(const char* str, const deUint32 maxSize)
{
	return deStrnlen(str, maxSize) < maxSize;
}

DE_INLINE bool operator==(const VkConformanceVersion& a, const VkConformanceVersion& b)
{
	return ((a.major == b.major)		&&
			(a.minor == b.minor)		&&
			(a.subminor == b.subminor)	&&
			(a.patch == b.patch));
}

void checkSupport (Context& context, const TestType config)
{
	DE_UNREF(config);
	context.requireDeviceFunctionality("VK_KHR_driver_properties");
}

void testDriverMatch (const VkPhysicalDeviceDriverProperties& deviceDriverProperties)
{
	for (deUint32 driverNdx = 0; driverNdx < DE_LENGTH_OF_ARRAY(driverIds); driverNdx++)
	{
		if (deviceDriverProperties.driverID == driverIds[driverNdx].id)
			return;
	}

	TCU_FAIL("Driver ID did not match any known driver");
}

void testNameIsNotEmpty (const VkPhysicalDeviceDriverProperties& deviceDriverProperties)
{
	if (deviceDriverProperties.driverName[0] == 0)
		TCU_FAIL("Driver name is empty");
}

void testNameZeroTerminated (const VkPhysicalDeviceDriverProperties& deviceDriverProperties)
{
	if (!isNullTerminated(deviceDriverProperties.driverName, VK_MAX_DRIVER_NAME_SIZE))
		TCU_FAIL("Driver name is not a null-terminated string");
}

void testInfoZeroTerminated (const VkPhysicalDeviceDriverProperties& deviceDriverProperties)
{
	if (!isNullTerminated(deviceDriverProperties.driverInfo, VK_MAX_DRIVER_INFO_SIZE))
		TCU_FAIL("Driver info is not a null-terminated string");
}

void testVersion (const VkPhysicalDeviceDriverProperties& deviceDriverProperties, deUint32 usedApiVersion)
{
	const deUint32 apiMajorVersion = VK_API_VERSION_MAJOR(usedApiVersion);
	const deUint32 apiMinorVersion = VK_API_VERSION_MINOR(usedApiVersion);

	if (deviceDriverProperties.conformanceVersion.major < apiMajorVersion ||
		(deviceDriverProperties.conformanceVersion.major == apiMajorVersion &&
		 deviceDriverProperties.conformanceVersion.minor < apiMinorVersion))
	{
		TCU_FAIL("Wrong driver conformance version (older than used API version)");
	}

	for (const VkConformanceVersion*	pConformanceVersion  = knownConformanceVersions;
										pConformanceVersion != DE_ARRAY_END(knownConformanceVersions);
									  ++pConformanceVersion)
	{
		if (deviceDriverProperties.conformanceVersion == *pConformanceVersion)
			return;
	}

	TCU_FAIL("Wrong driver conformance version (not known)");
}

tcu::TestStatus testQueryProperties (Context& context, const TestType testType)
{
	// Query the driver properties
	const VkPhysicalDevice				physDevice			= context.getPhysicalDevice();
	const int							memsetPattern		= 0xaa;
	VkPhysicalDeviceProperties2			deviceProperties2;
	VkPhysicalDeviceDriverProperties	deviceDriverProperties;

	deMemset(&deviceDriverProperties, memsetPattern, sizeof(deviceDriverProperties));
	deviceDriverProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
	deviceDriverProperties.pNext = DE_NULL;

	deMemset(&deviceProperties2, memsetPattern, sizeof(deviceProperties2));
	deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
	deviceProperties2.pNext = &deviceDriverProperties;

	context.getInstanceInterface().getPhysicalDeviceProperties2(physDevice, &deviceProperties2);

	// Verify the returned values
	switch (testType)
	{
		case TEST_TYPE_DRIVER_ID_MATCH:			testDriverMatch			(deviceDriverProperties);								break;
		case TEST_TYPE_NAME_IS_NOT_EMPTY:		testNameIsNotEmpty		(deviceDriverProperties);								break;
		case TEST_TYPE_NAME_ZERO_TERMINATED:	testNameZeroTerminated	(deviceDriverProperties);								break;
		case TEST_TYPE_INFO_ZERO_TERMINATED:	testInfoZeroTerminated	(deviceDriverProperties);								break;
		case TEST_TYPE_VERSION:					testVersion				(deviceDriverProperties, context.getUsedApiVersion());	break;
		default:								TCU_THROW(InternalError, "Unknown test type specified");
	}

	return tcu::TestStatus::pass("Pass");
}

void createTestCases (tcu::TestCaseGroup* group)
{
	addFunctionCase(group, "driver_id_match",		"Check driverID is supported",					checkSupport,	testQueryProperties,	TEST_TYPE_DRIVER_ID_MATCH);
	addFunctionCase(group, "name_is_not_empty",		"Check name field is not empty",				checkSupport,	testQueryProperties,	TEST_TYPE_NAME_IS_NOT_EMPTY);
	addFunctionCase(group, "name_zero_terminated",	"Check name field is zero-terminated",			checkSupport,	testQueryProperties,	TEST_TYPE_NAME_ZERO_TERMINATED);
	addFunctionCase(group, "info_zero_terminated",	"Check info field is zero-terminated",			checkSupport,	testQueryProperties,	TEST_TYPE_INFO_ZERO_TERMINATED);
	addFunctionCase(group, "conformance_version",	"Check conformanceVersion reported by driver",	checkSupport,	testQueryProperties,	TEST_TYPE_VERSION);
}

} // anonymous

tcu::TestCaseGroup*	createDriverPropertiesTests(tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "driver_properties", "VK_KHR_driver_properties tests", createTestCases);
}

} // api
} // vkt
<commit_msg>Update known conformance version for 1.3.4.0<commit_after>/*-------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2018 Advanced Micro Devices, Inc.
* Copyright (c) 2018 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief VK_KHR_driver_properties tests
*//*--------------------------------------------------------------------*/

#include "vktApiDriverPropertiesTests.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkKnownDriverIds.inl"

using namespace vk;

namespace vkt
{
namespace api
{
namespace
{

enum TestType
{
	TEST_TYPE_DRIVER_ID_MATCH			= 0,
	TEST_TYPE_NAME_IS_NOT_EMPTY,
	TEST_TYPE_NAME_ZERO_TERMINATED,
	TEST_TYPE_INFO_ZERO_TERMINATED,
	TEST_TYPE_VERSION,
};

static const VkConformanceVersion knownConformanceVersions[] =
{
#ifndef CTS_USES_VULKANSC
	makeConformanceVersion(1, 3, 4, 0),
	makeConformanceVersion(1, 3, 3, 1),
	makeConformanceVersion(1, 3, 3, 0),
	makeConformanceVersion(1, 3, 2, 0),
	makeConformanceVersion(1, 3, 1, 1),
	makeConformanceVersion(1, 3, 1, 0),
	makeConformanceVersion(1, 3, 0, 0),
	makeConformanceVersion(1, 2, 8, 0),
	makeConformanceVersion(1, 2, 7, 2),
	makeConformanceVersion(1, 2, 7, 1),
	makeConformanceVersion(1, 2, 7, 0),
	makeConformanceVersion(1, 2, 6, 2),
	makeConformanceVersion(1, 2, 6, 1),
	makeConformanceVersion(1, 2, 6, 0),
	makeConformanceVersion(1, 2, 5, 2),
	makeConformanceVersion(1, 2, 5, 1),
	makeConformanceVersion(1, 2, 5, 0),
	makeConformanceVersion(1, 2, 4, 1),
	makeConformanceVersion(1, 2, 4, 0),
	makeConformanceVersion(1, 2, 3, 3),
	makeConformanceVersion(1, 2, 3, 2),
	makeConformanceVersion(1, 2, 3, 1),
	makeConformanceVersion(1, 2, 3, 0),
	makeConformanceVersion(1, 2, 2, 2),
	makeConformanceVersion(1, 2, 2, 1),
	makeConformanceVersion(1, 2, 2, 0),
	makeConformanceVersion(1, 2, 1, 2),
	makeConformanceVersion(1, 2, 1, 1),
	makeConformanceVersion(1, 2, 1, 0),
	makeConformanceVersion(1, 2, 0, 2),
	makeConformanceVersion(1, 2, 0, 1),
	makeConformanceVersion(1, 2, 0, 0),
	makeConformanceVersion(1, 1, 6, 3),
	makeConformanceVersion(1, 1, 6, 2),
	makeConformanceVersion(1, 1, 6, 1),
	makeConformanceVersion(1, 1, 6, 0),
	makeConformanceVersion(1, 1, 5, 2),
	makeConformanceVersion(1, 1, 5, 1),
	makeConformanceVersion(1, 1, 5, 0),
	makeConformanceVersion(1, 1, 4, 3),
	makeConformanceVersion(1, 1, 4, 2),
	makeConformanceVersion(1, 1, 4, 1),
	makeConformanceVersion(1, 1, 4, 0),
	makeConformanceVersion(1, 1, 3, 3),
	makeConformanceVersion(1, 1, 3, 2),
	makeConformanceVersion(1, 1, 3, 1),
	makeConformanceVersion(1, 1, 3, 0),
#else
	makeConformanceVersion(1, 0, 1, 0),
	makeConformanceVersion(1, 0, 0, 0),
#endif // CTS_USES_VULKANSC
};

DE_INLINE bool isNullTerminated(const char* str, const deUint32 maxSize)
{
	return deStrnlen(str, maxSize) < maxSize;
}

DE_INLINE bool operator==(const VkConformanceVersion& a, const VkConformanceVersion& b)
{
	return ((a.major == b.major)		&&
			(a.minor == b.minor)		&&
			(a.subminor == b.subminor)	&&
			(a.patch == b.patch));
}

void checkSupport (Context& context, const TestType config)
{
	DE_UNREF(config);
	context.requireDeviceFunctionality("VK_KHR_driver_properties");
}

void testDriverMatch (const VkPhysicalDeviceDriverProperties& deviceDriverProperties)
{
	for (deUint32 driverNdx = 0; driverNdx < DE_LENGTH_OF_ARRAY(driverIds); driverNdx++)
	{
		if (deviceDriverProperties.driverID == driverIds[driverNdx].id)
			return;
	}

	TCU_FAIL("Driver ID did not match any known driver");
}

void testNameIsNotEmpty (const VkPhysicalDeviceDriverProperties& deviceDriverProperties)
{
	if (deviceDriverProperties.driverName[0] == 0)
		TCU_FAIL("Driver name is empty");
}

void testNameZeroTerminated (const VkPhysicalDeviceDriverProperties& deviceDriverProperties)
{
	if (!isNullTerminated(deviceDriverProperties.driverName, VK_MAX_DRIVER_NAME_SIZE))
		TCU_FAIL("Driver name is not a null-terminated string");
}

void testInfoZeroTerminated (const VkPhysicalDeviceDriverProperties& deviceDriverProperties)
{
	if (!isNullTerminated(deviceDriverProperties.driverInfo, VK_MAX_DRIVER_INFO_SIZE))
		TCU_FAIL("Driver info is not a null-terminated string");
}

void testVersion (const VkPhysicalDeviceDriverProperties& deviceDriverProperties, deUint32 usedApiVersion)
{
	const deUint32 apiMajorVersion = VK_API_VERSION_MAJOR(usedApiVersion);
	const deUint32 apiMinorVersion = VK_API_VERSION_MINOR(usedApiVersion);

	if (deviceDriverProperties.conformanceVersion.major < apiMajorVersion ||
		(deviceDriverProperties.conformanceVersion.major == apiMajorVersion &&
		 deviceDriverProperties.conformanceVersion.minor < apiMinorVersion))
	{
		TCU_FAIL("Wrong driver conformance version (older than used API version)");
	}

	for (const VkConformanceVersion*	pConformanceVersion  = knownConformanceVersions;
										pConformanceVersion != DE_ARRAY_END(knownConformanceVersions);
									  ++pConformanceVersion)
	{
		if (deviceDriverProperties.conformanceVersion == *pConformanceVersion)
			return;
	}

	TCU_FAIL("Wrong driver conformance version (not known)");
}

tcu::TestStatus testQueryProperties (Context& context, const TestType testType)
{
	// Query the driver properties
	const VkPhysicalDevice				physDevice			= context.getPhysicalDevice();
	const int							memsetPattern		= 0xaa;
	VkPhysicalDeviceProperties2			deviceProperties2;
	VkPhysicalDeviceDriverProperties	deviceDriverProperties;

	deMemset(&deviceDriverProperties, memsetPattern, sizeof(deviceDriverProperties));
	deviceDriverProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
	deviceDriverProperties.pNext = DE_NULL;

	deMemset(&deviceProperties2, memsetPattern, sizeof(deviceProperties2));
	deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
	deviceProperties2.pNext = &deviceDriverProperties;

	context.getInstanceInterface().getPhysicalDeviceProperties2(physDevice, &deviceProperties2);

	// Verify the returned values
	switch (testType)
	{
		case TEST_TYPE_DRIVER_ID_MATCH:			testDriverMatch			(deviceDriverProperties);								break;
		case TEST_TYPE_NAME_IS_NOT_EMPTY:		testNameIsNotEmpty		(deviceDriverProperties);								break;
		case TEST_TYPE_NAME_ZERO_TERMINATED:	testNameZeroTerminated	(deviceDriverProperties);								break;
		case TEST_TYPE_INFO_ZERO_TERMINATED:	testInfoZeroTerminated	(deviceDriverProperties);								break;
		case TEST_TYPE_VERSION:					testVersion				(deviceDriverProperties, context.getUsedApiVersion());	break;
		default:								TCU_THROW(InternalError, "Unknown test type specified");
	}

	return tcu::TestStatus::pass("Pass");
}

void createTestCases (tcu::TestCaseGroup* group)
{
	addFunctionCase(group, "driver_id_match",		"Check driverID is supported",					checkSupport,	testQueryProperties,	TEST_TYPE_DRIVER_ID_MATCH);
	addFunctionCase(group, "name_is_not_empty",		"Check name field is not empty",				checkSupport,	testQueryProperties,	TEST_TYPE_NAME_IS_NOT_EMPTY);
	addFunctionCase(group, "name_zero_terminated",	"Check name field is zero-terminated",			checkSupport,	testQueryProperties,	TEST_TYPE_NAME_ZERO_TERMINATED);
	addFunctionCase(group, "info_zero_terminated",	"Check info field is zero-terminated",			checkSupport,	testQueryProperties,	TEST_TYPE_INFO_ZERO_TERMINATED);
	addFunctionCase(group, "conformance_version",	"Check conformanceVersion reported by driver",	checkSupport,	testQueryProperties,	TEST_TYPE_VERSION);
}

} // anonymous

tcu::TestCaseGroup*	createDriverPropertiesTests(tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "driver_properties", "VK_KHR_driver_properties tests", createTestCases);
}

} // api
} // vkt
<|endoftext|>


<commit_before>/***
 * @file lbfgs_test.cc
 *
 * Tests the L-BFGS optimizer on a couple test functions.
 *
 * @author Ryan Curtin (gth671b@mail.gatech.edu)
 */

#include <fastlib/fastlib.h>
#include "lbfgs.h"
#include "test_functions.h"

using namespace mlpack::optimization;
using namespace mlpack::optimization::test;

//
// I do not like this test infrastructure.  We need to design something better
// (or use something that someone else has designed that is better).
//

bool TestRosenbrockFunction() {
  NOTIFY("Testing Rosenbrock function...");

  RosenbrockFunction f;
  L_BFGS<RosenbrockFunction> lbfgs(f, 10);

  arma::vec coords = f.GetInitialPoint();
  if(!lbfgs.Optimize(0, coords))
    NOTIFY("Optimization reported failure.");

  double final_value = f.Evaluate(coords);

  NOTIFY("Final objective value is %lf at (%lf, %lf)",
    final_value, coords[0], coords[1]);

  if((std::abs(final_value) <= 1e-5) &&
     (std::abs(coords[0] - 1) <= 1e-5) &&
     (std::abs(coords[1] - 1) <= 1e-5))
    return true;
  else
    return false;
}

bool TestWoodFunction() {
  NOTIFY("Testing Wood function...");

  WoodFunction f;
  L_BFGS<WoodFunction> lbfgs(f, 10);

  arma::vec coords = f.GetInitialPoint();
  if(!lbfgs.Optimize(0, coords))
    NOTIFY("Optimization reported failure.");

  double final_value = f.Evaluate(coords);

  NOTIFY("Final objective value is %lf at (%lf, %lf, %lf, %lf)",
    final_value, coords[0], coords[1], coords[2], coords[3]);

  if((std::abs(final_value) <= 1e-5) &&
     (std::abs(coords[0] - 1) <= 1e-5) &&
     (std::abs(coords[1] - 1) <= 1e-5) &&
     (std::abs(coords[2] - 1) <= 1e-5) &&
     (std::abs(coords[3] - 1) <= 1e-5))
    return true;
  else
    return false;
}

bool TestGeneralizedRosenbrockFunction() {
  for (int i = 2; i < 10; i++) {
    // Dimension: powers of 2
    int dim = std::pow(2, i);

    NOTIFY("Testing GeneralizedRosenbrockFunction (%d dimensions)...", dim);

    GeneralizedRosenbrockFunction f(dim);
    L_BFGS<GeneralizedRosenbrockFunction> lbfgs(f, 20);

    arma::vec coords = f.GetInitialPoint();
    if(!lbfgs.Optimize(0, coords))
      NOTIFY("Optimization reported failure.");

    double final_value = f.Evaluate(coords);

    NOTIFY("Final objective value is %lf.", final_value);

    bool correct = true;
    for (int j = 0; j < dim; j++) {
      if (std::abs(coords[j] - 1) > 1e-5) {
        correct = false;
        break;
      }
    }
    if (std::abs(final_value) > 1e-5)
      correct = false;

    if (correct)
      NOTIFY("Test passed.");
    else
      FATAL("Test failed!");
  }

  return true;
};

bool TestRosenbrockWoodFunction() {
  NOTIFY("Testing Rosenbrock-Wood combined function...");

  RosenbrockWoodFunction f;
  L_BFGS<RosenbrockWoodFunction> lbfgs(f, 10);

  arma::mat coords = f.GetInitialPoint();
  if(!lbfgs.Optimize(0, coords))
    NOTIFY("Optimization reported failure.");

  double final_value = f.Evaluate(coords);

  NOTIFY("Final objective value is %lf at", final_value);
  NOTIFY("  [[%lf, %lf, %lf, %lf]", coords[0, 0], coords[1, 0], coords[2, 0],
      coords[3, 0]);
  NOTIFY("   [%lf, %lf, %lf, %lf]]", coords[0, 1], coords[1, 1], coords[2, 1],
      coords[3, 1]);

  if((std::abs(final_value) <= 1e-5) &&
     (std::abs(coords[0, 0] - 1) <= 1e-5) &&
     (std::abs(coords[1, 0] - 1) <= 1e-5) &&
     (std::abs(coords[2, 0] - 1) <= 1e-5) &&
     (std::abs(coords[3, 0] - 1) <= 1e-5) &&
     (std::abs(coords[0, 1] - 1) <= 1e-5) &&
     (std::abs(coords[1, 1] - 1) <= 1e-5) &&
     (std::abs(coords[2, 1] - 1) <= 1e-5) &&
     (std::abs(coords[3, 1] - 1) <= 1e-5))
    return true;
  else
    return false;
}

int main(int argc, char* argv[]) {
  fx_init(argc, argv, NULL);

  if(!TestRosenbrockFunction())
    FATAL("Test failed!");
  else
    NOTIFY("Test passed.");

  if(!TestWoodFunction())
    FATAL("Test failed!");
  else
    NOTIFY("Test passed.");

  TestGeneralizedRosenbrockFunction();

  if(!TestRosenbrockWoodFunction())
    FATAL("Test failed!");
  else
    NOTIFY("Test passed.");

  fx_done(NULL);
}
<commit_msg>Fix formatting error.<commit_after>/***
 * @file lbfgs_test.cc
 *
 * Tests the L-BFGS optimizer on a couple test functions.
 *
 * @author Ryan Curtin (gth671b@mail.gatech.edu)
 */

#include <fastlib/fastlib.h>
#include "lbfgs.h"
#include "test_functions.h"

using namespace mlpack::optimization;
using namespace mlpack::optimization::test;

//
// I do not like this test infrastructure.  We need to design something better
// (or use something that someone else has designed that is better).
//

bool TestRosenbrockFunction() {
  NOTIFY("Testing Rosenbrock function...");

  RosenbrockFunction f;
  L_BFGS<RosenbrockFunction> lbfgs(f, 10);

  arma::vec coords = f.GetInitialPoint();
  if(!lbfgs.Optimize(0, coords))
    NOTIFY("Optimization reported failure.");

  double final_value = f.Evaluate(coords);

  NOTIFY("Final objective value is %lf at (%lf, %lf)",
      final_value, coords[0], coords[1]);

  if((std::abs(final_value) <= 1e-5) &&
     (std::abs(coords[0] - 1) <= 1e-5) &&
     (std::abs(coords[1] - 1) <= 1e-5))
    return true;
  else
    return false;
}

bool TestWoodFunction() {
  NOTIFY("Testing Wood function...");

  WoodFunction f;
  L_BFGS<WoodFunction> lbfgs(f, 10);

  arma::vec coords = f.GetInitialPoint();
  if(!lbfgs.Optimize(0, coords))
    NOTIFY("Optimization reported failure.");

  double final_value = f.Evaluate(coords);

  NOTIFY("Final objective value is %lf at (%lf, %lf, %lf, %lf)",
    final_value, coords[0], coords[1], coords[2], coords[3]);

  if((std::abs(final_value) <= 1e-5) &&
     (std::abs(coords[0] - 1) <= 1e-5) &&
     (std::abs(coords[1] - 1) <= 1e-5) &&
     (std::abs(coords[2] - 1) <= 1e-5) &&
     (std::abs(coords[3] - 1) <= 1e-5))
    return true;
  else
    return false;
}

bool TestGeneralizedRosenbrockFunction() {
  for (int i = 2; i < 10; i++) {
    // Dimension: powers of 2
    int dim = std::pow(2, i);

    NOTIFY("Testing GeneralizedRosenbrockFunction (%d dimensions)...", dim);

    GeneralizedRosenbrockFunction f(dim);
    L_BFGS<GeneralizedRosenbrockFunction> lbfgs(f, 20);

    arma::vec coords = f.GetInitialPoint();
    if(!lbfgs.Optimize(0, coords))
      NOTIFY("Optimization reported failure.");

    double final_value = f.Evaluate(coords);

    NOTIFY("Final objective value is %lf.", final_value);

    bool correct = true;
    for (int j = 0; j < dim; j++) {
      if (std::abs(coords[j] - 1) > 1e-5) {
        correct = false;
        break;
      }
    }
    if (std::abs(final_value) > 1e-5)
      correct = false;

    if (correct)
      NOTIFY("Test passed.");
    else
      FATAL("Test failed!");
  }

  return true;
};

bool TestRosenbrockWoodFunction() {
  NOTIFY("Testing Rosenbrock-Wood combined function...");

  RosenbrockWoodFunction f;
  L_BFGS<RosenbrockWoodFunction> lbfgs(f, 10);

  arma::mat coords = f.GetInitialPoint();
  if(!lbfgs.Optimize(0, coords))
    NOTIFY("Optimization reported failure.");

  double final_value = f.Evaluate(coords);

  NOTIFY("Final objective value is %lf at", final_value);
  NOTIFY("  [[%lf, %lf, %lf, %lf]", coords[0, 0], coords[1, 0], coords[2, 0],
      coords[3, 0]);
  NOTIFY("   [%lf, %lf, %lf, %lf]]", coords[0, 1], coords[1, 1], coords[2, 1],
      coords[3, 1]);

  if((std::abs(final_value) <= 1e-5) &&
     (std::abs(coords[0, 0] - 1) <= 1e-5) &&
     (std::abs(coords[1, 0] - 1) <= 1e-5) &&
     (std::abs(coords[2, 0] - 1) <= 1e-5) &&
     (std::abs(coords[3, 0] - 1) <= 1e-5) &&
     (std::abs(coords[0, 1] - 1) <= 1e-5) &&
     (std::abs(coords[1, 1] - 1) <= 1e-5) &&
     (std::abs(coords[2, 1] - 1) <= 1e-5) &&
     (std::abs(coords[3, 1] - 1) <= 1e-5))
    return true;
  else
    return false;
}

int main(int argc, char* argv[]) {
  fx_init(argc, argv, NULL);

  if(!TestRosenbrockFunction())
    FATAL("Test failed!");
  else
    NOTIFY("Test passed.");

  if(!TestWoodFunction())
    FATAL("Test failed!");
  else
    NOTIFY("Test passed.");

  TestGeneralizedRosenbrockFunction();

  if(!TestRosenbrockWoodFunction())
    FATAL("Test failed!");
  else
    NOTIFY("Test passed.");

  fx_done(NULL);
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/video_coding/main/source/decoding_state.h"
#include "modules/video_coding/main/source/frame_buffer.h"
#include "modules/video_coding/main/source/jitter_buffer_common.h"
#include "modules/video_coding/main/source/packet.h"

#include "modules/interface/module_common_types.h"

namespace webrtc {

VCMDecodingState::VCMDecodingState()
    : sequence_num_(0),
      time_stamp_(0),
      picture_id_(kNoPictureId),
      temporal_id_(kNoTemporalIdx),
      tl0_pic_id_(kNoTl0PicIdx),
      full_sync_(true),
      init_(true) {}

VCMDecodingState::~VCMDecodingState() {}

void VCMDecodingState::Reset() {
  // TODO(mikhal): Verify - not always would want to reset the sync
  sequence_num_ = 0;
  time_stamp_ = 0;
  picture_id_ = kNoPictureId;
  temporal_id_ = kNoTemporalIdx;
  tl0_pic_id_ = kNoTl0PicIdx;
  full_sync_ = true;
  init_ = true;
}

uint32_t VCMDecodingState::time_stamp() const {
  return time_stamp_;
}

uint16_t VCMDecodingState::sequence_num() const {
  return sequence_num_;
}

bool VCMDecodingState::IsOldFrame(const VCMFrameBuffer* frame) const {
  assert(frame != NULL);
  if (init_)
    return false;
  return (LatestTimestamp(time_stamp_, frame->TimeStamp(), NULL)
          == time_stamp_);
}

bool VCMDecodingState::IsOldPacket(const VCMPacket* packet) const {
  assert(packet != NULL);
  if (init_)
    return false;
  return (LatestTimestamp(time_stamp_, packet->timestamp, NULL)
           == time_stamp_);
}

void VCMDecodingState::SetState(const VCMFrameBuffer* frame) {
  assert(frame != NULL && frame->GetHighSeqNum() >= 0);
  UpdateSyncState(frame);
  sequence_num_ = static_cast<uint16_t>(frame->GetHighSeqNum());
  time_stamp_ = frame->TimeStamp();
  picture_id_ = frame->PictureId();
  temporal_id_ = frame->TemporalId();
  tl0_pic_id_ = frame->Tl0PicId();
  init_ = false;
}

void VCMDecodingState::SetStateOneBack(const VCMFrameBuffer* frame) {
  assert(frame != NULL && frame->GetHighSeqNum() >= 0);
  sequence_num_ = static_cast <uint16_t>(frame->GetHighSeqNum()) - 1u;
  time_stamp_ = frame->TimeStamp() - 1u;
  temporal_id_ = frame->TemporalId();
  if (frame->PictureId() != kNoPictureId) {
    if (frame->PictureId() == 0)
      picture_id_ = 0x7FFF;
    else
      picture_id_ =  frame->PictureId() - 1;
  }
  if (frame->Tl0PicId() != kNoTl0PicIdx) {
    if (frame->Tl0PicId() == 0)
      tl0_pic_id_ = 0x00FF;
    else
      tl0_pic_id_ = frame->Tl0PicId() - 1;
  }
  init_ = false;
}

void VCMDecodingState::UpdateEmptyPacket(const VCMPacket* packet) {
  assert(packet != NULL);
  if (packet->sizeBytes == 0 && packet->timestamp == time_stamp_) {
    // Empty packet (sizeBytes = 0), make sure we update the last
    // decoded sequence number.
    sequence_num_ = LatestSequenceNumber(packet->seqNum, sequence_num_, NULL);
  }
}

void VCMDecodingState::SetSeqNum(uint16_t new_seq_num) {
  sequence_num_ = new_seq_num;
}

bool VCMDecodingState::init() const {
  return init_;
}

bool VCMDecodingState::full_sync() const {
  return full_sync_;
}

void VCMDecodingState::UpdateSyncState(const VCMFrameBuffer* frame) {
  if (init_)
    return;
  if (frame->TemporalId() == kNoTemporalIdx ||
      frame->Tl0PicId() == kNoTl0PicIdx) {
    full_sync_ = true;
  } else if (frame->FrameType() == kVideoFrameKey ||
             frame->NonReference()) {
    full_sync_ = true;
  } else if (full_sync_) {
    // Verify that we are still in sync.
    // Sync will be broken if continuity is true for layers but not for the
    // other methods (PictureId and SeqNum).
    if (!ContinuousPictureId(frame->PictureId()) &&
        !ContinuousSeqNum(static_cast<uint16_t>(frame->GetLowSeqNum()))) {
      // Non-layered methods have failed.
      full_sync_ = false;
    }
  }
}

bool VCMDecodingState::ContinuousFrame(const VCMFrameBuffer* frame) const {
  // Check continuity based on the following hierarchy:
  // - Temporal layers (stop here if out of sync).
  // - Picture Id when available.
  // - Sequence numbers.
  // Return true when in initial state.
  // Note that when a method is not applicable it will return false.
  assert(frame != NULL);
  if (init_)
    return true;

  if (!ContinuousLayer(frame->TemporalId(), frame->Tl0PicId())) {
    // Base layers are not continuous or temporal layers are inactive.
    if (!full_sync_)
      return false;
    else if (!ContinuousPictureId(frame->PictureId()))
      return ContinuousSeqNum(static_cast<uint16_t>(frame->GetLowSeqNum()));
  }
  return true;
}

bool VCMDecodingState::ContinuousPictureId(int picture_id) const {
  // First, check if applicable.
  if (picture_id == kNoPictureId || picture_id_ == kNoPictureId)
    return false;
  uint16_t local_pic_id = static_cast<uint16_t>(picture_id_);
  uint16_t new_pic_id = static_cast<uint16_t>(picture_id);

  if (new_pic_id < local_pic_id) {
    // Wrap
    if (local_pic_id >= (1 << 8)) {
      // 15 bits used for picture id
      return (((local_pic_id + 1) % 0x7FFF) == new_pic_id);
    } else {
      // 7 bits used for picture id
      return (((local_pic_id + 1) % 0x7F) == new_pic_id);
    }
  }
  // No wrap
  return (local_pic_id + 1 == new_pic_id);
}

bool VCMDecodingState::ContinuousSeqNum(uint16_t seq_num) const {
  return (seq_num == static_cast<uint16_t>(sequence_num_ + 1));
}

bool VCMDecodingState::ContinuousLayer(int temporal_id,
                                       int tl0_pic_id) const {
  // First, check if applicable.
  if (temporal_id == kNoTemporalIdx || tl0_pic_id == kNoTl0PicIdx)
    return false;
  // If this is the first frame to use temporal layers, make sure we start
  // from base.
  else if (tl0_pic_id_ == kNoTl0PicIdx && temporal_id_ == kNoTemporalIdx &&
           temporal_id == 0)
    return true;

  // Current implementation: applicable for base layer only.
  if (temporal_id != 0)
    return false;
  return (static_cast<uint8_t>(tl0_pic_id_ + 1) ==
      static_cast<uint8_t>(tl0_pic_id));
}

}  // namespace webrtc
<commit_msg>video_coding: Updating sync state based on the layer flag Review URL: http://webrtc-codereview.appspot.com/333004<commit_after>/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/video_coding/main/source/decoding_state.h"
#include "modules/video_coding/main/source/frame_buffer.h"
#include "modules/video_coding/main/source/jitter_buffer_common.h"
#include "modules/video_coding/main/source/packet.h"

#include "modules/interface/module_common_types.h"

namespace webrtc {

VCMDecodingState::VCMDecodingState()
    : sequence_num_(0),
      time_stamp_(0),
      picture_id_(kNoPictureId),
      temporal_id_(kNoTemporalIdx),
      tl0_pic_id_(kNoTl0PicIdx),
      full_sync_(true),
      init_(true) {}

VCMDecodingState::~VCMDecodingState() {}

void VCMDecodingState::Reset() {
  // TODO(mikhal): Verify - not always would want to reset the sync
  sequence_num_ = 0;
  time_stamp_ = 0;
  picture_id_ = kNoPictureId;
  temporal_id_ = kNoTemporalIdx;
  tl0_pic_id_ = kNoTl0PicIdx;
  full_sync_ = true;
  init_ = true;
}

uint32_t VCMDecodingState::time_stamp() const {
  return time_stamp_;
}

uint16_t VCMDecodingState::sequence_num() const {
  return sequence_num_;
}

bool VCMDecodingState::IsOldFrame(const VCMFrameBuffer* frame) const {
  assert(frame != NULL);
  if (init_)
    return false;
  return (LatestTimestamp(time_stamp_, frame->TimeStamp(), NULL)
          == time_stamp_);
}

bool VCMDecodingState::IsOldPacket(const VCMPacket* packet) const {
  assert(packet != NULL);
  if (init_)
    return false;
  return (LatestTimestamp(time_stamp_, packet->timestamp, NULL)
           == time_stamp_);
}

void VCMDecodingState::SetState(const VCMFrameBuffer* frame) {
  assert(frame != NULL && frame->GetHighSeqNum() >= 0);
  UpdateSyncState(frame);
  sequence_num_ = static_cast<uint16_t>(frame->GetHighSeqNum());
  time_stamp_ = frame->TimeStamp();
  picture_id_ = frame->PictureId();
  temporal_id_ = frame->TemporalId();
  tl0_pic_id_ = frame->Tl0PicId();
  init_ = false;
}

void VCMDecodingState::SetStateOneBack(const VCMFrameBuffer* frame) {
  assert(frame != NULL && frame->GetHighSeqNum() >= 0);
  sequence_num_ = static_cast <uint16_t>(frame->GetHighSeqNum()) - 1u;
  time_stamp_ = frame->TimeStamp() - 1u;
  temporal_id_ = frame->TemporalId();
  if (frame->PictureId() != kNoPictureId) {
    if (frame->PictureId() == 0)
      picture_id_ = 0x7FFF;
    else
      picture_id_ =  frame->PictureId() - 1;
  }
  if (frame->Tl0PicId() != kNoTl0PicIdx) {
    if (frame->Tl0PicId() == 0)
      tl0_pic_id_ = 0x00FF;
    else
      tl0_pic_id_ = frame->Tl0PicId() - 1;
  }
  init_ = false;
}

void VCMDecodingState::UpdateEmptyPacket(const VCMPacket* packet) {
  assert(packet != NULL);
  if (packet->sizeBytes == 0 && packet->timestamp == time_stamp_) {
    // Empty packet (sizeBytes = 0), make sure we update the last
    // decoded sequence number.
    sequence_num_ = LatestSequenceNumber(packet->seqNum, sequence_num_, NULL);
  }
}

void VCMDecodingState::SetSeqNum(uint16_t new_seq_num) {
  sequence_num_ = new_seq_num;
}

bool VCMDecodingState::init() const {
  return init_;
}

bool VCMDecodingState::full_sync() const {
  return full_sync_;
}

void VCMDecodingState::UpdateSyncState(const VCMFrameBuffer* frame) {
  if (init_)
    return;
  if (frame->TemporalId() == kNoTemporalIdx ||
      frame->Tl0PicId() == kNoTl0PicIdx) {
    full_sync_ = true;
  } else if (frame->FrameType() == kVideoFrameKey || frame->LayerSync()) {
    full_sync_ = true;
  } else if (full_sync_) {
    // Verify that we are still in sync.
    // Sync will be broken if continuity is true for layers but not for the
    // other methods (PictureId and SeqNum).
    if (!ContinuousPictureId(frame->PictureId()) &&
        !ContinuousSeqNum(static_cast<uint16_t>(frame->GetLowSeqNum()))) {
      // Non-layered methods have failed.
      full_sync_ = false;
    }
  }
}

bool VCMDecodingState::ContinuousFrame(const VCMFrameBuffer* frame) const {
  // Check continuity based on the following hierarchy:
  // - Temporal layers (stop here if out of sync).
  // - Picture Id when available.
  // - Sequence numbers.
  // Return true when in initial state.
  // Note that when a method is not applicable it will return false.
  assert(frame != NULL);
  if (init_)
    return true;

  if (!ContinuousLayer(frame->TemporalId(), frame->Tl0PicId())) {
    // Base layers are not continuous or temporal layers are inactive.
    // In the presence of temporal layers, check for Picture ID/sequence number
    // continuity if sync can be restored by this frame.
    if (!full_sync_ && !frame->LayerSync())
      return false;
    else if (!ContinuousPictureId(frame->PictureId()))
      return ContinuousSeqNum(static_cast<uint16_t>(frame->GetLowSeqNum()));
  }
  return true;
}

bool VCMDecodingState::ContinuousPictureId(int picture_id) const {
  // First, check if applicable.
  if (picture_id == kNoPictureId || picture_id_ == kNoPictureId)
    return false;
  uint16_t local_pic_id = static_cast<uint16_t>(picture_id_);
  uint16_t new_pic_id = static_cast<uint16_t>(picture_id);

  if (new_pic_id < local_pic_id) {
    // Wrap
    if (local_pic_id >= (1 << 8)) {
      // 15 bits used for picture id
      return (((local_pic_id + 1) % 0x7FFF) == new_pic_id);
    } else {
      // 7 bits used for picture id
      return (((local_pic_id + 1) % 0x7F) == new_pic_id);
    }
  }
  // No wrap
  return (local_pic_id + 1 == new_pic_id);
}

bool VCMDecodingState::ContinuousSeqNum(uint16_t seq_num) const {
  return (seq_num == static_cast<uint16_t>(sequence_num_ + 1));
}

bool VCMDecodingState::ContinuousLayer(int temporal_id,
                                       int tl0_pic_id) const {
  // First, check if applicable.
  if (temporal_id == kNoTemporalIdx || tl0_pic_id == kNoTl0PicIdx)
    return false;
  // If this is the first frame to use temporal layers, make sure we start
  // from base.
  else if (tl0_pic_id_ == kNoTl0PicIdx && temporal_id_ == kNoTemporalIdx &&
           temporal_id == 0)
    return true;

  // Current implementation: Look for base layer continuity.
  if (temporal_id != 0)
    return false;
  return (static_cast<uint8_t>(tl0_pic_id_ + 1) ==
      static_cast<uint8_t>(tl0_pic_id));
}

}  // namespace webrtc
<|endoftext|>


<commit_before>#ifndef CMDSTAN_WRITE_PROFILING_HPP
#define CMDSTAN_WRITE_PROFILING_HPP

#include <stan/math/rev/core/profiling.hpp>
#include <stan/callbacks/writer.hpp>
#include <stan/version.hpp>
#include <string>
#include <vector>

namespace cmdstan {

/**
 * Writes the data from the map of profiles in a CSV format
 * to the supplied writer.
 *
 * @param writer object of a Stan writer class to write to.
 * @param p reference to the map of profiles
 */
void write_profiling(std::ostream& output, stan::math::profile_map& p) {
  stan::math::profile_map::iterator it;

  output << "name,thread_id,total_time,forward_time,reverse_time,chain_"
            "stack,no_chain_stack,autodiff_calls,no_autodiff_calls"
         << std::endl;
  for (it = p.begin(); it != p.end(); it++) {
    output << it->first.first << "," << it->first.second << ","
           << (it->second.get_fwd_time() + it->second.get_rev_time()) << ","
           << it->second.get_fwd_time() << "," << it->second.get_rev_time()
           << "," << it->second.get_chain_stack_used() << ","
           << it->second.get_nochain_stack_used() << ","
           << it->second.get_num_rev_passes() << ","
           << it->second.get_num_no_AD_fwd_passes() << std::endl;
  }
}
}  // namespace cmdstan
#endif
<commit_msg>Updated write profiling docs<commit_after>#ifndef CMDSTAN_WRITE_PROFILING_HPP
#define CMDSTAN_WRITE_PROFILING_HPP

#include <stan/math/rev/core/profiling.hpp>
#include <stan/callbacks/writer.hpp>
#include <stan/version.hpp>
#include <string>
#include <vector>

namespace cmdstan {

/**
 * Writes the data from the map of profiles in a CSV format
 * to the output.
 *
 * @param output stream to write output to
 * @param p reference to the map of profiles
 */
void write_profiling(std::ostream& output, stan::math::profile_map& p) {
  stan::math::profile_map::iterator it;

  output << "name,thread_id,total_time,forward_time,reverse_time,chain_"
            "stack,no_chain_stack,autodiff_calls,no_autodiff_calls"
         << std::endl;
  for (it = p.begin(); it != p.end(); it++) {
    output << it->first.first << "," << it->first.second << ","
           << (it->second.get_fwd_time() + it->second.get_rev_time()) << ","
           << it->second.get_fwd_time() << "," << it->second.get_rev_time()
           << "," << it->second.get_chain_stack_used() << ","
           << it->second.get_nochain_stack_used() << ","
           << it->second.get_num_rev_passes() << ","
           << it->second.get_num_no_AD_fwd_passes() << std::endl;
  }
}
}  // namespace cmdstan
#endif
<|endoftext|>


<commit_before>/*
 * ADIOStoMultiParticle.h
 *
 * Copyright (C) 2018 by Universitaet Stuttgart (VISUS).
 * Alle Rechte vorbehalten.
 */

#include "stdafx.h"
#include "ADIOStoMultiParticle.h"
#include "CallADIOSData.h"
#include "mmcore/moldyn/MultiParticleDataCall.h"
#include "vislib/sys/Log.h"

namespace megamol {
namespace adios {

ADIOStoMultiParticle::ADIOStoMultiParticle(void)
    : core::Module()
    , mpSlot("mpSlot", "Slot to send multi particle data.")
    , adiosSlot("adiosSlot", "Slot to request ADIOS IO") {

    this->mpSlot.SetCallback(core::moldyn::MultiParticleDataCall::ClassName(),
        core::moldyn::MultiParticleDataCall::FunctionName(0), &ADIOStoMultiParticle::getDataCallback);
    this->mpSlot.SetCallback(core::moldyn::MultiParticleDataCall::ClassName(),
        core::moldyn::MultiParticleDataCall::FunctionName(1), &ADIOStoMultiParticle::getExtentCallback);
    this->MakeSlotAvailable(&this->mpSlot);

    this->adiosSlot.SetCompatibleCall<CallADIOSDataDescription>();
    this->MakeSlotAvailable(&this->adiosSlot);
}

ADIOStoMultiParticle::~ADIOStoMultiParticle(void) { this->Release(); }

bool ADIOStoMultiParticle::create(void) { return true; }

void ADIOStoMultiParticle::release(void) {}

bool ADIOStoMultiParticle::getDataCallback(core::Call& call) {
    core::moldyn::MultiParticleDataCall* mpdc = dynamic_cast<core::moldyn::MultiParticleDataCall*>(&call);
    if (mpdc == nullptr) return false;

    CallADIOSData* cad = this->adiosSlot.CallAs<CallADIOSData>();
    if (cad == nullptr) return false;

    if (mpdc->FrameID() != currentFrame) {

        cad->setFrameIDtoLoad(mpdc->FrameID());

        if (!(*cad)(1)) {
            vislib::sys::Log::DefaultLog.WriteError("ADIOStoMultiParticle: Error during GetHeader");
            return false;
        }

        auto availVars = cad->getAvailableVars();
        if (cad->isInVars("xyz")) {
            cad->inquire("xyz");
        } else if (cad->isInVars("x") && cad->isInVars("y") && cad->isInVars("z")) {
            cad->inquire("x");
            cad->inquire("y");
            cad->inquire("z");
        } else {
			vislib::sys::Log::DefaultLog.WriteError("ADIOStoMultiParticle: No particle positions found");
			return false;
		}
        int stride = 3;
        cad->inquire("box");
        cad->inquire("p_count");
        // Radius
        if (cad->isInVars("radius")) {
            cad->inquire("radius");
            stride += 1;
        } else if (cad->isInVars("global_radius")) {
            cad->inquire("global_radius");
        }
        // Colors
        if (cad->isInVars("r")) {
            cad->inquire("r");
            cad->inquire("g");
            cad->inquire("b");
            cad->inquire("a");
            stride += 4;
        } else if (cad->isInVars("global_r")) {
            cad->inquire("global_r");
            cad->inquire("global_g");
            cad->inquire("global_b");
            cad->inquire("global_a");
        }
		// Intensity
		else if (cad->isInVars("i")) {
			cad->inquire("i");
			stride += 1;
		}
        // ID
        if (cad->isInVars("id")) {
            cad->inquire("id");
            // TODO stride with int cannot work properly
            stride += 1;
        }

        if (!(*cad)(0)) {
            vislib::sys::Log::DefaultLog.WriteError("ADIOStoMultiParticle: Error during GetData");
            return false;
        }

        std::vector<float> X;
        std::vector<float> Y;
        std::vector<float> Z;

        if (cad->isInVars("xyz")) {
            X = cad->getData("xyz")->GetAsFloat();
        } else if (cad->isInVars("x") && cad->isInVars("y") && cad->isInVars("z")) {
            X = cad->getData("x")->GetAsFloat();
            Y = cad->getData("y")->GetAsFloat();
            Z = cad->getData("z")->GetAsFloat();
        } else {
			vislib::sys::Log::DefaultLog.WriteError("ADIOStoMultiParticle: No particle positions found");
			return false;
		}
        auto box = cad->getData("box")->GetAsFloat();
        auto p_count = cad->getData("p_count")->GetAsInt();
        std::vector<float> radius;
        std::vector<float> r;
        std::vector<float> g;
        std::vector<float> b;
        std::vector<float> a;
        std::vector<int> id;
		std::vector<float> intensity;

        // Radius
        if (cad->isInVars("radius")) {
            radius = cad->getData("radius")->GetAsFloat();
        } else if (cad->isInVars("global_radius")) {
            radius = cad->getData("global_radius")->GetAsFloat();
        }
        // Colors
        if (cad->isInVars("r")) {
            r = cad->getData("r")->GetAsFloat();
            g = cad->getData("g")->GetAsFloat();
            b = cad->getData("b")->GetAsFloat();
            a = cad->getData("a")->GetAsFloat();
        } else if (cad->isInVars("global_r")) {
            r = cad->getData("global_r")->GetAsFloat();
            g = cad->getData("global_g")->GetAsFloat();
            b = cad->getData("global_b")->GetAsFloat();
            a = cad->getData("global_a")->GetAsFloat();
		} else if (cad->isInVars("i")) {
			intensity = cad->getData("i")->GetAsFloat();
			// normalizing intentsity to [0,1]
			std::vector<float>::iterator minIt = std::min_element(std::begin(intensity), std::end(intensity));
			std::vector<float>::iterator maxIt = std::max_element(std::begin(intensity), std::end(intensity));
			float minIntensity = intensity[std::distance(std::begin(intensity), minIt)];
			float maxIntensity = intensity[std::distance(std::begin(intensity), maxIt)];
			for (auto i = 0; i < intensity.size(); i++) {
				intensity[i] = (intensity[i] - minIntensity)/(maxIntensity - minIntensity);
			}
		}
        // ID
        if (cad->isInVars("id")) {
            id = cad->getData("id")->GetAsInt();
        }

        // Set bounding box
        const vislib::math::Cuboid<float> cubo(box[0], box[1], box[2], box[3], box[4], box[5]);
        mpdc->AccessBoundingBoxes().SetObjectSpaceBBox(cubo);
        mpdc->AccessBoundingBoxes().SetObjectSpaceClipBox(cubo);

        // Set particles
        const size_t particleCount = p_count[0];

        mix.clear();
        mix.resize(particleCount * stride);

        for (auto i = 0; i < particleCount; i++) {
            int pos = 0;
            if (cad->isInVars("xyz")) {
                mix[stride * i + 0] = X[3 * i + 0];
                mix[stride * i + 1] = X[3 * i + 1];
                mix[stride * i + 2] = X[3 * i + 2];
            } else {
                mix[stride * i + 0] = X[i];
                mix[stride * i + 1] = Y[i];
                mix[stride * i + 2] = Z[i];
			}
            pos += 3;
            if (cad->isInVars("radius")) {
                mix[stride * i + pos] = radius[i];
                pos += 1;
            }
            if (cad->isInVars("r")) {
                mix[stride * i + pos + 0] = r[i];
                mix[stride * i + pos + 1] = g[i];
                mix[stride * i + pos + 2] = b[i];
                mix[stride * i + pos + 3] = a[i];
			} else if (cad->isInVars("i")) {
				mix[stride * i + pos] = intensity[i];
			}
            // TODO
            // if (cad->isInVars("id")) {
        }

        mpdc->SetFrameCount(cad->getFrameCount());
        mpdc->SetDataHash(cad->getDataHash());
        mpdc->SetParticleListCount(1);
        mpdc->AccessParticles(0).SetCount(particleCount);

        auto colType = core::moldyn::SimpleSphericalParticles::COLDATA_NONE;
        auto vertType = core::moldyn::SimpleSphericalParticles::VERTDATA_FLOAT_XYZ;
        auto idType = core::moldyn::SimpleSphericalParticles::IDDATA_NONE;

        if (cad->isInVars("global_radius")) {
            mpdc->AccessParticles(0).SetGlobalRadius(radius[0]);
        } else if (cad->isInVars("radius")) {
            vertType = core::moldyn::SimpleSphericalParticles::VERTDATA_FLOAT_XYZR;
		} else {
			mpdc->AccessParticles(0).SetGlobalRadius(1.0f);
		}
        if (cad->isInVars("global_r")) {
            mpdc->AccessParticles(0).SetGlobalColour(r[0] * 255, g[0] * 255, b[0] * 255, a[0] * 255);
        } else if (cad->isInVars("r")) {
            colType = core::moldyn::SimpleSphericalParticles::COLDATA_FLOAT_RGBA;
		} else if (cad->isInVars("i")) {
			colType = core::moldyn::SimpleSphericalParticles::COLDATA_FLOAT_I;
		} else {
			mpdc->AccessParticles(0).SetGlobalColour(0.8 * 255, 0.8 * 255, 0.8 * 255, 1.0 * 255);
		}
        if (cad->isInVars("id")) {
            idType = core::moldyn::SimpleSphericalParticles::IDDATA_UINT32;
        }

        mpdc->AccessParticles(0).SetVertexData(vertType, mix.data(), stride * sizeof(float));
        mpdc->AccessParticles(0).SetColourData(colType,
            mix.data() + (vertType == core::moldyn::SimpleSphericalParticles::VERTDATA_FLOAT_XYZ ? 3 : 4),
            stride * sizeof(float));
        // mpdc->AccessParticles(0).SetIDData(idType, mix.data(), stride * sizeof(float));

        currentFrame = mpdc->FrameID();
    }
    return true;
}

bool ADIOStoMultiParticle::getExtentCallback(core::Call& call) {

    core::moldyn::MultiParticleDataCall* mpdc = dynamic_cast<core::moldyn::MultiParticleDataCall*>(&call);
    if (mpdc == nullptr) return false;

    CallADIOSData* cad = this->adiosSlot.CallAs<CallADIOSData>();
    if (cad == nullptr) return false;

    this->getDataCallback(call);

    return true;
}

} // end namespace adios
} // end namespace megamol<commit_msg>fixed empty filename case<commit_after>/*
 * ADIOStoMultiParticle.h
 *
 * Copyright (C) 2018 by Universitaet Stuttgart (VISUS).
 * Alle Rechte vorbehalten.
 */

#include "stdafx.h"
#include "ADIOStoMultiParticle.h"
#include "CallADIOSData.h"
#include "mmcore/moldyn/MultiParticleDataCall.h"
#include "vislib/sys/Log.h"

namespace megamol {
namespace adios {

ADIOStoMultiParticle::ADIOStoMultiParticle(void)
    : core::Module()
    , mpSlot("mpSlot", "Slot to send multi particle data.")
    , adiosSlot("adiosSlot", "Slot to request ADIOS IO") {

    this->mpSlot.SetCallback(core::moldyn::MultiParticleDataCall::ClassName(),
        core::moldyn::MultiParticleDataCall::FunctionName(0), &ADIOStoMultiParticle::getDataCallback);
    this->mpSlot.SetCallback(core::moldyn::MultiParticleDataCall::ClassName(),
        core::moldyn::MultiParticleDataCall::FunctionName(1), &ADIOStoMultiParticle::getExtentCallback);
    this->MakeSlotAvailable(&this->mpSlot);

    this->adiosSlot.SetCompatibleCall<CallADIOSDataDescription>();
    this->MakeSlotAvailable(&this->adiosSlot);
}

ADIOStoMultiParticle::~ADIOStoMultiParticle(void) { this->Release(); }

bool ADIOStoMultiParticle::create(void) { return true; }

void ADIOStoMultiParticle::release(void) {}

bool ADIOStoMultiParticle::getDataCallback(core::Call& call) {
    core::moldyn::MultiParticleDataCall* mpdc = dynamic_cast<core::moldyn::MultiParticleDataCall*>(&call);
    if (mpdc == nullptr) return false;

    CallADIOSData* cad = this->adiosSlot.CallAs<CallADIOSData>();
    if (cad == nullptr) return false;

    if (mpdc->FrameID() != currentFrame) {

        cad->setFrameIDtoLoad(mpdc->FrameID());

        if (!(*cad)(1)) {
            vislib::sys::Log::DefaultLog.WriteError("ADIOStoMultiParticle: Error during GetHeader");
            return false;
        }

        auto availVars = cad->getAvailableVars();
        if (cad->isInVars("xyz")) {
            cad->inquire("xyz");
        } else if (cad->isInVars("x") && cad->isInVars("y") && cad->isInVars("z")) {
            cad->inquire("x");
            cad->inquire("y");
            cad->inquire("z");
        } else {
			vislib::sys::Log::DefaultLog.WriteError("ADIOStoMultiParticle: No particle positions found");
			return false;
		}
        int stride = 3;
        cad->inquire("box");
        cad->inquire("p_count");
        // Radius
        if (cad->isInVars("radius")) {
            cad->inquire("radius");
            stride += 1;
        } else if (cad->isInVars("global_radius")) {
            cad->inquire("global_radius");
        }
        // Colors
        if (cad->isInVars("r")) {
            cad->inquire("r");
            cad->inquire("g");
            cad->inquire("b");
            cad->inquire("a");
            stride += 4;
        } else if (cad->isInVars("global_r")) {
            cad->inquire("global_r");
            cad->inquire("global_g");
            cad->inquire("global_b");
            cad->inquire("global_a");
        }
		// Intensity
		else if (cad->isInVars("i")) {
			cad->inquire("i");
			stride += 1;
		}
        // ID
        if (cad->isInVars("id")) {
            cad->inquire("id");
            // TODO stride with int cannot work properly
            stride += 1;
        }

        if (!(*cad)(0)) {
            vislib::sys::Log::DefaultLog.WriteError("ADIOStoMultiParticle: Error during GetData");
            return false;
        }

        std::vector<float> X;
        std::vector<float> Y;
        std::vector<float> Z;

        if (cad->isInVars("xyz")) {
            X = cad->getData("xyz")->GetAsFloat();
        } else if (cad->isInVars("x") && cad->isInVars("y") && cad->isInVars("z")) {
            X = cad->getData("x")->GetAsFloat();
            Y = cad->getData("y")->GetAsFloat();
            Z = cad->getData("z")->GetAsFloat();
        } else {
			vislib::sys::Log::DefaultLog.WriteError("ADIOStoMultiParticle: No particle positions found");
			return false;
		}
        auto box = cad->getData("box")->GetAsFloat();
        auto p_count = cad->getData("p_count")->GetAsInt();
        std::vector<float> radius;
        std::vector<float> r;
        std::vector<float> g;
        std::vector<float> b;
        std::vector<float> a;
        std::vector<int> id;
		std::vector<float> intensity;

        // Radius
        if (cad->isInVars("radius")) {
            radius = cad->getData("radius")->GetAsFloat();
        } else if (cad->isInVars("global_radius")) {
            radius = cad->getData("global_radius")->GetAsFloat();
        }
        // Colors
        if (cad->isInVars("r")) {
            r = cad->getData("r")->GetAsFloat();
            g = cad->getData("g")->GetAsFloat();
            b = cad->getData("b")->GetAsFloat();
            a = cad->getData("a")->GetAsFloat();
        } else if (cad->isInVars("global_r")) {
            r = cad->getData("global_r")->GetAsFloat();
            g = cad->getData("global_g")->GetAsFloat();
            b = cad->getData("global_b")->GetAsFloat();
            a = cad->getData("global_a")->GetAsFloat();
		} else if (cad->isInVars("i")) {
			intensity = cad->getData("i")->GetAsFloat();
			// normalizing intentsity to [0,1]
			std::vector<float>::iterator minIt = std::min_element(std::begin(intensity), std::end(intensity));
			std::vector<float>::iterator maxIt = std::max_element(std::begin(intensity), std::end(intensity));
			float minIntensity = intensity[std::distance(std::begin(intensity), minIt)];
			float maxIntensity = intensity[std::distance(std::begin(intensity), maxIt)];
			for (auto i = 0; i < intensity.size(); i++) {
				intensity[i] = (intensity[i] - minIntensity)/(maxIntensity - minIntensity);
			}
		}
        // ID
        if (cad->isInVars("id")) {
            id = cad->getData("id")->GetAsInt();
        }

        // Set bounding box
        const vislib::math::Cuboid<float> cubo(box[0], box[1], box[2], box[3], box[4], box[5]);
        mpdc->AccessBoundingBoxes().SetObjectSpaceBBox(cubo);
        mpdc->AccessBoundingBoxes().SetObjectSpaceClipBox(cubo);

        // Set particles
        const size_t particleCount = p_count[0];

        mix.clear();
        mix.resize(particleCount * stride);

        for (auto i = 0; i < particleCount; i++) {
            int pos = 0;
            if (cad->isInVars("xyz")) {
                mix[stride * i + 0] = X[3 * i + 0];
                mix[stride * i + 1] = X[3 * i + 1];
                mix[stride * i + 2] = X[3 * i + 2];
            } else {
                mix[stride * i + 0] = X[i];
                mix[stride * i + 1] = Y[i];
                mix[stride * i + 2] = Z[i];
			}
            pos += 3;
            if (cad->isInVars("radius")) {
                mix[stride * i + pos] = radius[i];
                pos += 1;
            }
            if (cad->isInVars("r")) {
                mix[stride * i + pos + 0] = r[i];
                mix[stride * i + pos + 1] = g[i];
                mix[stride * i + pos + 2] = b[i];
                mix[stride * i + pos + 3] = a[i];
			} else if (cad->isInVars("i")) {
				mix[stride * i + pos] = intensity[i];
			}
            // TODO
            // if (cad->isInVars("id")) {
        }

        mpdc->SetFrameCount(cad->getFrameCount());
        mpdc->SetDataHash(cad->getDataHash());
        mpdc->SetParticleListCount(1);
        mpdc->AccessParticles(0).SetCount(particleCount);

        auto colType = core::moldyn::SimpleSphericalParticles::COLDATA_NONE;
        auto vertType = core::moldyn::SimpleSphericalParticles::VERTDATA_FLOAT_XYZ;
        auto idType = core::moldyn::SimpleSphericalParticles::IDDATA_NONE;

        if (cad->isInVars("global_radius")) {
            mpdc->AccessParticles(0).SetGlobalRadius(radius[0]);
        } else if (cad->isInVars("radius")) {
            vertType = core::moldyn::SimpleSphericalParticles::VERTDATA_FLOAT_XYZR;
		} else {
			mpdc->AccessParticles(0).SetGlobalRadius(1.0f);
		}
        if (cad->isInVars("global_r")) {
            mpdc->AccessParticles(0).SetGlobalColour(r[0] * 255, g[0] * 255, b[0] * 255, a[0] * 255);
        } else if (cad->isInVars("r")) {
            colType = core::moldyn::SimpleSphericalParticles::COLDATA_FLOAT_RGBA;
		} else if (cad->isInVars("i")) {
			colType = core::moldyn::SimpleSphericalParticles::COLDATA_FLOAT_I;
		} else {
			mpdc->AccessParticles(0).SetGlobalColour(0.8 * 255, 0.8 * 255, 0.8 * 255, 1.0 * 255);
		}
        if (cad->isInVars("id")) {
            idType = core::moldyn::SimpleSphericalParticles::IDDATA_UINT32;
        }

        mpdc->AccessParticles(0).SetVertexData(vertType, mix.data(), stride * sizeof(float));
        mpdc->AccessParticles(0).SetColourData(colType,
            mix.data() + (vertType == core::moldyn::SimpleSphericalParticles::VERTDATA_FLOAT_XYZ ? 3 : 4),
            stride * sizeof(float));
        // mpdc->AccessParticles(0).SetIDData(idType, mix.data(), stride * sizeof(float));

        currentFrame = mpdc->FrameID();
    }
    return true;
}

bool ADIOStoMultiParticle::getExtentCallback(core::Call& call) {

    core::moldyn::MultiParticleDataCall* mpdc = dynamic_cast<core::moldyn::MultiParticleDataCall*>(&call);
    if (mpdc == nullptr) return false;

    CallADIOSData* cad = this->adiosSlot.CallAs<CallADIOSData>();
    if (cad == nullptr) return false;

    if (!this->getDataCallback(call)) return false;

    return true;
}

} // end namespace adios
} // end namespace megamol<|endoftext|>


<commit_before>#include "segment.h"
#include <cstdlib>

namespace oop_project {

const size_t Segment::kMaxCars = 5;

Segment::Segment(size_t capacity, Segment* prev, int ready_percent,
                 size_t num_junctions, size_t toll_pass_limit)
    : capacity_(capacity),
      enter_junction_(new Junction(num_junctions, toll_pass_limit)),
      next_(NULL),
      prev_(prev),
      ready_percent_(ready_percent) {
  size_t num_cars = rand() % kMaxCars + 1;
  cars_.resize(num_cars);
  for (size_t i = 0; i < cars_.size(); ++i) {
    size_t exit_junction = rand() % (num_junctions - enter_junction_->id()) +
                           enter_junction_->id();
    cars_[i] = new Car(exit_junction, NULL);
  }
}

Segment::~Segment() {
  for (size_t i = 0; i < cars_.size(); ++i) {
    delete cars_[i];
  }
  delete enter_junction_;
}

void Segment::Enter() {
  size_t max_allowed_cars;
  std::vector<Car*> passed_cars;
  if (prev_ != NULL) {
    max_allowed_cars = capacity_ - cars_.size();
    passed_cars = prev_->Pass(max_allowed_cars);
    cars_.insert(cars_.end(), passed_cars.begin(), passed_cars.end());
  }

  max_allowed_cars = capacity_ - cars_.size();
  passed_cars = enter_junction_->Operate(max_allowed_cars);
  cars_.insert(cars_.end(), passed_cars.begin(), passed_cars.end());
}

void Segment::Exit() {
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (cars_[i]->ready() &&
        cars_[i]->exit_junction() == enter_junction_->id() + 1) {
      delete cars_[i];
      cars_.erase(cars_.begin() + i);
    }
  }
}

void Segment::Operate() {
  Exit();
  Enter();

  std::random_shuffle(cars_.begin(), cars_.end());
  size_t num_new_ready = ready_percent_ * cars_.size() / 100;
  size_t num_changed_cars = 0;
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (num_changed_cars == num_new_ready) {
      break;
    }
    if (!cars_[i]->ready()) {
      cars_[i]->set_ready(true);
      ++num_changed_cars;
    }
  }
}

std::vector<Car*> Segment::Pass(size_t max_allowed_cars) {
  std::vector<Car*> ret;
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (ret.size() == max_allowed_cars) {
      break;
    }
    if (cars_[i]->ready() &&
        cars_[i]->exit_junction() != enter_junction_->id() + 1) {
      ret.push_back(cars_[i]);
      cars_.erase(cars_.begin() + i);
    }
  }
  return ret;
}

size_t Segment::num_cars() const {
  return cars_.size();
}

std::vector<Car*> Segment::ready_cars() const {
  std::vector<Car*> ret;
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (cars_[i]->ready()) {
      ret.push_back(cars_[i]);
    }
  }
  return ret;
}

size_t Segment::enter_junction() const {
  return enter_junction_->id();
}

void Segment::set_next(Segment* next) {
  next_ = next;
}

}  // namespace oop_project
<commit_msg>Segment: Fixed bug that generated more cars than capacity allowed<commit_after>#include "segment.h"
#include <cstdlib>

namespace oop_project {

const size_t Segment::kMaxCars = 5;

Segment::Segment(size_t capacity, Segment* prev, int ready_percent,
                 size_t num_junctions, size_t toll_pass_limit)
    : capacity_(capacity),
      enter_junction_(new Junction(num_junctions, toll_pass_limit)),
      next_(NULL),
      prev_(prev),
      ready_percent_(ready_percent) {
  size_t num_cars = std::min(capacity_, rand() % kMaxCars + 1);
  cars_.resize(num_cars);
  for (size_t i = 0; i < cars_.size(); ++i) {
    size_t exit_junction = rand() % (num_junctions - enter_junction_->id()) +
                           enter_junction_->id();
    cars_[i] = new Car(exit_junction, NULL);
  }
}

Segment::~Segment() {
  for (size_t i = 0; i < cars_.size(); ++i) {
    delete cars_[i];
  }
  delete enter_junction_;
}

void Segment::Enter() {
  size_t max_allowed_cars;
  std::vector<Car*> passed_cars;
  if (prev_ != NULL) {
    max_allowed_cars = capacity_ - cars_.size();
    passed_cars = prev_->Pass(max_allowed_cars);
    cars_.insert(cars_.end(), passed_cars.begin(), passed_cars.end());
  }

  max_allowed_cars = capacity_ - cars_.size();
  passed_cars = enter_junction_->Operate(max_allowed_cars);
  cars_.insert(cars_.end(), passed_cars.begin(), passed_cars.end());
}

void Segment::Exit() {
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (cars_[i]->ready() &&
        cars_[i]->exit_junction() == enter_junction_->id() + 1) {
      delete cars_[i];
      cars_.erase(cars_.begin() + i);
    }
  }
}

void Segment::Operate() {
  Exit();
  Enter();

  std::random_shuffle(cars_.begin(), cars_.end());
  size_t num_new_ready = ready_percent_ * cars_.size() / 100;
  size_t num_changed_cars = 0;
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (num_changed_cars == num_new_ready) {
      break;
    }
    if (!cars_[i]->ready()) {
      cars_[i]->set_ready(true);
      ++num_changed_cars;
    }
  }
}

std::vector<Car*> Segment::Pass(size_t max_allowed_cars) {
  std::vector<Car*> ret;
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (ret.size() == max_allowed_cars) {
      break;
    }
    if (cars_[i]->ready() &&
        cars_[i]->exit_junction() != enter_junction_->id() + 1) {
      ret.push_back(cars_[i]);
      cars_.erase(cars_.begin() + i);
    }
  }
  return ret;
}

size_t Segment::num_cars() const {
  return cars_.size();
}

std::vector<Car*> Segment::ready_cars() const {
  std::vector<Car*> ret;
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (cars_[i]->ready()) {
      ret.push_back(cars_[i]);
    }
  }
  return ret;
}

size_t Segment::enter_junction() const {
  return enter_junction_->id();
}

void Segment::set_next(Segment* next) {
  next_ = next;
}

}  // namespace oop_project
<|endoftext|>