<commit_before>/*
 * fMBT, free Model Based Testing tool
 * Copyright (c) 2011, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include "history_log.hh"

#include <libxml/xmlreader.h>
#ifndef LIBXML_READER_ENABLED
#error "LIBXML_READER_ENABLED is needed"
#endif

#include "helper.hh"

History_log::History_log(Log& l, std::string params) :
  History(l,params), alphabet_done(false), act(NULL), tag(NULL), c(NULL), a(NULL), file(params)
{
  separator=std::string(" ");
  anames.push_back("");
  tnames.push_back("");
  a = new Alphabet_impl(anames,tnames);
}

void History_log::processNode(xmlTextReaderPtr reader)
{
  char* name =(char*) xmlTextReaderConstName(reader);
  if (name==NULL) return;

  if (xmlTextReaderDepth(reader)>2) {
    if (!alphabet_done) {
      alphabet_done=true;
      if (model_from_log) {
	l.ref();
	myes=new Model_yes(l,"");
	myes->set_model(a);
	c->set_model(myes);
      }
    }
  }

  if (!alphabet_done) {
    if ((xmlTextReaderDepth(reader)==2) &&
	(strcmp((const char*)name,"action_name")==0)) {
      char* aname=unescape_string((char*)xmlTextReaderGetAttribute(reader,(xmlChar*)"name"));
      if (aname!=NULL) {
	anames.push_back(aname);
	free(aname);
      }
    }

    if ((xmlTextReaderDepth(reader)==2) &&
	(strcmp((const char*)name,"tag_name")==0)) {
      char* tname=unescape_string((char*)xmlTextReaderGetAttribute(reader,(xmlChar*)"name"));
      if (tname!=NULL) {
	tnames.push_back(tname);
	free(tname);
      }
    }

  }

  if ((xmlTextReaderDepth(reader)==3) &&
      (strcmp((const char*)name,"current_time")==0)) {
    char* time=(char*)xmlTextReaderGetAttribute(reader,(xmlChar*)"time");
    char* endp;
    long sec = strtol(time, &endp, 10);
    if (*endp=='.') {
      long usec=strtol(endp+1, &endp, 10);
      current_time.tv_sec=sec;
      current_time.tv_usec=usec;
    }
    free(time);
  }

  if ((xmlTextReaderDepth(reader)==3) &&
      (strcmp((const char*)name,"action")==0)) {
    // action
    if (act) {
      send_action();
    }
    act=unescape_string((char*)xmlTextReaderGetAttribute(reader,(xmlChar*)"name"));
    log.debug("FOUND ACT %s\n",act);
    send_action();
  }

  if ((xmlTextReaderDepth(reader)==3) &&
      (strcmp((const char*)name,"tags")==0)) {
    // tags
    if (tag) {
      free(tag);
    }
    tag=(char*)xmlTextReaderGetAttribute(reader,(xmlChar*)"enabled");
    log.debug("FOUND TAG %s\n",tag);
  }

  if ((xmlTextReaderDepth(reader)==3) &&
      (strcmp((const char*)name,"stop")==0)) {
    log.debug("STOP\n");
    if (act) {
      send_action();
    }
    // verdict
    char* ver=(char*)xmlTextReaderGetAttribute(reader,(xmlChar*)"verdict");
    std::vector<std::string> p;

    if (tag!=NULL) {
      std::string t(tag);
      strvec(p,t,separator);
      for(unsigned i=0;i<p.size();i++) {
	unescape_string(p[i]);
      }
    }

    std::string a(ver);
    test_verdict=ver;
    free(ver);
    send_action(a,p,true);
  }
}

Alphabet* History_log::set_coverage(Coverage* cov,
				    Alphabet* alpha)
{
  c=cov;

  if (alpha) {
    model_from_log=false;
  } else {
    model_from_log=true;
  }

  LIBXML_TEST_VERSION

    xmlTextReaderPtr reader =
    xmlReaderForFile(file.c_str(), NULL, 0);

  if (reader != NULL) {
    int ret;
    ret = xmlTextReaderRead(reader);
    while (ret == 1) {
      processNode(reader);
      ret = xmlTextReaderRead(reader);
    }
    xmlFreeTextReader(reader);
  }
  xmlCleanupParser();
  xmlMemoryDump();

  return myes;
}

void History_log::send_action()
{
  std::string a(act);
  std::string t(tag);

  std::vector<std::string> props;

  if (t!="") {
    strvec(props,t,separator);
    for(unsigned i=0;i<t.size();i++) {
      unescape_string(props[i]);
    }
  }
  send_action(a,props);
  free(tag);
  free(act);
  tag=NULL;
  act=NULL;
}

bool History_log::send_action(std::string& act,
			      std::vector<std::string>& props,
			      bool verdict)
{
  std::vector<int> p;

  log.debug("SEND_ACTION (%i)\n",props.size());

  for(unsigned i=0;i<props.size();i++) {
    int j=find(a->getSPNames(),props[i]);
    log.debug("TAG %i(%s) %i\n",
	      i,props[i].c_str(),j);
    p.push_back(j);
  }

  if (c&&a) {
    if (verdict) {
      if (act=="pass") {
	c->history(0,p,Verdict::PASS);
	return true;
      }

      if (act=="fail") {
	c->history(0,p,Verdict::FAIL);
	return true;
      }

      if (act=="inconclusive") {
	c->history(0,p,Verdict::INCONCLUSIVE);
	return true;
      }

      if (act=="error") {
	c->history(0,p,Verdict::ERROR);
	return true;
      }

      if (act=="undefined") {
	c->history(0,p,Verdict::UNDEFINED);
	return true;
      }
      return false;
    }
    int action=find(a->getActionNames(),act);

    if (action>0) {
      c->history(action,p,Verdict::UNDEFINED);
      return true;
    } else {
      // Tau?
    }
  }

  return false;
}

FACTORY_DEFAULT_CREATOR(History, History_log, "log")
<commit_msg>Fix indexing vector. There might be less elements in a vector than charasters in a string<commit_after>/*
 * fMBT, free Model Based Testing tool
 * Copyright (c) 2011, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include "history_log.hh"

#include <libxml/xmlreader.h>
#ifndef LIBXML_READER_ENABLED
#error "LIBXML_READER_ENABLED is needed"
#endif

#include "helper.hh"

History_log::History_log(Log& l, std::string params) :
  History(l,params), alphabet_done(false), act(NULL), tag(NULL), c(NULL), a(NULL), file(params)
{
  separator=std::string(" ");
  anames.push_back("");
  tnames.push_back("");
  a = new Alphabet_impl(anames,tnames);
}

void History_log::processNode(xmlTextReaderPtr reader)
{
  char* name =(char*) xmlTextReaderConstName(reader);
  if (name==NULL) return;

  if (xmlTextReaderDepth(reader)>2) {
    if (!alphabet_done) {
      alphabet_done=true;
      if (model_from_log) {
	l.ref();
	myes=new Model_yes(l,"");
	myes->set_model(a);
	c->set_model(myes);
      }
    }
  }

  if (!alphabet_done) {
    if ((xmlTextReaderDepth(reader)==2) &&
	(strcmp((const char*)name,"action_name")==0)) {
      char* aname=unescape_string((char*)xmlTextReaderGetAttribute(reader,(xmlChar*)"name"));
      if (aname!=NULL) {
	anames.push_back(aname);
	free(aname);
      }
    }

    if ((xmlTextReaderDepth(reader)==2) &&
	(strcmp((const char*)name,"tag_name")==0)) {
      char* tname=unescape_string((char*)xmlTextReaderGetAttribute(reader,(xmlChar*)"name"));
      if (tname!=NULL) {
	tnames.push_back(tname);
	free(tname);
      }
    }

  }

  if ((xmlTextReaderDepth(reader)==3) &&
      (strcmp((const char*)name,"current_time")==0)) {
    char* time=(char*)xmlTextReaderGetAttribute(reader,(xmlChar*)"time");
    char* endp;
    long sec = strtol(time, &endp, 10);
    if (*endp=='.') {
      long usec=strtol(endp+1, &endp, 10);
      current_time.tv_sec=sec;
      current_time.tv_usec=usec;
    }
    free(time);
  }

  if ((xmlTextReaderDepth(reader)==3) &&
      (strcmp((const char*)name,"action")==0)) {
    // action
    if (act) {
      send_action();
    }
    act=unescape_string((char*)xmlTextReaderGetAttribute(reader,(xmlChar*)"name"));
    log.debug("FOUND ACT %s\n",act);
    send_action();
  }

  if ((xmlTextReaderDepth(reader)==3) &&
      (strcmp((const char*)name,"tags")==0)) {
    // tags
    if (tag) {
      free(tag);
    }
    tag=(char*)xmlTextReaderGetAttribute(reader,(xmlChar*)"enabled");
    log.debug("FOUND TAG %s\n",tag);
  }

  if ((xmlTextReaderDepth(reader)==3) &&
      (strcmp((const char*)name,"stop")==0)) {
    log.debug("STOP\n");
    if (act) {
      send_action();
    }
    // verdict
    char* ver=(char*)xmlTextReaderGetAttribute(reader,(xmlChar*)"verdict");
    std::vector<std::string> p;

    if (tag!=NULL) {
      std::string t(tag);
      strvec(p,t,separator);
      for(unsigned i=0;i<p.size();i++) {
	unescape_string(p[i]);
      }
    }

    std::string a(ver);
    test_verdict=ver;
    free(ver);
    send_action(a,p,true);
  }
}

Alphabet* History_log::set_coverage(Coverage* cov,
				    Alphabet* alpha)
{
  c=cov;

  if (alpha) {
    model_from_log=false;
  } else {
    model_from_log=true;
  }

  LIBXML_TEST_VERSION

    xmlTextReaderPtr reader =
    xmlReaderForFile(file.c_str(), NULL, 0);

  if (reader != NULL) {
    int ret;
    ret = xmlTextReaderRead(reader);
    while (ret == 1) {
      processNode(reader);
      ret = xmlTextReaderRead(reader);
    }
    xmlFreeTextReader(reader);
  }
  xmlCleanupParser();
  xmlMemoryDump();

  return myes;
}

void History_log::send_action()
{
  std::string a(act);
  std::string t(tag);

  std::vector<std::string> props;

  if (t!="") {
    strvec(props,t,separator);
    for(unsigned i=0;i<props.size();i++) {
      unescape_string(props[i]);
    }
  }
  send_action(a,props);
  free(tag);
  free(act);
  tag=NULL;
  act=NULL;
}

bool History_log::send_action(std::string& act,
			      std::vector<std::string>& props,
			      bool verdict)
{
  std::vector<int> p;

  log.debug("SEND_ACTION (%i)\n",props.size());

  for(unsigned i=0;i<props.size();i++) {
    int j=find(a->getSPNames(),props[i]);
    log.debug("TAG %i(%s) %i\n",
	      i,props[i].c_str(),j);
    p.push_back(j);
  }

  if (c&&a) {
    if (verdict) {
      if (act=="pass") {
	c->history(0,p,Verdict::PASS);
	return true;
      }

      if (act=="fail") {
	c->history(0,p,Verdict::FAIL);
	return true;
      }

      if (act=="inconclusive") {
	c->history(0,p,Verdict::INCONCLUSIVE);
	return true;
      }

      if (act=="error") {
	c->history(0,p,Verdict::ERROR);
	return true;
      }

      if (act=="undefined") {
	c->history(0,p,Verdict::UNDEFINED);
	return true;
      }
      return false;
    }
    int action=find(a->getActionNames(),act);

    if (action>0) {
      c->history(action,p,Verdict::UNDEFINED);
      return true;
    } else {
      // Tau?
    }
  }

  return false;
}

FACTORY_DEFAULT_CREATOR(History, History_log, "log")
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2015 Relja Ljubobratovic, ljubobratovic.relja@gmail.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// Author:
// Relja Ljubobratovic, ljubobratovic.relja@gmail.com

#include "homography.hpp"

#include <linalg.hpp>
#include <math.hpp>

void homography_solve(const std::vector<cv::vec2r> &image_points, const std::vector<cv::vec3r> &model_points, cv::matrixr &H) {
	auto n = image_points.size();
	ASSERT(model_points.size() == n);
	cv::matrixr L = cv::matrixr::zeros(2*n, 9);

	for(unsigned k = 0; k < n; k++) {

		real_t X=model_points[k][0];  /* X coord of model point k */
		real_t Y=model_points[k][1];  /* Y coord of model point k */
		real_t W=model_points[k][2];  /* W coord of model point k */
		real_t u=image_points[k][0];  /* u coord of image point k */
		real_t v=image_points[k][1];  /* v coord of image point k */

		int i = 2*k;                 /* line number in matrix L  */

		L(i,0) =    X;	L(i, 1) =    Y;	L(i, 2) =    W;
		L(i, 3) =    0;	L(i, 4) =    0;	L(i, 5) =    0;
		L(i, 6) = -u*X; L(i, 7) = -u*Y;	L(i, 8) = -u*W;

		i++;

		L(i, 0) =    0; L(i, 1) =    0; L(i, 2) =    0;
		L(i, 3) =    X; L(i, 4) =    Y; L(i, 5) =    W;
		L(i, 6) = -v*X; L(i, 7) = -v*Y; L(i, 8) = -v*W;
	}

	cv::null_solve(L, H);
	H.reshape(3, 3);

	H *= 1. / H(2, 2);
}

// Similarity estimation for normalization process.
template<size_t _size>
cv::matrixr homography_dlt_sim_estimation(const std::vector<cv::vectorx<real_t, _size> > &features) {
	cv::matrixr transform = cv::matrixr::eye(3);

	cv::vec2r centroid(0, 0);
	cv::matrixr S;

	for (auto feat : features) {
		centroid += feat;
	}
	centroid /= features.size();

	real_t sum_dist = 0;

	for (auto feat : features) {
		sum_dist+= centroid.distance(feat);
	}
	centroid *= -1;

	real_t scale_v = std::sqrt(2.) / (sum_dist / features.size());

	transform(0, 0) = scale_v;
	transform(1, 1) = scale_v;
	transform(0, 2) = centroid[0];
	transform(1, 2) = centroid[1];

	return transform;
}

template<size_t _size>
void homography_dlt_normalize(std::vector<cv::vectorx<real_t, _size> > &features, const cv::matrixr &S) {
	ASSERT(S && S.rows() == 3 && S.cols() == 3);
	cv::matrixr x(3, 1), xp(3, 1);
	for (unsigned i = 0; i < features.size(); ++i) {
		x(0, 0) = features[i][0];
		x(1, 0) = features[i][1];
		x(2, 0) = (_size == 3) ? features[i][2] : 1.;
		cross(S, x, xp);
		features[i][0] = xp(0, 0) / xp(2, 0);
		features[i][1] = xp(1, 0) / xp(2, 0);
		if(_size == 3)
			features[i][2] = 1.;
	}
}

void homography_dlt(const std::vector<cv::vec2r> &src_pts, const std::vector<cv::vec3r> &tgt_pts, cv::matrixr &H) {
	ASSERT(src_pts.size() >= 4 && src_pts.size() == tgt_pts.size());

	// 0. Prepare data;
	cv::matrixr srcS, tgtS, invTgtS;
	cv::matrixr A = cv::matrixr::zeros(2 * src_pts.size(), 9);

	// 1. Perform normalization;
	srcS = homography_dlt_sim_estimation<2>(src_pts);
	tgtS = homography_dlt_sim_estimation<3>(tgt_pts);

	auto src_n = src_pts; // source normalized points
	auto tgt_n = tgt_pts; // target normalized points

	invTgtS = tgtS.clone();
	invert(invTgtS);

	homography_dlt_normalize<2>(src_n, srcS);
	homography_dlt_normalize<3>(tgt_n, tgtS);

	// 2. Pack matrix A;
	for (unsigned i = 0; i < src_pts.size(); ++i) {
		A(i * 2 + 0, 0) = -1 * src_n[i][0];
		A(i * 2 + 0, 1) = -1 * src_n[i][1];
		A(i * 2 + 0, 2) = -1;
		A(i * 2 + 0, 6) = tgt_n[i][0] * src_n[i][0];
		A(i * 2 + 0, 7) = tgt_n[i][0] * src_n[i][1];
		A(i * 2 + 0, 8) = tgt_n[i][0];

		A(i * 2 + 1, 3) = -1 * src_n[i][0];
		A(i * 2 + 1, 4) = -1 * src_n[i][1];
		A(i * 2 + 1, 5) = -1;
		A(i * 2 + 1, 6) = tgt_n[i][1] * src_n[i][0];
		A(i * 2 + 1, 7) = tgt_n[i][1] * src_n[i][1];
		A(i * 2 + 1, 8) = tgt_n[i][1];
	}

	// 3. solve nullspace of A for H;
	cv::null_solve(A, H);

	H.reshape(3, 3);

	// 4. denormalize the homography.
	H = invTgtS * H * srcS;
}

/*
 * Pack homography matrices A and B by the form used for least squares solving.
 */
void pack_ab(const std::vector<cv::vec2r> &src_pts, const std::vector<cv::vec3r> &tgt_pts, cv::matrixr &A, cv::matrixr &B) {

	ASSERT(src_pts.size() && src_pts.size() == tgt_pts.size());

	// construct matrices
	A = cv::matrixr::zeros(src_pts.size() * 2, 8);
	B.create(src_pts.size() * 2, 1);

	// populate matrices with data.
	for (unsigned i = 0; i < src_pts.size(); i++) {

		auto &src = src_pts[i];
		auto &tgt = tgt_pts[i];

		B(i * 2, 0) = tgt[0];
		B(i * 2 + 1, 0) = tgt[1];

		A(i * 2, 0) = src[0];
		A(i * 2, 1) = src[1];
		A(i * 2, 2) = 1;
		A(i * 2 + 1, 3) = src[0];
		A(i * 2 + 1, 4) = src[1];
		A(i * 2 + 1, 5) = 1;

		A(i * 2, 6) = -1 * src[0] * tgt[0];
		A(i * 2, 7) = -1 * src[1] * tgt[0];
		A(i * 2 + 1, 6) = -1 * src[0] * tgt[1];
		A(i * 2 + 1, 7) = -1 * src[1] * tgt[1];
	}
}

/*
 * Solve homography using least squares method.
 */
void homography_least_squares(const std::vector<cv::vec2r> &src_pts, const std::vector<cv::vec3r> &tgt_pts, cv::matrixr &H) {

	cv::matrixr A, B;
	pack_ab(src_pts, tgt_pts, A, B);
	cv::matrixr _H(8, 1);

	cv::matrixr At = A.transposed();
	lu_solve(At * A, At * B, _H);

	if (!_H) {
		throw std::runtime_error("Internal error!~ failure occurred calculating homography.\n");
	}

	H.create(1, 9);
	std::copy(_H.begin(), _H.end(), H.begin());
	H.reshape(3, 3);
	H(2, 2) = 1;
}

std::vector<cv::vec2r> homography_optimization::source_pts;
std::vector<cv::vec3r> homography_optimization::target_pts;

void homography_optimization::reprojection_fcn(int *m, int *n, double* x, double* fvec,int *iflag) {
	// TODO: implement inline cross product without convertion to matrices.

	ASSERT(*m == source_pts.size());
	ASSERT(*n == 9);

	if (*iflag == 0)
		return;

	// calculate m_projected
	cv::matrixd _H(3, 3, x); // TODO: check if copies
	cv::matrixd ptn(3, 1), p_ptn(3, 1), res_ptn(3, 1);

	for (int i = 0; i < *m; ++i) {
		ptn(0, 0) = target_pts[i][0]; // model point
		ptn(1, 0) = target_pts[i][1];
		ptn(2, 0) = target_pts[i][2];

		p_ptn(0, 0) = source_pts[i][0]; // photo projection point
		p_ptn(1, 0) = source_pts[i][1];
		p_ptn(2, 0) = 1.;

		cv::cross( _H, ptn, res_ptn);

		res_ptn(0, 0) /= res_ptn(2, 0);
		res_ptn(1, 0) /= res_ptn(2, 0);
		res_ptn(2, 0) = 1.;

		fvec[i] = cv::distance(p_ptn, res_ptn, cv::Norm::L2);
	}
}

int homography_optimization::evaluate(cv::matrixr &H, cv::optimization_fcn fcn, double tol) {

	ASSERT(source_pts.size() > 9);

	int m = source_pts.size();
	int n = 9;

	int info = 0;

	auto *_H = new double[n];

	for (int i = 0; i < 9; ++i) {
		_H[i] = H.data_begin()[i];
	}

	info = cv::lmdif1(fcn, m, n, _H, tol);

	for (int i = 0; i < 9; ++i) {
		H.data_begin()[i] = _H[i];
	}

	return info;
}

<commit_msg>homography methods moved from main<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2015 Relja Ljubobratovic, ljubobratovic.relja@gmail.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// Author:
// Relja Ljubobratovic, ljubobratovic.relja@gmail.com

#include "homography.hpp"

#include <linalg.hpp>
#include <math.hpp>

cv::matrixr homography_8_point(const std::vector<cv::vec2r> &image_points, const std::vector<cv::vec3r> &model_points) {

	cv::matrixr H;

	auto n = image_points.size();
	ASSERT(model_points.size() == n);
	cv::matrixr L = cv::matrixr::zeros(2*n, 9);

	for(unsigned k = 0; k < n; k++) {

		real_t X=model_points[k][0];  /* X coord of model point k */
		real_t Y=model_points[k][1];  /* Y coord of model point k */
		real_t W=model_points[k][2];  /* W coord of model point k */
		real_t u=image_points[k][0];  /* u coord of image point k */
		real_t v=image_points[k][1];  /* v coord of image point k */

		int i = 2*k;                 /* line number in matrix L  */

		L(i,0) =    X;
		L(i, 1) =    Y;
		L(i, 2) =    W;
		L(i, 3) =    0;
		L(i, 4) =    0;
		L(i, 5) =    0;
		L(i, 6) = -u*X;
		L(i, 7) = -u*Y;
		L(i, 8) = -u*W;

		i++;

		L(i, 0) =    0;
		L(i, 1) =    0;
		L(i, 2) =    0;
		L(i, 3) =    X;
		L(i, 4) =    Y;
		L(i, 5) =    W;
		L(i, 6) = -v*X;
		L(i, 7) = -v*Y;
		L(i, 8) = -v*W;
	}

	cv::null_solve(L, H);
	H.reshape(3, 3);

	H *= 1. / H(2, 2);

	return H;
}

// Similarity estimation for normalization process.
template<size_t _size>
cv::matrixr homography_dlt_sim_estimation(const std::vector<cv::vectorx<real_t, _size> > &features) {
	cv::matrixr transform = cv::matrixr::eye(3);

	cv::vec2r centroid(0, 0);
	cv::matrixr S;

	for (auto feat : features) {
		centroid += feat;
	}
	centroid /= features.size();

	real_t sum_dist = 0;

	for (auto feat : features) {
		sum_dist+= centroid.distance(feat);
	}
	centroid *= -1;

	real_t scale_v = std::sqrt(2.) / (sum_dist / features.size());

	transform(0, 0) = scale_v;
	transform(1, 1) = scale_v;
	transform(0, 2) = centroid[0];
	transform(1, 2) = centroid[1];

	return transform;
}

template<size_t _size>
void homography_dlt_normalize(std::vector<cv::vectorx<real_t, _size> > &features, const cv::matrixr &S) {
	ASSERT(S && S.rows() == 3 && S.cols() == 3);
	cv::matrixr x(3, 1), xp(3, 1);
	for (unsigned i = 0; i < features.size(); ++i) {
		x(0, 0) = features[i][0];
		x(1, 0) = features[i][1];
		x(2, 0) = (_size == 3) ? features[i][2] : 1.;
		cross(S, x, xp);
		features[i][0] = xp(0, 0) / xp(2, 0);
		features[i][1] = xp(1, 0) / xp(2, 0);
		if(_size == 3)
			features[i][2] = 1.;
	}
}

cv::matrixr homography_dlt(const std::vector<cv::vec2r> &src_pts, const std::vector<cv::vec3r> &tgt_pts) {
	ASSERT(src_pts.size() >= 4 && src_pts.size() == tgt_pts.size());

	cv::matrixr H;

	// 0. Prepare data;
	cv::matrixr srcS, tgtS, invTgtS;
	cv::matrixr A = cv::matrixr::zeros(2 * src_pts.size(), 9);

	// 1. Perform normalization;
	srcS = homography_dlt_sim_estimation<2>(src_pts);
	tgtS = homography_dlt_sim_estimation<3>(tgt_pts);

	auto src_n = src_pts; // source normalized points
	auto tgt_n = tgt_pts; // target normalized points

	invTgtS = tgtS.clone();
	invert(invTgtS);

	homography_dlt_normalize<2>(src_n, srcS);
	homography_dlt_normalize<3>(tgt_n, tgtS);

	// 2. Pack matrix A;
	for (unsigned i = 0; i < src_pts.size(); ++i) {
		A(i * 2 + 0, 0) = -1 * src_n[i][0];
		A(i * 2 + 0, 1) = -1 * src_n[i][1];
		A(i * 2 + 0, 2) = -1;
		A(i * 2 + 0, 6) = tgt_n[i][0] * src_n[i][0];
		A(i * 2 + 0, 7) = tgt_n[i][0] * src_n[i][1];
		A(i * 2 + 0, 8) = tgt_n[i][0];

		A(i * 2 + 1, 3) = -1 * src_n[i][0];
		A(i * 2 + 1, 4) = -1 * src_n[i][1];
		A(i * 2 + 1, 5) = -1;
		A(i * 2 + 1, 6) = tgt_n[i][1] * src_n[i][0];
		A(i * 2 + 1, 7) = tgt_n[i][1] * src_n[i][1];
		A(i * 2 + 1, 8) = tgt_n[i][1];
	}

	// 3. solve nullspace of A for H;
	cv::null_solve(A, H);

	H.reshape(3, 3);

	// 4. denormalize the homography.
	H = invTgtS * H * srcS;

	return H;
}

/*
 * Pack homography matrices A and B by the form used for least squares solving.
 */
void pack_ab(const std::vector<cv::vec2r> &src_pts, const std::vector<cv::vec3r> &tgt_pts, cv::matrixr &A, cv::matrixr &B) {

	ASSERT(src_pts.size() && src_pts.size() == tgt_pts.size());

	// construct matrices
	A = cv::matrixr::zeros(src_pts.size() * 2, 8);
	B.create(src_pts.size() * 2, 1);

	// populate matrices with data.
	for (unsigned i = 0; i < src_pts.size(); i++) {

		auto &src = src_pts[i];
		auto &tgt = tgt_pts[i];

		B(i * 2, 0) = tgt[0];
		B(i * 2 + 1, 0) = tgt[1];

		A(i * 2, 0) = src[0];
		A(i * 2, 1) = src[1];
		A(i * 2, 2) = 1;
		A(i * 2 + 1, 3) = src[0];
		A(i * 2 + 1, 4) = src[1];
		A(i * 2 + 1, 5) = 1;

		A(i * 2, 6) = -1 * src[0] * tgt[0];
		A(i * 2, 7) = -1 * src[1] * tgt[0];
		A(i * 2 + 1, 6) = -1 * src[0] * tgt[1];
		A(i * 2 + 1, 7) = -1 * src[1] * tgt[1];
	}
}

/*
 * Solve homography using least squares method.
 */
cv::matrixr homography_least_squares(const std::vector<cv::vec2r> &src_pts, const std::vector<cv::vec3r> &tgt_pts) {

	cv::matrixr A, B, H;
	pack_ab(src_pts, tgt_pts, A, B);
	cv::matrixr _H(8, 1);

	cv::matrixr At = A.transposed();
	lu_solve(At * A, At * B, _H);

	if (!_H) {
		throw std::runtime_error("Internal error!~ failure occurred calculating homography.\n");
	}

	H.create(1, 9);
	std::copy(_H.begin(), _H.end(), H.begin());
	H.reshape(3, 3);
	H(2, 2) = 1;

	return H;
}

cv::matrixr homography_solve(const std::vector<cv::vec2r> &image_points, const std::vector<cv::vec3r> &model_points, H_calc_alg alg) {
	switch (alg) {
	case HOMOGRAPHY_8_POINT:
		return homography_8_point(image_points, model_points);
	case HOMOGRAPHY_LEAST_SQUARES:
		return homography_least_squares(image_points, model_points);
	case HOMOGRAPHY_DLT:
		return homography_dlt(image_points, model_points);
	};
}

std::vector<cv::vec2r> source_pts;
std::vector<cv::vec3r> target_pts;

void reprojection_fcn(int *m, int *n, double* x, double* fvec,int *iflag) {
	// TODO: implement inline cross product without convertion to matrices.

	ASSERT(*m == source_pts.size());
	ASSERT(*n == 9);

	if (*iflag == 0)
		return;

	// calculate m_projected
	cv::matrixd _H(3, 3, x); // borrow x and form matrix
	cv::matrixd ptn(3, 1), p_ptn(3, 1), res_ptn(3, 1);

	for (int i = 0; i < *m; ++i) {
		ptn(0, 0) = target_pts[i][0]; // model point
		ptn(1, 0) = target_pts[i][1];
		ptn(2, 0) = target_pts[i][2];

		p_ptn(0, 0) = source_pts[i][0]; // photo projection point
		p_ptn(1, 0) = source_pts[i][1];
		p_ptn(2, 0) = 1.;

		cv::cross( _H, ptn, res_ptn);

		res_ptn(0, 0) /= res_ptn(2, 0);
		res_ptn(1, 0) /= res_ptn(2, 0);
		res_ptn(2, 0) = 1.;

		fvec[i] = cv::distance(p_ptn, res_ptn, cv::Norm::L2);
	}
}

int homography_optimize(const std::vector<cv::vec2r> &image_points, const std::vector<cv::vec3r> &model_points,
                        cv::matrixr &H, double tol) {

	source_pts = image_points;
	target_pts = model_points;

	ASSERT(source_pts.size() > 9);

	int m = source_pts.size();
	int n = 9;

	int info = 0;

	auto *_H = new double[n];

	for (int i = 0; i < 9; ++i) {
		_H[i] = H.data_begin()[i];
	}

	info = cv::lmdif1(reprojection_fcn, m, n, _H, tol);

	for (int i = 0; i < 9; ++i) {
		H.data_begin()[i] = _H[i];
	}

	return info;
}

real_t calc_h_reprojection_error(const cv::matrixr &H, const std::vector<cv::vec2r> &source_pts, const std::vector<cv::vec3r> &target_pts) {

	ASSERT(source_pts.size() == target_pts.size() && H && H.rows() == 3 && H.cols() == 3);

	unsigned ptn_count = source_pts.size();
	real_t err = 0.0;

	// calculate m_projected
	cv::matrixr ptn(3, 1), p_ptn(3, 1), res_ptn(3, 1);

	for (unsigned i = 0; i < ptn_count; ++i) {
		ptn(0, 0) = source_pts[i][0];
		ptn(1, 0) = source_pts[i][1];
		ptn(2, 0) = 1.;

		p_ptn(0, 0) = target_pts[i][0];
		p_ptn(1, 0) = target_pts[i][1];
		p_ptn(2, 0) = target_pts[i][2];

		cv::cross( H, ptn, res_ptn);

		res_ptn(0, 0) /= res_ptn(2, 0);
		res_ptn(1, 0) /= res_ptn(2, 0);
		res_ptn(2, 0) = 1;

		err += cv::distance(res_ptn, p_ptn, cv::Norm::L2);
	}

	return err / ptn_count;
}

<|endoftext|>


<commit_before>#include <osg/Group>
#include <osg/Notify>
#include <osg/Geometry>
#include <osg/ArgumentParser>
#include <osg/ApplicationUsage>
#include <osg/Texture2D>
#include <osg/Geode>
#include <osg/PagedLOD>

#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>

#include <osgUtil/Optimizer>

#include <iostream>

osg::Geode* createTile(const osg::Vec3& lb, const osg::Vec3& rb,
                       const osg::Vec3& lt, const osg::Vec3& rt,
                       const std::string& imageFile)
{

    // create the geometry.
    osg::Geometry* geom = new osg::Geometry;

    osg::Vec3Array* coords = new osg::Vec3Array(4);
    (*coords)[0] = lt;
    (*coords)[1] = lb;
    (*coords)[2] = rb;
    (*coords)[3] = rt;
    geom->setVertexArray(coords);

    osg::Vec2Array* tcoords = new osg::Vec2Array(4);
    (*tcoords)[0].set(0.0f,1.0f);
    (*tcoords)[1].set(0.0f,0.0f);
    (*tcoords)[2].set(1.0f,0.0f);
    (*tcoords)[3].set(1.0f,1.0f);
    geom->setTexCoordArray(0,tcoords);

    osg::Vec4Array* colours = new osg::Vec4Array(1);
    (*colours)[0].set(1.0f,1.0f,1.0,1.0f);
    geom->setColorArray(colours);
    geom->setColorBinding(osg::Geometry::BIND_OVERALL);

    osg::Vec3Array* normals = new osg::Vec3Array(1);
    (*normals)[0] = (rb-lb)^(lt-lb);
    (*normals)[0].normalize();
    geom->setNormalArray(normals);
    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

    geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));

    // add the texture to the geometry.
    geom->getOrCreateStateSet()->setTextureAttributeAndModes(
        0, // texture unit 0.
        new osg::Texture2D(osgDB::readImageFile(imageFile)),
        osg::StateAttribute::ON);

    // create the geode.
    osg::Geode* geode = new osg::Geode;
    geode->addDrawable(geom);

    return geode;

}

osg::Node* createPagedModel()
{
    osg::PagedLOD* level_0 = new osg::PagedLOD;

    float distance = 1000.0f;

    osg::Vec3 lb(0.0f,0.0f,0.0f);
    osg::Vec3 rb(distance,0.0f,0.0f);
    osg::Vec3 rt(distance,0.0f,distance);
    osg::Vec3 lt(0.0f,0.0f,distance);

    level_0->addChild(createTile(lb,rb,lt,rt,"lz.rgb"),distance,1e5,"");
    level_0->addChild(createTile(lb,rb,lt,rt,"land_shallow_topo_2048.jpg"),0,distance,"level_1.osg");

    return level_0;
}

class WriteOutPagedLODSubgraphsVistor : public osg::NodeVisitor
{
public:
    WriteOutPagedLODSubgraphsVistor():
        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
    {
    }

    virtual void apply(osg::PagedLOD& plod)
    {
        // go through all the named children and write them out to disk.
        for(unsigned int i=0;i<plod.getNumChildren();++i)
        {
            osg::Node* child = plod.getChild(i);
            std::string filename = plod.getFileName(i);
            if (!filename.empty()) osgDB::writeNodeFile(*child,filename);
        }

        traverse(plod);
    }
};

int main( int argc, char **argv )
{

    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments(&argc,argv);

    // set up the usage document, in case we need to print out how to use this program.
    arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" creates a hierachy of files for paging which can be later loaded by viewers.");
    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");

    // if user request help write it out to cout.
    if (arguments.read("-h") || arguments.read("--help"))
    {
        arguments.getApplicationUsage()->write(std::cout);
        return 1;
    }

    // any option left unread are converted into errors to write out later.
    arguments.reportRemainingOptionsAsUnrecognized();

    // report any errors if they have occured when parsing the program aguments.
    if (arguments.errors())
    {
        arguments.writeErrorMessages(std::cout);
        return 1;
    }

//     if (arguments.argc()<=1)
//     {
//         arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
//         return 1;
//     }

    osg::ref_ptr<osg::Node> model = createPagedModel();

    if (model.valid())
    {
        osgDB::writeNodeFile(*model,"level_0.osg");

        WriteOutPagedLODSubgraphsVistor woplsv;
        model->accept(woplsv);
    }

    return 0;
}
<commit_msg>Changed osgpagedlod example to convert LOD nodes into PagedLOD ones.<commit_after>#include <osg/Group>
#include <osg/Notify>
#include <osg/Geometry>
#include <osg/ArgumentParser>
#include <osg/ApplicationUsage>
#include <osg/Texture2D>
#include <osg/Geode>
#include <osg/PagedLOD>

#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>

#include <osgUtil/Optimizer>

#include <iostream>
#include <sstream>

class WriteOutPagedLODSubgraphsVistor : public osg::NodeVisitor
{
public:
    WriteOutPagedLODSubgraphsVistor():
        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
    {
    }

    virtual void apply(osg::PagedLOD& plod)
    {

        // go through all the named children and write them out to disk.
        for(unsigned int i=0;i<plod.getNumChildren();++i)
        {
            osg::Node* child = plod.getChild(i);
            std::string filename = plod.getFileName(i);
            if (!filename.empty())
            {
                osg::notify(osg::NOTICE)<<"Writing out "<<filename<<std::endl;
                osgDB::writeNodeFile(*child,filename);
            }
        }

        traverse(plod);
    }
};

class ConvertToPageLODVistor : public osg::NodeVisitor
{
public:
    ConvertToPageLODVistor(const std::string& basename, const std::string& extension):
        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
        _basename(basename),
        _extension(extension)
    {
    }

    virtual ~ConvertToPageLODVistor()
    {
    }

    virtual void apply(osg::LOD& lod)
    {
        _lodSet.insert(&lod);

        traverse(lod);
    }

    virtual void apply(osg::PagedLOD& plod)
    {
        // do thing, but want to avoid call LOD.
        traverse(plod);
    }

    void convert()
    {
        unsigned int lodNum = 0;
        for(LODSet::iterator itr = _lodSet.begin();
            itr != _lodSet.end();
            ++itr, ++lodNum)
        {
            osg::ref_ptr<osg::LOD> lod = const_cast<osg::LOD*>(itr->get());

            if (lod->getNumParents()==0)
            {
                osg::notify(osg::NOTICE)<<"Warning can't operator on root node."<<std::endl;
                break;
            }

            osg::notify(osg::NOTICE)<<"Converting LOD to PagedLOD"<<std::endl;

            osg::PagedLOD* plod = new osg::PagedLOD;

            const osg::LOD::RangeList& originalRangeList = lod->getRangeList();
            typedef std::map< osg::LOD::MinMaxPair , unsigned int > MinMaxPairMap;
            MinMaxPairMap rangeMap;
            unsigned int pos = 0;
            for(osg::LOD::RangeList::const_iterator ritr = originalRangeList.begin();
                ritr != originalRangeList.end();
                ++ritr, ++pos)
            {
                rangeMap[*ritr] = pos;
            }

            pos = 0;
            for(MinMaxPairMap::reverse_iterator mitr = rangeMap.rbegin();
                mitr != rangeMap.rend();
                ++mitr, ++pos)
            {
                if (pos==0)
                {
                    plod->addChild(lod->getChild(mitr->second), mitr->first.first, mitr->first.second);
                   osg::notify(osg::NOTICE)<<"  adding staight child"<<std::endl;
                }
                else
                {
                    std::string filename = _basename;
                    std::ostringstream os;
                    os << _basename << "_"<<lodNum<<"_"<<pos<<_extension;

                    plod->addChild(lod->getChild(mitr->second), mitr->first.first, mitr->first.second, os.str());
                   osg::notify(osg::NOTICE)<<"  adding tiled subgraph"<<os.str()<<std::endl;
                }
            }

            osg::Node::ParentList parents = lod->getParents();
            for(osg::Node::ParentList::iterator pitr=parents.begin();
                pitr!=parents.end();
                ++pitr)
            {
                (*pitr)->replaceChild(lod.get(),plod);
            }

            plod->setCenter(plod->getBound().center());
            plod->setCenter(plod->getBound().center());

        }
    }

    typedef std::set< osg::ref_ptr<osg::LOD> >  LODSet;
    LODSet _lodSet;
    std::string _basename;
    std::string _extension;

};

int main( int argc, char **argv )
{

    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments(&argc,argv);

    // set up the usage document, in case we need to print out how to use this program.
    arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" creates a hierachy of files for paging which can be later loaded by viewers.");
    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");

    // if user request help write it out to cout.
    if (arguments.read("-h") || arguments.read("--help"))
    {
        arguments.getApplicationUsage()->write(std::cout);
        return 1;
    }

    // any option left unread are converted into errors to write out later.
    arguments.reportRemainingOptionsAsUnrecognized();

    // report any errors if they have occured when parsing the program aguments.
    if (arguments.errors())
    {
        arguments.writeErrorMessages(std::cout);
        return 1;
    }

//     if (arguments.argc()<=1)
//     {
//         arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
//         return 1;
//     }

    osg::ref_ptr<osg::Node> model = osgDB::readNodeFiles(arguments);

    if (!model)
    {
        osg::notify(osg::NOTICE)<<"No model loaded."<<std::endl;
        return 1;
    }

    ConvertToPageLODVistor converter("tile",".ive");
    model->accept(converter);
    converter.convert();

    if (model.valid())
    {
        osgDB::writeNodeFile(*model,"tile.ive");

        WriteOutPagedLODSubgraphsVistor woplsv;
        model->accept(woplsv);
    }

    return 0;
}
<|endoftext|>


<commit_before>
#include <iostream>
#include <QApplication>
#include <propertyzeug/Property.h>
#include <propertyzeug/PropertyGroup.h>
#include <propertyguizeug/PropertyBrowser.h>

using namespace zeug;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    PropertyGroup settings("Settings");
    PropertyGroup constraints("Constraints");

    int position[] = {10, 20, 30};
    int mat3x2[] = {1, 2, 3, 4, 5, 6};
    double mat2x2[] = {1.1, 2.3, 6.1, 4};
    bool boolMat[] = {true, false, true, false};

    constraints.addProperty<std::vector<int>>("Position", std::vector<int>(std::begin(position),
                                                                           std::end(position)));
    settings.addProperty(&constraints);
    constraints.addProperty("Height", 3);
    constraints.addProperty("Width", 12.3);
    settings.addProperty<std::string>("FilePath", "/Users/Horst/Desktop/");
    settings.addProperty<std::vector<int>>("Mat3x2", std::vector<int>(std::begin(mat3x2),
                                                                      std::end(mat3x2)));
    settings.property<std::vector<int>>("Mat3x2")->setDimensions(2,3);
    settings.addProperty<std::vector<double>>("Mat2x2", std::vector<double>(std::begin(mat2x2),
                                                                            std::end(mat2x2)));
    settings.property<std::vector<double>>("Mat2x2")->setDimensions(2,2);
    settings.addProperty<bool>("Activate", true);
    settings.addProperty<int>("Count", 79);
    PropertyGroup extras("Extras");
    settings.addProperty(&extras);
    extras.addProperty<Color>("Color", Color(255,122,0,190));
    extras.addProperty<FilePath>("Path", FilePath("/Users/max/"));
    // extras.property<FilePath>("Path")->setIsFile(false);
    extras.addProperty<std::string>("Animal", "Rabbit");
    extras.property<std::string>("Animal")->setChoices({"Rabbit", "Duck", "Elephant"});
    PropertyGroup general("General");
    extras.addProperty(&general);
    general.addProperty<std::vector<bool>>("BoolMat", std::vector<bool>(std::begin(boolMat),
                                                                        std::end(boolMat)));
    general.property<std::vector<bool>>("BoolMat")->setDimensions(2,2);

    PropertyBrowser browser1(&settings);
    browser1.show();

    return a.exec();
}
<commit_msg>Fixes for Windows #2<commit_after>
#include <iostream>
#include <QApplication>
#include <propertyzeug/Property.h>
#include <propertyzeug/PropertyGroup.h>
#include <propertyguizeug/PropertyBrowser.h>

using namespace zeug;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QApplication::setOrganizationName("hpicgs_libzeug");

    PropertyGroup settings("Settings");
    PropertyGroup constraints("Constraints");

    int position[] = {10, 20, 30};
    int mat3x2[] = {1, 2, 3, 4, 5, 6};
    double mat2x2[] = {1.1, 2.3, 6.1, 4};
    bool boolMat[] = {true, false, true, false};

    constraints.addProperty<std::vector<int>>("Position", std::vector<int>(std::begin(position),
                                                                           std::end(position)));
    settings.addProperty(&constraints);
    constraints.addProperty("Height", 3);
    constraints.addProperty("Width", 12.3);
    settings.addProperty<std::string>("FilePath", "/Users/Horst/Desktop/");
    settings.addProperty<std::vector<int>>("Mat3x2", std::vector<int>(std::begin(mat3x2),
                                                                      std::end(mat3x2)));
    settings.property<std::vector<int>>("Mat3x2")->setDimensions(2,3);
    settings.addProperty<std::vector<double>>("Mat2x2", std::vector<double>(std::begin(mat2x2),
                                                                            std::end(mat2x2)));
    settings.property<std::vector<double>>("Mat2x2")->setDimensions(2,2);
    settings.addProperty<bool>("Activate", true);
    settings.addProperty<int>("Count", 79);
    PropertyGroup extras("Extras");
    settings.addProperty(&extras);
    extras.addProperty<Color>("Color", Color(255,122,0,190));
    extras.addProperty<FilePath>("Path", FilePath("/Users/max/"));
    // extras.property<FilePath>("Path")->setIsFile(false);
    extras.addProperty<std::string>("Animal", "Rabbit");
    extras.property<std::string>("Animal")->setChoices({"Rabbit", "Duck", "Elephant"});
    PropertyGroup general("General");
    extras.addProperty(&general);
    general.addProperty<std::vector<bool>>("BoolMat", std::vector<bool>(std::begin(boolMat),
                                                                        std::end(boolMat)));
    general.property<std::vector<bool>>("BoolMat")->setDimensions(2,2);

    PropertyBrowser browser1(&settings);
    browser1.show();

    return a.exec();
}
<|endoftext|>


<commit_before><commit_msg>Fix division by zero (#17625)<commit_after><|endoftext|>


<commit_before>/**\file
 * \brief "Hello World" HTTP Server
 *
 * This is an example HTTP server that serves a simple "Hello World!" on /, and
 * a 404 on all other resources.
 *
 * Call it like this:
 * \code
 * $ ./http-hello localhost 8080
 * \endcode
 *
 * With localhost and 8080 being a host name and port of your choosing. Then,
 * while the programme is running, open a browser and go to
 * http://localhost:8080/ and you should see the familiar greeting.
 *
 * \copyright
 * Copyright (c) 2015, ef.gy Project Members
 * \copyright
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * \see Project Documentation: http://ef.gy/documentation/libefgy
 * \see Project Source Code: https://github.com/ef-gy/libefgy
 */

#define ASIO_DISABLE_THREADS
#include <ef.gy/http.h>
#include <iostream>

using namespace efgy;
using asio::ip::tcp;

/**\brief Hello World request handler
 *
 * This function serves the familiar "Hello World!" when called.
 *
 * \param[out] session The HTTP session to answer on.
 *
 * \returns true (always, as we always reply).
 */
static bool hello(typename net::http::server<tcp>::session &session,
                  std::smatch &) {
  session.reply(200, "Hello World!");

  return true;
}

/**\brief Main function for the HTTP demo
 *
 * This is the main function for the HTTP Hello World demo.
 *
 * \param[in] argc Process argument count.
 * \param[in] argv Process argument vector.
 *
 * \returns 0 when nothing bad happened, 1 otherwise.
 */
int main(int argc, char *argv[]) {
  try {
    if (argc != 3) {
      std::cerr << "Usage: http-hello <host> <port>\n";
      return 1;
    }

    asio::io_service io_service;
    tcp::resolver resolver(io_service);
    tcp::resolver::query query(argv[1], argv[2]);
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    tcp::resolver::iterator end;

    if (endpoint_iterator != end) {
      tcp::endpoint endpoint = *endpoint_iterator;
      net::http::server<tcp> s(io_service, endpoint, std::cout);

      s.processor.add("^/$", hello);

      io_service.run();
    }

    return 0;
  }
  catch (std::exception & e) {
    std::cerr << "Exception: " << e.what() << "\n";
  }
  catch (std::system_error & e) {
    std::cerr << "System Error: " << e.what() << "\n";
  }

  return 1;
}
<commit_msg>clean up parts of the HTTP server interface; add a /quit to the HTTP example<commit_after>/**\file
 * \brief "Hello World" HTTP Server
 *
 * This is an example HTTP server that serves a simple "Hello World!" on /, and
 * a 404 on all other resources.
 *
 * Call it like this:
 * \code
 * $ ./http-hello localhost 8080
 * \endcode
 *
 * With localhost and 8080 being a host name and port of your choosing. Then,
 * while the programme is running, open a browser and go to
 * http://localhost:8080/ and you should see the familiar greeting.
 *
 * \copyright
 * Copyright (c) 2015, ef.gy Project Members
 * \copyright
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * \see Project Documentation: http://ef.gy/documentation/libefgy
 * \see Project Source Code: https://github.com/ef-gy/libefgy
 */

#define ASIO_DISABLE_THREADS
#include <ef.gy/http.h>
#include <iostream>

using namespace efgy;
using asio::ip::tcp;

/**\brief Hello World request handler
 *
 * This function serves the familiar "Hello World!" when called.
 *
 * \param[out] session The HTTP session to answer on.
 *
 * \returns true (always, as we always reply).
 */
static bool hello(typename net::http::server<tcp>::session &session,
                  std::smatch &) {
  session.reply(200, "Hello World!");

  return true;
}

/**\brief Hello World request handler for /quit
 *
 * When this handler is invoked, it stops the ASIO IO handler (after replying,
 * maybe...).
 *
 * \note Having this on your production server in this exact way is PROBABLY a
 *       really bad idea, unless you gate it in an upstream forward proxy. Or
 *       you have some way of automatically respawning your server. Or both.
 *
 * \param[out] session The HTTP session to answer on.
 *
 * \returns true (always, as we always reply).
 */
static bool quit(typename net::http::server<tcp>::session &session,
                 std::smatch &) {
  session.reply(200, "Good Bye, Cruel World!");

  session.server.io.stop();

  return true;
}

/**\brief Main function for the HTTP demo
 *
 * This is the main function for the HTTP Hello World demo.
 *
 * \param[in] argc Process argument count.
 * \param[in] argv Process argument vector
 *
 * \returns 0 when nothing bad happened, 1 otherwise.
 */
int main(int argc, char *argv[]) {
  try {
    if (argc != 3) {
      std::cerr << "Usage: http-hello <host> <port>\n";
      return 1;
    }

    asio::io_service io_service;
    tcp::resolver resolver(io_service);
    tcp::resolver::query query(argv[1], argv[2]);
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    tcp::resolver::iterator end;

    if (endpoint_iterator != end) {
      tcp::endpoint endpoint = *endpoint_iterator;
      net::http::server<tcp> s(io_service, endpoint, std::cout);

      s.processor.add("^/$", hello);
      s.processor.add("^/quit$", quit);

      io_service.run();
    }

    return 0;
  }
  catch (std::exception & e) {
    std::cerr << "Exception: " << e.what() << "\n";
  }
  catch (std::system_error & e) {
    std::cerr << "System Error: " << e.what() << "\n";
  }

  return 1;
}
<|endoftext|>


<commit_before>#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <vector>
#include <math.h>

#include "vectorsprite.h"

#define PI 3.14159265

using std::vector;

int main ( int argc, char** argv )
{
    // initialize SDL video
    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "Unable to init SDL: %s\n", SDL_GetError() );
        return 1;
    }

    // make sure SDL cleans up before exit
    atexit(SDL_Quit);

    // create a new window
    SDL_Surface* screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_GL_DOUBLEBUFFER | SDL_OPENGL);
    if ( !screen )
    {
        printf("Unable to set 640x480 video: %s\n", SDL_GetError());
        return 1;
    }

    int* keys = new int[256];

    vector<Vector2> vector2s;
    vector2s.push_back(Vector2(200, 200));
    vector2s.push_back(Vector2(250, 250));
    vector2s.push_back(Vector2(300, 300));
    vector2s.push_back(Vector2(250, 150) + Vector2(150, 150));

    glClearColor(0, 0, 0, 0);
    glClearDepth(1.0f);

    glViewport(0, 0, 640, 480);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glOrtho(0, 640, 480, 0, 1, -1);

    glMatrixMode(GL_MODELVIEW);

    glEnable(GL_TEXTURE_2D);

    glLoadIdentity();

    Vector2 vs_pos = Vector2(200, 200);
    vector< Vector2 > vs_points;
    vs_points.push_back(Vector2(-20, -20));
    vs_points.push_back(Vector2(-20, 20));
    vs_points.push_back(Vector2(20, 20));
    vs_points.push_back(Vector2(20, -20));

    Colour vs_colour = Colour(50, 50, 255);
    VectorSprite vs = VectorSprite(vs_pos, &vs_points, &vs_colour);
    float COLOUR_CONV = 1.0/255.0;

    // program main loop
    bool done = false;
    while (!done)
    {
        // message processing loop
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            // check for messages
            switch (event.type)
            {
                // exit if the window is closed
            case SDL_QUIT:
                done = true;
                break;

                // check for keypresses
            case SDL_KEYDOWN:
                {
                    /*// exit if ESCAPE is pressed
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                    else if (event.key.keysym.sym == SDLK_w)
                        vs.pos.y-=10;
                    else if (event.key.keysym.sym == SDLK_s)
                        vs.pos.y+=10;
                    else if (event.key.keysym.sym == SDLK_a)
                        vs.pos.x-=10;
                    else if (event.key.keysym.sym == SDLK_d)
                        vs.pos.x+=10;
                    */
                    keys[event.key.keysym.sym] = 1;
                    break;

                }
            case SDL_KEYUP:
                {
                    keys[event.key.keysym.sym] = 0;
                    break;
                }
            } // end switch
        } // end of message processing

        // DRAWING STARTS HERE

        if (keys[SDLK_w] == 1)
        {
            vs.pos.y -= 10;
        }
        if (keys[SDLK_s] == 1)
        {
            vs.pos.y += 10;
        }
        if (keys[SDLK_a] == 1)
        {
            vs.pos.x -= 10;
        }
        if (keys[SDLK_d] == 1)
        {
            vs.pos.x += 10;
        }
        if (keys[SDLK_ESCAPE] == 1)
        {
            done = true;
        }

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();

        /*glBegin(GL_QUADS);
            glColor3f(1, 0, 0); glVertex3f(0, 0, 0);
            glColor3f(1, 1, 0); glVertex3f(100, 0, 0);
            glColor3f(1, 0, 1); glVertex3f(100, 100, 0);
            glColor3f(1, 1, 1); glVertex3f(0, 100, 0);
        glEnd();*/
        vs.rotate_radians(PI / 6.0);
        Colour d_col = *vs.colour;
        vector< Vector2 > d_pts = *vs.points;
        unsigned int i;
        glBegin(GL_LINE_LOOP);
            glColor3f(d_col.r*COLOUR_CONV, d_col.g*COLOUR_CONV, d_col.b*COLOUR_CONV);
            for (i = 0; i < d_pts.size(); i++)
            {
                glVertex2f(d_pts.at(i).x + vs.pos.x, d_pts.at(i).y + vs.pos.y);
            }
        glEnd();

        /*glBegin(GL_LINE_LOOP);
            glColor3f(1, 1, 1);
            unsigned int i;
            for (i = 0; i < vector2s.size(); i++)
            {
                glVertex3f(vector2s.at(i).x, vector2s.at(i).y, 0);
            }
        glEnd();*/

        SDL_GL_SwapBuffers();
    } // end main loop

    // all is well ;)
    printf("Exited cleanly\n");
    return 0;
}
<commit_msg>Cleaning up a bit<commit_after>#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <vector>
#include <math.h>

#include "vectorsprite.h"

#define PI 3.14159265

using std::vector;

int main ( int argc, char** argv )
{
    // initialize SDL video
    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "Unable to init SDL: %s\n", SDL_GetError() );
        return 1;
    }

    // make sure SDL cleans up before exit
    atexit(SDL_Quit);

    // create a new window
    SDL_Surface* screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_GL_DOUBLEBUFFER | SDL_OPENGL);
    if ( !screen )
    {
        printf("Unable to set 640x480 video: %s\n", SDL_GetError());
        return 1;
    }

    int* keys = new int[256];

    vector<Vector2> vector2s;
    vector2s.push_back(Vector2(200, 200));
    vector2s.push_back(Vector2(250, 250));
    vector2s.push_back(Vector2(300, 300));
    vector2s.push_back(Vector2(250, 150) + Vector2(150, 150));

    glClearColor(0, 0, 0, 0);
    glClearDepth(1.0f);

    glViewport(0, 0, 640, 480);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glOrtho(0, 640, 480, 0, 1, -1);

    glMatrixMode(GL_MODELVIEW);

    glEnable(GL_TEXTURE_2D);

    glLoadIdentity();

    Vector2 vs_pos = Vector2(200, 200);
    vector< Vector2 > vs_points;
    vs_points.push_back(Vector2(-20, -20));
    vs_points.push_back(Vector2(-20, 20));
    vs_points.push_back(Vector2(20, 20));
    vs_points.push_back(Vector2(20, -20));

    Colour vs_colour = Colour(50, 50, 255);
    VectorSprite vs = VectorSprite(vs_pos, &vs_points, &vs_colour);
    float COLOUR_CONV = 1.0/255.0;

    // program main loop
    bool done = false;
    while (!done)
    {
        // message processing loop
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            // check for messages
            switch (event.type)
            {
                // exit if the window is closed
            case SDL_QUIT:
                done = true;
                break;

                // check for keypresses
            case SDL_KEYDOWN:
                {
                    /*// exit if ESCAPE is pressed
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                    else if (event.key.keysym.sym == SDLK_w)
                        vs.pos.y-=10;
                    else if (event.key.keysym.sym == SDLK_s)
                        vs.pos.y+=10;
                    else if (event.key.keysym.sym == SDLK_a)
                        vs.pos.x-=10;
                    else if (event.key.keysym.sym == SDLK_d)
                        vs.pos.x+=10;
                    */
                    keys[event.key.keysym.sym] = 1;
                    break;

                }
            case SDL_KEYUP:
                {
                    keys[event.key.keysym.sym] = 0;
                    break;
                }
            } // end switch
        } // end of message processing

        // Use keyboard state to change game state

        if (keys[SDLK_ESCAPE] == 1)
        {
            done = true;
        }
        if (keys[SDLK_w] == 1)
        {
            vs.pos.y -= 10;
        }
        if (keys[SDLK_s] == 1)
        {
            vs.pos.y += 10;
        }
        if (keys[SDLK_a] == 1)
        {
            vs.pos.x -= 10;
        }
        if (keys[SDLK_d] == 1)
        {
            vs.pos.x += 10;
        }

        // DRAWING STARTS HERE
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();

        /*glBegin(GL_QUADS);
            glColor3f(1, 0, 0); glVertex3f(0, 0, 0);
            glColor3f(1, 1, 0); glVertex3f(100, 0, 0);
            glColor3f(1, 0, 1); glVertex3f(100, 100, 0);
            glColor3f(1, 1, 1); glVertex3f(0, 100, 0);
        glEnd();*/
        vs.rotate_radians(PI / 60.0);
        Colour d_col = *vs.colour;
        vector< Vector2 > d_pts = *vs.points;
        unsigned int i;
        glBegin(GL_LINE_LOOP);
            glColor3f(d_col.r*COLOUR_CONV, d_col.g*COLOUR_CONV, d_col.b*COLOUR_CONV);
            for (i = 0; i < d_pts.size(); i++)
            {
                glVertex2f(d_pts.at(i).x + vs.pos.x, d_pts.at(i).y + vs.pos.y);
            }
        glEnd();

        /*glBegin(GL_LINE_LOOP);
            glColor3f(1, 1, 1);
            unsigned int i;
            for (i = 0; i < vector2s.size(); i++)
            {
                glVertex3f(vector2s.at(i).x, vector2s.at(i).y, 0);
            }
        glEnd();*/

        SDL_GL_SwapBuffers();
    } // end main loop

    // all is well ;)
    printf("Exited cleanly\n");
    return 0;
}
<|endoftext|>


<commit_before>#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <vector>
#include <string>

class FlyingGame
{
private:
  sf::RenderWindow window;
  sf::Texture treepic;
  sf::Texture grasspic;
  sf::Texture mountainpic;
  sf::Texture plane;
  sf::Texture plane_left;
  sf::Texture enemy;
  sf::Texture shoot;
  sf::Texture explosion;
  sf::Sprite mountain;
  sf::Sprite mountainRight;
  sf::Sprite mountainLeft;
  sf::Sprite tree;
  sf::Sprite treeRight;
  sf::Sprite treeLeft;
  sf::Sprite grass;
  sf::Sprite grassRight;
  sf::Sprite grassLeft;
  sf::Sprite player;
  sf::Sprite bullet;
  std::vector<sf::Sprite> enemies;
  std::vector<sf::Sprite> bullets;
  sf::FloatRect enemiesbox;
  sf::Sprite oneEnemy;
  sf::Clock clock;
  sf::Clock enemySpeed;
  sf::Clock bulletSpeedClock;
  sf::Clock time_last_shot;
  sf::Clock bulletTime;
  sf::Clock enemySpawnTimer;
  sf::Clock timeLeft;
  float posX;
  float treeSpeed;
  float mountainSpeed;
  float grassSpeed;
  float speedX;
  int lives;
  int enemiesLeft;
  int hitTheGround;
  int enemiesKilled;
  int level;
  sf::Text showEnemiesLeft;
  sf::Text livesLeft;
  sf::Text bombsExploded;
  sf::Font font;
  sf::Text gameOver;
  sf::Text timeRemaining;
  sf::Text showLevel;
  sf::Text tryAgain;
  sf::Text speedometer;
  bool direction_left;

  void render()
  {
    //clear old draw new place and show
    window.clear();
    window.draw(mountain);
    window.draw(mountainRight);
    window.draw(mountainLeft);
    window.draw(tree);
    window.draw(treeRight);
    window.draw(treeLeft);
    window.draw(grass);
    window.draw(grassRight);
    window.draw(grassLeft);
    window.draw(showEnemiesLeft);
    window.draw(livesLeft);
    window.draw(bombsExploded);
    window.draw(timeRemaining);
    window.draw(showLevel);
    window.draw(speedometer);
    if (checkIfGameOver())
    {
      tryAgain.setString("Press SPACE to try again\nPress ESCAPE to exit the game");
      gameOver.setString("Game Over");
      window.draw(gameOver);
      window.draw(tryAgain);
      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
      {
        enemies.clear();
        timeLeft.restart();
        enemiesLeft = 0;
        lives = 3;
        hitTheGround = 0;

      }
    }
    else if (checkWinner())
    {
      gameOver.setString("You Survived");
      window.draw(gameOver);
      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
      {
        enemies.clear();
        timeLeft.restart();
        enemiesLeft = 0;
        lives = 3;
        hitTheGround = 0;
      }
    }
    else
    {
      window.draw(player);
      //draw all from enemies vector and bullets
      for (auto e = enemies.begin(); e != enemies.end(); e++)
      {
        window.draw(*e);
      }
      for (auto b = bullets.begin(); b != bullets.end(); b++)
      {
        window.draw(*b);
      }
    }
    window.display();
  }

  void processEvent()
  {
    sf::Event event;
    //events handler bad and slow. just using for closing the window
    while (window.pollEvent(event))
      //  switch(event.type)
        //{
          // //    //case sf::Event::KeyPressed : PlayerInput(event.key.code, true);
            // //    //  break;
              // //    //  case sf::Event::KeyReleased : PlayerInput(event.key.code, false);
                // //      break;
                  if (event.type == sf::Event::Closed)
                    window.close();
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
      window.close();
    //}
  }

  void playerMove()
  {
    //timer
    sf::Time elapsed = clock.getElapsedTime();
    float playerSpeed = 700.f;
    float maxSpeed = 450.f;
    //accelerator havent used yet
    float accelerator = 10.f;
    //vector to get players position on the map
    sf::Vector2f spot = player.getPosition();
    speedometer.setString("Speed: " + int2Str(abs(speedX)) + "km/h");
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
    {
      //cant move out of the map
      if (player.getPosition().y <= 40)
      {
        player.setPosition(spot.x, 40);
      }
      else
      {
        //if moving left. meaning speed is < 0
        if (speedX < 0)
        {
          if (speedX < -maxSpeed)
          {
            speedX = -maxSpeed;
          }
          else
          {
            speedX -= 3.f;
          }
          player.move(0, speedX * elapsed.asSeconds());
        }
        else
        {
          if (speedX > maxSpeed)
          {
            speedX = maxSpeed;
          }
          else
          {
            speedX += 3.f;
          }
          player.move(0, -speedX * elapsed.asSeconds());

        }
      }
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
    {
      //cant move any lower
      if (player.getPosition().y >= 450)
      {
        player.setPosition(spot.x, 450);
      }
      else
      {
        if (speedX < 0)
        {
          if (speedX < -maxSpeed)
          {
            speedX = -maxSpeed;
          }
          else
          {
            speedX -= 3.f;
          }

          player.move(0, -speedX*elapsed.asSeconds());
        }
        else
        {
          if (speedX > maxSpeed)
          {
            speedX = maxSpeed;
          }
          else
          {
            speedX += 3.f;
          }
          player.move(0, speedX * elapsed.asSeconds());
        }
      }
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
    {
      /*direction_left = true;*/
      //change sprite to face left. player smooth move.
      player.setTexture(plane_left);
      //starting speed if i turn around
      player.move(playerSpeed*elapsed.asSeconds(), 0);
      //if player reaches 700,y stop
      if (spot.x >= 720)
      {
        player.setPosition(720, spot.y);
      }

      if (speedX > maxSpeed)
      {
        speedX = maxSpeed;
      }
      else
      {
        speedX += 5.f;
      }
    }

    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
    {
      /*direction_left = false;*/
      player.setTexture(plane);
      player.move(-playerSpeed*elapsed.asSeconds(), 0);

      if (spot.x <= 20)
      {
        player.setPosition(20, spot.y);
      }

      if (speedX < -maxSpeed)
      {
        speedX = -maxSpeed;
      }
      else
      {
        speedX -= 5.f;
      }
    }
    //move the backgrounds left or right
    treeSpeed = elapsed.asSeconds() * speedX / 2;
    grassSpeed = elapsed.asSeconds() * speedX;
    mountainSpeed = elapsed.asSeconds() * speedX / 4;
    grass.move(grassSpeed, 0);
    grassRight.move(grassSpeed, 0);
    grassLeft.move(grassSpeed, 0);
    tree.move(treeSpeed, 0);
    treeRight.move(treeSpeed, 0);
    treeLeft.move(treeSpeed, 0);
    mountain.move(mountainSpeed, 0);
    mountainRight.move(mountainSpeed, 0);
    mountainLeft.move(mountainSpeed, 0);
    //restart the timer
    clock.restart();
    //for tests
    //int  X = speedX;
    //int  Y = tree.getPosition().y;
    //printf_s("%d ", X);
  }

  void enemyMove()
  {
    sf::Time enemyElapsed = enemySpeed.getElapsedTime();
    sf::FloatRect playerbox = player.getGlobalBounds();

    for (auto i = enemies.begin(); i != enemies.end();)
    {
      enemiesbox = i->getGlobalBounds();

      if (playerbox.intersects(enemiesbox))
      {
        player.setPosition(400, 460);
        speedX = 0;
        lives = lives - 1;
      }

      sf::Vector2f asd = i->getPosition();
      if (asd.y >= 480)//funktsioniert nicht :? DOCH
      {
        i->setPosition(asd.x, 480);
        hitTheGround++;
        enemiesLeft--;
        enemies.erase(i);
        break;
      }
      else if (i->getPosition().x > 1595)
      {
        i->setPosition(-795, asd.y);
      }
      else if (i->getPosition().x < -795)
      {
        i->setPosition(1595, asd.y);
      }
      else
      {
        //enemy move x at the same speed the player does for circlemap effect. enemy y can change freely
        i->move(speedX*enemyElapsed.asSeconds(), 20 * enemyElapsed.asSeconds());
        i++;
      }
    }
    livesLeft.setString("Lives left: " + int2Str(lives));
    bombsExploded.setString("Bombs Exploded: " + int2Str(hitTheGround));
    enemySpeed.restart();
  }

  void createBullet()
  {
    //moving bullets
    /*sf::Time bulletEraser = bulletTime.getElapsedTime();*/
    sf::Time reload = time_last_shot.getElapsedTime();
    sf::Time bulletSpeed = bulletSpeedClock.getElapsedTime();

    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
    {
      //create new sprite reference shot. set start postiion and add it to the bulelt list
      if (reload > sf::seconds(0.2))
      {
        sf::Sprite *nshot = new sf::Sprite;
        nshot->setPosition(player.getPosition().x + 20, player.getPosition().y + 20);
        nshot->setTexture(shoot);
        bullets.push_back(*nshot);
        time_last_shot.restart();
        if(player.getPosition().x > 350)
        {
          direction_left = true;
        }
        else
        {
          direction_left = false;
        }
      }
    }

    for (auto i = bullets.begin(); i != bullets.end();)
    {
      //according to direction fly left or right
      if (direction_left)
      {
        i->move(-1000 * bulletSpeed.asSeconds(), 0);
      }
      else
      {
        i->move(1000 * bulletSpeed.asSeconds(), 0);
      }
      //if bullet flies of the screen or is older then 0.3sec then erase from vector
      if (i->getPosition().x <= 0 || i->getPosition().x >= 800)
      {
        bullets.erase(i);
        break;
      }
      else
      {
        i++;
      }
    }
    bulletSpeedClock.restart();
  }

  void collision()
  {
    for (auto e = enemies.begin(); e != enemies.end();)
    {
      //if element is removed dont increment the iterator and skip the collison check for the next element!
      bool collides = false;
      for (auto i = bullets.begin(); i != bullets.end(); i++)
      {
        sf::FloatRect enemiez = e->getGlobalBounds();
        sf::FloatRect bulletz = i->getGlobalBounds();

        if (bulletz.intersects(enemiez))
        {
          enemiesLeft = enemiesLeft - 1;
          enemiesKilled++;
          bullets.erase(i);
          //assing iterator to return value of erase, because once you erase an elelemnt your pervious iterator is invalidated.
          e = enemies.erase(e);
          collides = true;
          break;
        }
      }
      if (!collides)
      {
        e++;
      }
    }
    showEnemiesLeft.setString("Enemies left:" + int2Str(enemiesLeft));
  }

  void placeEnemiesAtStart()
  {
    float posx = rand() % 1550 + (-750);
    float posy = rand() % 50 + (-50);
    oneEnemy.setTexture(enemy);
    oneEnemy.setPosition(posx, posy);
  }

  void backgroundLoop()
  {
    if (grass.getPosition().x >= 795)
    {
      grassLeft.setPosition(-800, 475);
      grass.setPosition(0, 475);
      grassRight.setPosition(800, 475);
    }
    else if (tree.getPosition().x >= 795)
    {
      treeLeft.setPosition(-800, 285);
      tree.setPosition(0, 285);
      treeRight.setPosition(800, 285);
    }

    else if (mountain.getPosition().x >= 795)
    {
      mountainLeft.setPosition(-795, 0);
      mountain.setPosition(0, 0);
      mountainRight.setPosition(795, 0);
    }
    else if (grass.getPosition().x <= -795)
    {
      grassLeft.setPosition(-800, 475);
      grass.setPosition(0, 475);
      grassRight.setPosition(800, 475);
    }
    else if (tree.getPosition().x <= -795)
    {
      treeLeft.setPosition(-800, 285);
      tree.setPosition(0, 285);
      treeRight.setPosition(800, 285);
    }
    else if (mountain.getPosition().x <= -795)
    {
      mountainLeft.setPosition(-795, 0);
      mountain.setPosition(0, 0);
      mountainRight.setPosition(795, 0);
    }
  }

  static inline std::string int2Str(float x)
    //converts int to string with help of sstream namespace
  {
    std::stringstream type;
    type << x;
    return type.str();
  }

  bool checkIfGameOver()
  {
    if (lives == 0 || hitTheGround > 3)
    {
      speedX = 0;
      return true;
    }
    else
    {
      return false;
    }
  }
  bool checkWinner()
  {
    sf::Time timer = timeLeft.getElapsedTime();
    float countDown = timer.asSeconds();
    if (countDown >= 60.f)
    {
      timeRemaining.setString("You saved the planet!");
      speedX = 0;
      return true;
    }
    else
    {
      timeRemaining.setString("Time Survived: " + int2Str(countDown));
      return false;
    }

  }
  void createEnemies()
  {
    sf::Time spawnSome = enemySpawnTimer.getElapsedTime();
    sf::Time timerDifficulty = sf::seconds(4);
    if (spawnSome > timerDifficulty)
    {
      enemiesLeft++;
      placeEnemiesAtStart();
      enemies.push_back(oneEnemy);
      enemySpawnTimer.restart();
    }
  }
public:
  void Run()
  {
    while (window.isOpen())
    {
      processEvent();
      playerMove();
      enemyMove();
      createBullet();
      collision();
      backgroundLoop();
      createEnemies();
      render();
    }
  }

  FlyingGame() : window(sf::VideoMode(800, 600, 32), "FlyingGame")
  {
    //game window with player and background etc automaticly created when i create instance of flyinggame class
    level = 1;
    speedX = 0;
    lives = 3;
    hitTheGround = 0;
    enemiesLeft = 0;
    enemiesKilled = 0;
    window.setMouseCursorVisible(false);
    //window.setFramerateLimit(3);
    window.setVerticalSyncEnabled(true);
    mountainpic.loadFromFile("pic/mountain.png");
    grasspic.loadFromFile("pic/new_grass.png");
    treepic.loadFromFile("pic/trees.png");
    shoot.loadFromFile("pic/bullet-s.png");
    enemy.loadFromFile("pic/bomb_new.png");
    plane.loadFromFile("pic/player_right.png");
    plane_left.loadFromFile("pic/player_left.png");
    explosion.loadFromFile("pic/explosion.png");
    font.loadFromFile("roboto-black.ttf");
    plane.setSmooth(true);
    plane_left.setSmooth(true);
    shoot.setSmooth(true);
    enemy.setSmooth(true);
    player.setTexture(plane);
    tree.setTexture(treepic);
    treeRight.setTexture(treepic);
    treeLeft.setTexture(treepic);
    grassRight.setTexture(grasspic);
    grass.setTexture(grasspic);
    grassLeft.setTexture(grasspic);
    mountain.setTexture(mountainpic);
    mountainRight.setTexture(mountainpic);
    mountainLeft.setTexture(mountainpic);
    tree.setPosition(0, 285);
    treeRight.setPosition(800, 285);
    treeLeft.setPosition(-800, 285);
    grass.setPosition(0, 475);
    grassRight.setPosition(800, 475);
    grassLeft.setPosition(-800, 475);
    mountain.setPosition(0, 0);
    mountainRight.setPosition(800, 0);
    mountainLeft.setPosition(-800, 0);
    player.setPosition(400, 460);
    player.setTextureRect(sf::IntRect(0, 0, 64, 32));
    tree.setTextureRect(sf::IntRect(0, 280, 800, 250));
    treeRight.setTextureRect(sf::IntRect(0, 280, 800, 250));
    treeLeft.setTextureRect(sf::IntRect(0, 280, 800, 250));
    mountain.setTextureRect(sf::IntRect(0, 0, 800, 500));
    mountainRight.setTextureRect(sf::IntRect(0, 0, 800, 500));
    mountainLeft.setTextureRect(sf::IntRect(0, 0, 800, 500));
    grass.setTextureRect(sf::IntRect(0, 470, 800, 200));
    grassRight.setTextureRect(sf::IntRect(0, 470, 800, 200));
    grassLeft.setTextureRect(sf::IntRect(0, 470, 800, 200));
    showEnemiesLeft.setPosition(10,540);
    showEnemiesLeft.setFont(font);
    showEnemiesLeft.setCharacterSize(24);
    showEnemiesLeft.setColor(sf::Color::Red);
    livesLeft.setPosition(620, 10);
    livesLeft.setFont(font);
    livesLeft.setCharacterSize(24);
    livesLeft.setColor(sf::Color::Red);
    bombsExploded.setPosition(280, 540);
    bombsExploded.setFont(font);
    bombsExploded.setCharacterSize(24);
    bombsExploded.setColor(sf::Color::Red);
    gameOver.setPosition(200, 200);
    gameOver.setFont(font);
    gameOver.setCharacterSize(64);
    gameOver.setColor(sf::Color::Red);
    timeRemaining.setFont(font);
    timeRemaining.setCharacterSize(24);
    timeRemaining.setColor(sf::Color::Red);
    timeRemaining.setPosition(280, 10);
    showLevel.setFont(font);
    showLevel.setCharacterSize(24);
    showLevel.setColor(sf::Color::Red);
    showLevel.setPosition(620, 540);
    showLevel.setString("Level: " + int2Str(level));
    speedometer.setFont(font);
    speedometer.setPosition(10,10);
    speedometer.setCharacterSize(24);
    speedometer.setColor(sf::Color::Red);
    tryAgain.setFont(font);
    tryAgain.setCharacterSize(24);
    tryAgain.setColor(sf::Color::Red);
    tryAgain.setPosition(220, 280);
  }
};
<commit_msg>Delete game.cpp<commit_after><|endoftext|>


<commit_before>#include "game.h"
#include <QTimer>
#include <QDebug>

Game::Game(QObject *parent) :
    QObject(parent)
{

}

void Game::playTimeout() {
    // TODO: Impl
    // End Current Game
    // Update High Score if needed
}

void Game::yourScoreChanged() {
    // TODO: react to score deltas
}

void Game::highScoreChanged() {
    // TODO: react to high score deltas
}
<commit_msg>Builds now<commit_after>#include "game.h"
#include <QTimer>
#include <QDebug>

Game::Game(QObject *parent) :
    QObject(parent)
{

}

void Game::playTimeout() {
    // TODO: Impl
    // End Current Game
    // Update High Score if needed
}
<|endoftext|>


<commit_before>#include <iostream>

#include <SFML/Graphics.hpp>
#include "game.h"

Game::Game():
    playing(true),
    screen(),
    map(nullptr)
    //map_camera(nullptr),
    //unitRepository(nullptr)
{
    sf::ContextSettings settings;
    settings.antialiasingLevel = 8;
    screen.create(sf::VideoMode(800, 600), "Dune 2 - The Maker", sf::Style::Close, settings);
    screen.setFramerateLimit(IDEAL_FPS);
    screen.setMouseCursorVisible(false);

    if (!init()){
        std::cerr << "Failed to initialized game.";
        playing = false;
    }
}

int Game::execute() {

    sf::Clock clock;

  while(playing) {
    sf::Event event;
    actionMap.clearEvents();
    sf::Time dt = clock.restart();
    while(screen.pollEvent(event)) {
      actionMap.pushEvent(event);
    }

    updateState(dt);
    render();
  }

  return 0;
}

bool Game::init() {
  if (!terrain.loadFromFile("graphics/terrain.png")) {
    std::cout << "Failed to read graphics/terrain.png data" << std::endl;
    return false;
  }

  sf::Image temp;
  if (!temp.loadFromFile("graphics/shroud_edges.bmp")) {
    std::cout << "Failed to read graphics/shroud_edges.bmp data" << std::endl;
    return false;
  }

  temp.createMaskFromColor(sf::Color(255, 0, 255));
  shroud_edges.loadFromImage(temp);

  map.reset(new Map(terrain, shroud_edges));
  map->load("maps/4PL_Mountains.ini");

  camera.reset({0,0,800,600});
  screen.setView(camera);

  //init a trike
  sf::Image trikeImage;
  trikeImage.loadFromFile("graphics/Unit_Trike.bmp");
  trikeImage.createMaskFromColor(sf::Color(0,0,0));
  sf::Texture* trikeTexture = new sf::Texture; //yes we are leaking! Player should own this
  trikeTexture->loadFromImage(trikeImage);

  sf::Image trikeShadowImage;
  trikeShadowImage.loadFromFile("graphics/Unit_Trike_s.bmp");
  trikeShadowImage.createMaskFromColor(sf::Color(255,0,255));
  sf::Texture* trikeShadowTexture = new sf::Texture;
  trikeShadowTexture->loadFromImage(trikeShadowImage);

  sf::Image selectedImage;
  selectedImage.loadFromFile("graphics/selected.bmp");
  selectedImage.createMaskFromColor(sf::Color(255, 0, 255));
  sf::Texture* selectedTexture = new sf::Texture; //more leaks!
  selectedTexture->loadFromImage(selectedImage);
  units.emplace_back(new Unit(*trikeTexture, *trikeShadowTexture, *selectedTexture, 256, 256, 0, *map));

   ////init two players
  //int idCount = 0;
  //players.emplace_back(House::Sardaukar, idCount++);
  //players.emplace_back(House::Harkonnen, idCount++);

  //units.emplace_back(unitRepository->create(UNIT_FRIGATE, House::Sardaukar, 3, 3, 10, SUBCELL_CENTER, players[0]));
  //units.emplace_back(unitRepository->create(UNIT_TRIKE, House::Sardaukar, 8, 8, 3, SUBCELL_CENTER, players[0]));

  //// soldiers
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Sardaukar, 14, 14, 3, SUBCELL_CENTER, players[0]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Sardaukar, 14, 14, 3, SUBCELL_UPLEFT, players[0]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Sardaukar, 14, 14, 3, SUBCELL_UPRIGHT, players[0]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Sardaukar, 14, 14, 3, SUBCELL_DOWNLEFT, players[0]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Sardaukar, 14, 14, 3, SUBCELL_DOWNRIGHT, players[0]));

  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Harkonnen, 18, 8, 3, SUBCELL_CENTER, players[1]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Harkonnen, 18, 8, 3, SUBCELL_UPLEFT, players[1]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Harkonnen, 18, 8, 3, SUBCELL_UPRIGHT, players[1]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Harkonnen, 18, 8, 3, SUBCELL_DOWNLEFT, players[1]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Harkonnen, 18, 8, 3, SUBCELL_DOWNRIGHT, players[1]));

  //thor Actions here

  actionMap["boxStart"] = thor::Action(sf::Mouse::Left, thor::Action::PressOnce);
  actionMap["orderMove"] = thor::Action(sf::Mouse::Left, thor::Action::PressOnce);
  actionMap["boxDrag"] = thor::Action(sf::Mouse::Left, thor::Action::Hold);
  actionMap["boxRelease"] = thor::Action(sf::Mouse::Left, thor::Action::ReleaseOnce);
  actionMap["deselectAll"] = thor::Action(sf::Mouse::Right, thor::Action::PressOnce);
  actionMap["close"] = thor::Action(sf::Event::Closed) || thor::Action(sf::Keyboard::Q, thor::Action::PressOnce);
  actionMap["cameraLeft"] = thor::Action(sf::Keyboard::Left, thor::Action::Hold);
  actionMap["cameraRight"] = thor::Action(sf::Keyboard::Right, thor::Action::Hold);
  actionMap["cameraUp"] = thor::Action(sf::Keyboard::Up, thor::Action::Hold);
  actionMap["cameraDown"] = thor::Action(sf::Keyboard::Down, thor::Action::Hold);

  typedef thor::ActionContext<std::string> actionContext;

  system.connect("close", [this](actionContext){playing = false;});

  system.connect("boxRelease", [this](actionContext){
    for (auto& unit : units){
      if (box.intersects(unit->getBounds())){
        unit->select();
        system.connect("orderMove", [this, &unit](actionContext context){
          unit->order_move(screen.mapPixelToCoords(mouse.getHotspot(*context.event)));
        });
        mouse.setType(Mouse::Type::Move); //at least one unit selected...
      }
    }
    box.clear();
  });

  system.connect("boxStart", [this](actionContext context){
    sf::Vector2f toSet = screen.mapPixelToCoords(mouse.getHotspot(*context.event));
    box.setTopLeft(toSet);
  });

  system.connect("deselectAll", [this](actionContext){
//    system.clearConnections("orderMove"); // -> This is bugged in Thor
    mouse.setType(Mouse::Type::Default);
    for (auto& unit : units)
      unit->unselect();
  });

  system.connect("boxDrag", [this](actionContext){
    box.setBottomRight(screen.mapPixelToCoords(sf::Mouse::getPosition(screen)));
  });

  const float cameraSpeed = 15.f;

  system.connect("cameraLeft", [this, cameraSpeed](actionContext) {camera.move(-cameraSpeed, 0.f);});
  system.connect("cameraRight", [this, cameraSpeed](actionContext){camera.move(cameraSpeed, 0.f); });
  system.connect("cameraUp", [this, cameraSpeed](actionContext)   {camera.move(0.f, -cameraSpeed);});
  system.connect("cameraDown", [this, cameraSpeed](actionContext) {camera.move(0.f, cameraSpeed); });

  return true;
}

void Game::render() {
  screen.clear();

  screen.setView(camera);

  screen.draw(*map);

  for (const auto& unit : units)
      screen.draw(*unit);

  map->drawShrouded(screen, sf::RenderStates::Default);

  screen.draw(box);

  screen.draw(fpsCounter);

  screen.setView(camera);

  screen.draw(mouse);

  screen.display();
}

void Game::updateState(sf::Time dt) {
  actionMap.invokeCallbacks(system, &screen);

  sf::Vector2f half_of_camera = camera.getSize() / 2.f;
  sf::Vector2f topLeft = camera.getCenter() - (half_of_camera);
  sf::Vector2f downRight = camera.getCenter() + (half_of_camera);

  if (topLeft.x <= Cell::TILE_SIZE) camera.setCenter(half_of_camera.x + Cell::TILE_SIZE, camera.getCenter().y);
  if (topLeft.y <= Cell::TILE_SIZE) camera.setCenter(camera.getCenter().x, half_of_camera.y + Cell::TILE_SIZE);

  mouse.setPosition(screen.mapPixelToCoords(sf::Mouse::getPosition(screen),camera));

  int max_width = (map->getMaxWidth() + 1) * Cell::TILE_SIZE;
  int max_height = (map->getMaxHeight() + 1) * Cell::TILE_SIZE;

  if (downRight.x >= max_width) camera.setCenter(max_width - half_of_camera.x, camera.getCenter().y);
  if (downRight.y >= max_height) camera.setCenter(camera.getCenter().x, max_height - half_of_camera.y);

  for (auto& unit: units){
    unit->updateState();
  }

  fpsCounter.update(dt);
  map->prepare(screen.mapPixelToCoords(sf::Vector2i(0,0)));
}
<commit_msg>fixed mouse jumping around<commit_after>#include <iostream>

#include <SFML/Graphics.hpp>
#include "game.h"

Game::Game():
    playing(true),
    screen(),
    map(nullptr)
    //map_camera(nullptr),
    //unitRepository(nullptr)
{
    sf::ContextSettings settings;
    settings.antialiasingLevel = 8;
    screen.create(sf::VideoMode(800, 600), "Dune 2 - The Maker", sf::Style::Close, settings);
    screen.setFramerateLimit(IDEAL_FPS);
    screen.setMouseCursorVisible(false);

    if (!init()){
        std::cerr << "Failed to initialized game.";
        playing = false;
    }
}

int Game::execute() {

    sf::Clock clock;

  while(playing) {
    sf::Event event;
    actionMap.clearEvents();
    sf::Time dt = clock.restart();
    while(screen.pollEvent(event)) {
      actionMap.pushEvent(event);
    }

    updateState(dt);
    render();
  }

  return 0;
}

bool Game::init() {
  if (!terrain.loadFromFile("graphics/terrain.png")) {
    std::cout << "Failed to read graphics/terrain.png data" << std::endl;
    return false;
  }

  sf::Image temp;
  if (!temp.loadFromFile("graphics/shroud_edges.bmp")) {
    std::cout << "Failed to read graphics/shroud_edges.bmp data" << std::endl;
    return false;
  }

  temp.createMaskFromColor(sf::Color(255, 0, 255));
  shroud_edges.loadFromImage(temp);

  map.reset(new Map(terrain, shroud_edges));
  map->load("maps/4PL_Mountains.ini");

  camera.reset({0,0,800,600});
  screen.setView(camera);

  //init a trike
  sf::Image trikeImage;
  trikeImage.loadFromFile("graphics/Unit_Trike.bmp");
  trikeImage.createMaskFromColor(sf::Color(0,0,0));
  sf::Texture* trikeTexture = new sf::Texture; //yes we are leaking! Player should own this
  trikeTexture->loadFromImage(trikeImage);

  sf::Image trikeShadowImage;
  trikeShadowImage.loadFromFile("graphics/Unit_Trike_s.bmp");
  trikeShadowImage.createMaskFromColor(sf::Color(255,0,255));
  sf::Texture* trikeShadowTexture = new sf::Texture;
  trikeShadowTexture->loadFromImage(trikeShadowImage);

  sf::Image selectedImage;
  selectedImage.loadFromFile("graphics/selected.bmp");
  selectedImage.createMaskFromColor(sf::Color(255, 0, 255));
  sf::Texture* selectedTexture = new sf::Texture; //more leaks!
  selectedTexture->loadFromImage(selectedImage);
  units.emplace_back(new Unit(*trikeTexture, *trikeShadowTexture, *selectedTexture, 256, 256, 0, *map));

   ////init two players
  //int idCount = 0;
  //players.emplace_back(House::Sardaukar, idCount++);
  //players.emplace_back(House::Harkonnen, idCount++);

  //units.emplace_back(unitRepository->create(UNIT_FRIGATE, House::Sardaukar, 3, 3, 10, SUBCELL_CENTER, players[0]));
  //units.emplace_back(unitRepository->create(UNIT_TRIKE, House::Sardaukar, 8, 8, 3, SUBCELL_CENTER, players[0]));

  //// soldiers
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Sardaukar, 14, 14, 3, SUBCELL_CENTER, players[0]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Sardaukar, 14, 14, 3, SUBCELL_UPLEFT, players[0]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Sardaukar, 14, 14, 3, SUBCELL_UPRIGHT, players[0]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Sardaukar, 14, 14, 3, SUBCELL_DOWNLEFT, players[0]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Sardaukar, 14, 14, 3, SUBCELL_DOWNRIGHT, players[0]));

  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Harkonnen, 18, 8, 3, SUBCELL_CENTER, players[1]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Harkonnen, 18, 8, 3, SUBCELL_UPLEFT, players[1]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Harkonnen, 18, 8, 3, SUBCELL_UPRIGHT, players[1]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Harkonnen, 18, 8, 3, SUBCELL_DOWNLEFT, players[1]));
  //units.emplace_back(unitRepository->create(UNIT_SOLDIER, House::Harkonnen, 18, 8, 3, SUBCELL_DOWNRIGHT, players[1]));

  //thor Actions here

  actionMap["boxStart"] = thor::Action(sf::Mouse::Left, thor::Action::PressOnce);
  actionMap["orderMove"] = thor::Action(sf::Mouse::Left, thor::Action::PressOnce);
  actionMap["boxDrag"] = thor::Action(sf::Mouse::Left, thor::Action::Hold);
  actionMap["boxRelease"] = thor::Action(sf::Mouse::Left, thor::Action::ReleaseOnce);
  actionMap["deselectAll"] = thor::Action(sf::Mouse::Right, thor::Action::PressOnce);
  actionMap["close"] = thor::Action(sf::Event::Closed) || thor::Action(sf::Keyboard::Q, thor::Action::PressOnce);
  actionMap["cameraLeft"] = thor::Action(sf::Keyboard::Left, thor::Action::Hold);
  actionMap["cameraRight"] = thor::Action(sf::Keyboard::Right, thor::Action::Hold);
  actionMap["cameraUp"] = thor::Action(sf::Keyboard::Up, thor::Action::Hold);
  actionMap["cameraDown"] = thor::Action(sf::Keyboard::Down, thor::Action::Hold);

  typedef thor::ActionContext<std::string> actionContext;

  system.connect("close", [this](actionContext){playing = false;});

  system.connect("boxRelease", [this](actionContext){
    for (auto& unit : units){
      if (box.intersects(unit->getBounds())){
        unit->select();
        system.connect("orderMove", [this, &unit](actionContext context){
          unit->order_move(screen.mapPixelToCoords(mouse.getHotspot(*context.event)));
        });
        mouse.setType(Mouse::Type::Move); //at least one unit selected...
      }
    }
    box.clear();
  });

  system.connect("boxStart", [this](actionContext context){
    sf::Vector2f toSet = screen.mapPixelToCoords(mouse.getHotspot(*context.event));
    box.setTopLeft(toSet);
  });

  system.connect("deselectAll", [this](actionContext){
//    system.clearConnections("orderMove"); // -> This is bugged in Thor
    mouse.setType(Mouse::Type::Default);
    for (auto& unit : units)
      unit->unselect();
  });

  system.connect("boxDrag", [this](actionContext){
    box.setBottomRight(screen.mapPixelToCoords(sf::Mouse::getPosition(screen)));
  });

  const float cameraSpeed = 15.f;

  system.connect("cameraLeft", [this, cameraSpeed](actionContext) {camera.move(-cameraSpeed, 0.f);});
  system.connect("cameraRight", [this, cameraSpeed](actionContext){camera.move(cameraSpeed, 0.f); });
  system.connect("cameraUp", [this, cameraSpeed](actionContext)   {camera.move(0.f, -cameraSpeed);});
  system.connect("cameraDown", [this, cameraSpeed](actionContext) {camera.move(0.f, cameraSpeed); });

  return true;
}

void Game::render() {
  screen.clear();

  screen.setView(camera);

  screen.draw(*map);

  for (const auto& unit : units)
      screen.draw(*unit);

  map->drawShrouded(screen, sf::RenderStates::Default);

  screen.draw(box);

  screen.draw(fpsCounter);

  screen.setView(camera);

  screen.draw(mouse);

  screen.display();
}

void Game::updateState(sf::Time dt) {
  actionMap.invokeCallbacks(system, &screen);

  sf::Vector2f half_of_camera = camera.getSize() / 2.f;
  sf::Vector2f topLeft = camera.getCenter() - (half_of_camera);
  sf::Vector2f downRight = camera.getCenter() + (half_of_camera);

  if (topLeft.x <= Cell::TILE_SIZE) camera.setCenter(half_of_camera.x + Cell::TILE_SIZE, camera.getCenter().y);
  if (topLeft.y <= Cell::TILE_SIZE) camera.setCenter(camera.getCenter().x, half_of_camera.y + Cell::TILE_SIZE);

  int max_width = (map->getMaxWidth() + 1) * Cell::TILE_SIZE;
  int max_height = (map->getMaxHeight() + 1) * Cell::TILE_SIZE;

  if (downRight.x >= max_width) camera.setCenter(max_width - half_of_camera.x, camera.getCenter().y);
  if (downRight.y >= max_height) camera.setCenter(camera.getCenter().x, max_height - half_of_camera.y);

  mouse.setPosition(screen.mapPixelToCoords(sf::Mouse::getPosition(screen),camera));

  for (auto& unit: units){
    unit->updateState();
  }

  fpsCounter.update(dt);
  map->prepare(screen.mapPixelToCoords(sf::Vector2i(0,0)));
}
<|endoftext|>