<commit_before>/*
 *  Camera.cpp
 *  Prueba Opengl iPad
 *
 *  Created by <NAME> on 24/01/11.
 *  Copyright 2011 Universidad de Las Palmas. All rights reserved.
 *
 */


#include "IMathUtils.hpp"
#include <string.h>

#include "Camera.hpp"
#include "Plane.hpp"
#include "GL.hpp"


void Camera::initialize(const InitializationContext* ic)
{
  _planet = ic->getPlanet();
  setCartesianPosition( MutableVector3D(_planet->getRadii().maxAxis() * 5, 0, 0) );
  _dirtyFlags.setAll(true);
}


void Camera::copyFrom(const Camera &that) {
  _width  = that._width;
  _height = that._height;
  
  _planet = that._planet;
  
  _position = MutableVector3D(that._position);
  _center   = MutableVector3D(that._center);
  _up       = MutableVector3D(that._up);
  
  _dirtyFlags.copyFrom(that._dirtyFlags);
  
  _frustumData = FrustumData(that._frustumData);
  
  _projectionMatrix = MutableMatrix44D(that._projectionMatrix);
  _modelMatrix      = MutableMatrix44D(that._modelMatrix);
  _modelViewMatrix  = MutableMatrix44D(that._modelViewMatrix);
  
  _cartesianCenterOfView = MutableVector3D(that._cartesianCenterOfView);
  
  _geodeticCenterOfView = (that._geodeticCenterOfView == NULL) ? NULL : new Geodetic3D(*that._geodeticCenterOfView);
  
#ifdef C_CODE
  if (_frustum != NULL) {
    delete _frustum;
  }
  if (_frustumInModelCoordinates != NULL) {
    delete _frustumInModelCoordinates;
  }
  if (_halfFrustum != NULL) {
    delete _halfFrustum;
  }
  if (_halfFrustumInModelCoordinates != NULL) {
    delete _halfFrustumInModelCoordinates;
  }
#endif
  
  _frustum = (that._frustum == NULL) ? NULL : new Frustum(*that._frustum);
  
  _frustumInModelCoordinates = (that._frustumInModelCoordinates == NULL) ? NULL : new Frustum(*that._frustumInModelCoordinates);
  
  _halfFrustum = (that._frustum == NULL) ? NULL : new Frustum(*that._frustum);
  
  _halfFrustumInModelCoordinates = (that._frustumInModelCoordinates == NULL) ? NULL : new Frustum(*that._frustumInModelCoordinates);
}

Camera::Camera(int width, int height) :
_width(0),
_height(0),
_planet(NULL),
_position(0, 0, 0),
_center(0, 0, 0),
_up(0, 0, 1),
_dirtyFlags(),
_frustumData(),
_projectionMatrix(),
_modelMatrix(),
_modelViewMatrix(),
_cartesianCenterOfView(0,0,0),
_geodeticCenterOfView(NULL),
_frustum(NULL),
_frustumInModelCoordinates(NULL),
_halfFrustumInModelCoordinates(NULL),
_halfFrustum(NULL)
{
  resizeViewport(width, height);
}

void Camera::resetPosition() {
  _position = MutableVector3D(0, 0, 0);
  _center = MutableVector3D(0, 0, 0);
  _up = MutableVector3D(0, 0, 1);
  
  _dirtyFlags.setAll(true);
  
  _frustumData = FrustumData();
  _projectionMatrix = MutableMatrix44D();
  _modelMatrix = MutableMatrix44D();
  _modelViewMatrix = MutableMatrix44D();
  _cartesianCenterOfView = MutableVector3D();
  
  if (_geodeticCenterOfView != NULL) delete _geodeticCenterOfView;
  _geodeticCenterOfView = NULL;
  
  if (_frustum != NULL) delete _frustum;
  _frustum = NULL;
  
  if (_frustumInModelCoordinates != NULL) delete _frustumInModelCoordinates;
  _frustumInModelCoordinates = NULL;
  
  if (_halfFrustumInModelCoordinates != NULL) delete _halfFrustumInModelCoordinates;
  _halfFrustumInModelCoordinates = NULL;
  
  if (_halfFrustum != NULL) delete _halfFrustum;
  _halfFrustum = NULL;
}

void Camera::resizeViewport(int width, int height) {
  _width = width;
  _height = height;
  
  _dirtyFlags._projectionMatrix = true;
  
  //cleanCachedValues();
}

void Camera::print() {
  getModelMatrix().print("Model Matrix", ILogger::instance());
  getProjectionMatrix().print("Projection Matrix", ILogger::instance());
  getModelViewMatrix().print("ModelView Matrix", ILogger::instance());
  ILogger::instance()->logInfo("Width: %d, Height %d\n", _width, _height);
}

void Camera::render(const RenderContext* rc) const {

  GL *gl = rc->getGL();
  gl->setProjection(getProjectionMatrix());
  gl->loadMatrixf(getModelMatrix());
    
//  // TEMP: TEST TO SEE HALF SIZE FRUSTUM CLIPPING 
//  if (false) {
//    const MutableMatrix44D inversed = getModelMatrix().inversed();
//    
//    const FrustumData data = calculateFrustumData();
//    const Vector3D p0(Vector3D(data._left/2, data._top/2, -data._znear-10).transformedBy(inversed, 1));
//    const Vector3D p1(Vector3D(data._left/2, data._bottom/2, -data._znear-10).transformedBy(inversed, 1));
//    const Vector3D p2(Vector3D(data._right/2, data._bottom/2, -data._znear-10).transformedBy(inversed, 1));
//    const Vector3D p3(Vector3D(data._right/2, data._top/2, -data._znear-10).transformedBy(inversed, 1));
//    
//    const float vertices[] = {
//      (float) p0.x(), (float) p0.y(), (float) p0.z(),
//      (float) p1.x(), (float) p1.y(), (float) p1.z(),
//      (float) p2.x(), (float) p2.y(), (float) p2.z(),
//      (float) p3.x(), (float) p3.y(), (float) p3.z(),    
//    };
//    const int indices[] = {0, 1, 2, 3};
//    
//    gl->enableVerticesPosition();
//    gl->vertexPointer(3, 0, vertices);
//    gl->lineWidth(2);
//    gl->color(1, 0, 1, 1);
//    gl->drawLineLoop(4, indices);
//    
//    gl->lineWidth(1);
//    gl->color(1, 1, 1, 1);
//  }
  

}


Vector3D Camera::pixel2Ray(const Vector2D& pixel) const {
  const int px = (int) pixel.x();
  const int py = _height - (int) pixel.y();
  const Vector3D pixel3D(px, py, 0);
    
  const Vector3D obj = getModelViewMatrix().unproject(pixel3D,
                                                      0, 0, _width, _height);
  if (obj.isNan()) {
    return obj; 
  }
    
  return obj.sub(_position.asVector3D());
}

Vector3D Camera::pixel2PlanetPoint(const Vector2D& pixel) const {
  return _planet->closestIntersection(_position.asVector3D(), pixel2Ray(pixel));
}

Vector2D Camera::point2Pixel(const Vector3D& point) const {  
  const Vector2D p = getModelViewMatrix().project(point,
                                                  0, 0, _width, _height);
  
  if (p.isNan()) {
    return p;
  }
  
  return Vector2D(p.x(), _height-p.y());
}

void Camera::applyTransform(const MutableMatrix44D& M) {
  setCartesianPosition( _position.transformedBy(M, 1.0) );
  setCenter( _center.transformedBy(M, 1.0) );
  
  setUp(  _up.transformedBy(M, 0.0) );
  
  //_dirtyFlags.setAll(true);
}

void Camera::dragCamera(const Vector3D& p0, const Vector3D& p1) {
  // compute the rotation axe
  const Vector3D rotationAxis = p0.cross(p1);
  
  // compute the angle
  //const Angle rotationDelta = Angle::fromRadians( - acos(p0.normalized().dot(p1.normalized())) );
  const Angle rotationDelta = Angle::fromRadians(-GMath.asin(rotationAxis.length()/p0.length()/p1.length()));
  
  if (rotationDelta.isNan()) {
    return; 
  }
  
  rotateWithAxis(rotationAxis, rotationDelta);
}


void Camera::rotateWithAxis(const Vector3D& axis, const Angle& delta) {
  applyTransform(MutableMatrix44D::createRotationMatrix(delta, axis));
}

void Camera::moveForward(double d) {
  const Vector3D view = _center.sub(_position).normalized().asVector3D();
  applyTransform(MutableMatrix44D::createTranslationMatrix(view.times(d)));
}

void Camera::pivotOnCenter(const Angle& a) {
  const Vector3D rotationAxis = _position.sub(_center).asVector3D();
  rotateWithAxis(rotationAxis, a);
}

void Camera::rotateWithAxisAndPoint(const Vector3D& axis, const Vector3D& point, const Angle& delta) {
  const MutableMatrix44D m = MutableMatrix44D::createGeneralRotationMatrix(delta, axis, point);
  applyTransform(m);
}

void Camera::setPosition(const Geodetic3D& g3d) {
  setCartesianPosition( _planet->toCartesian(g3d).asMutableVector3D() );
}

Vector3D Camera::centerOfViewOnPlanet() const {
  const Vector3D ray = _center.sub(_position).asVector3D();
  return _planet->closestIntersection(_position.asVector3D(), ray);
}

Vector3D Camera::getHorizontalVector() {
  int todo_remove_get_in_matrix;
  MutableMatrix44D M = getModelMatrix();
  return Vector3D(M.get(0), M.get(4), M.get(8));
}

Angle Camera::compute3DAngularDistance(const Vector2D& pixel0,
                                       const Vector2D& pixel1) {
  const Vector3D point0 = pixel2PlanetPoint(pixel0);
  if (point0.isNan()) {
    return Angle::nan();
  }
  
  const Vector3D point1 = pixel2PlanetPoint(pixel1);
  if (point1.isNan()) {
    return Angle::nan();
  }
  
  return point0.angleBetween(point1);
}
<commit_msg>updated code to draw half frustum on the screen<commit_after>/*
 *  Camera.cpp
 *  Prueba Opengl iPad
 *
 *  Created by <NAME> on 24/01/11.
 *  Copyright 2011 Universidad de Las Palmas. All rights reserved.
 *
 */


#include "IMathUtils.hpp"
#include <string.h>

#include "Camera.hpp"
#include "Plane.hpp"
#include "GL.hpp"
#include "FloatBufferBuilderFromCartesian3D.hpp"
#include "IntBufferBuilder.hpp"


void Camera::initialize(const InitializationContext* ic)
{
  _planet = ic->getPlanet();
  setCartesianPosition( MutableVector3D(_planet->getRadii().maxAxis() * 5, 0, 0) );
  _dirtyFlags.setAll(true);
}


void Camera::copyFrom(const Camera &that) {
  _width  = that._width;
  _height = that._height;
  
  _planet = that._planet;
  
  _position = MutableVector3D(that._position);
  _center   = MutableVector3D(that._center);
  _up       = MutableVector3D(that._up);
  
  _dirtyFlags.copyFrom(that._dirtyFlags);
  
  _frustumData = FrustumData(that._frustumData);
  
  _projectionMatrix = MutableMatrix44D(that._projectionMatrix);
  _modelMatrix      = MutableMatrix44D(that._modelMatrix);
  _modelViewMatrix  = MutableMatrix44D(that._modelViewMatrix);
  
  _cartesianCenterOfView = MutableVector3D(that._cartesianCenterOfView);
  
  _geodeticCenterOfView = (that._geodeticCenterOfView == NULL) ? NULL : new Geodetic3D(*that._geodeticCenterOfView);
  
#ifdef C_CODE
  if (_frustum != NULL) {
    delete _frustum;
  }
  if (_frustumInModelCoordinates != NULL) {
    delete _frustumInModelCoordinates;
  }
  if (_halfFrustum != NULL) {
    delete _halfFrustum;
  }
  if (_halfFrustumInModelCoordinates != NULL) {
    delete _halfFrustumInModelCoordinates;
  }
#endif
  
  _frustum = (that._frustum == NULL) ? NULL : new Frustum(*that._frustum);
  
  _frustumInModelCoordinates = (that._frustumInModelCoordinates == NULL) ? NULL : new Frustum(*that._frustumInModelCoordinates);
  
  _halfFrustum = (that._frustum == NULL) ? NULL : new Frustum(*that._frustum);
  
  _halfFrustumInModelCoordinates = (that._frustumInModelCoordinates == NULL) ? NULL : new Frustum(*that._frustumInModelCoordinates);
}

Camera::Camera(int width, int height) :
_width(0),
_height(0),
_planet(NULL),
_position(0, 0, 0),
_center(0, 0, 0),
_up(0, 0, 1),
_dirtyFlags(),
_frustumData(),
_projectionMatrix(),
_modelMatrix(),
_modelViewMatrix(),
_cartesianCenterOfView(0,0,0),
_geodeticCenterOfView(NULL),
_frustum(NULL),
_frustumInModelCoordinates(NULL),
_halfFrustumInModelCoordinates(NULL),
_halfFrustum(NULL)
{
  resizeViewport(width, height);
}

void Camera::resetPosition() {
  _position = MutableVector3D(0, 0, 0);
  _center = MutableVector3D(0, 0, 0);
  _up = MutableVector3D(0, 0, 1);
  
  _dirtyFlags.setAll(true);
  
  _frustumData = FrustumData();
  _projectionMatrix = MutableMatrix44D();
  _modelMatrix = MutableMatrix44D();
  _modelViewMatrix = MutableMatrix44D();
  _cartesianCenterOfView = MutableVector3D();
  
  if (_geodeticCenterOfView != NULL) delete _geodeticCenterOfView;
  _geodeticCenterOfView = NULL;
  
  if (_frustum != NULL) delete _frustum;
  _frustum = NULL;
  
  if (_frustumInModelCoordinates != NULL) delete _frustumInModelCoordinates;
  _frustumInModelCoordinates = NULL;
  
  if (_halfFrustumInModelCoordinates != NULL) delete _halfFrustumInModelCoordinates;
  _halfFrustumInModelCoordinates = NULL;
  
  if (_halfFrustum != NULL) delete _halfFrustum;
  _halfFrustum = NULL;
}

void Camera::resizeViewport(int width, int height) {
  _width = width;
  _height = height;
  
  _dirtyFlags._projectionMatrix = true;
  
  //cleanCachedValues();
}

void Camera::print() {
  getModelMatrix().print("Model Matrix", ILogger::instance());
  getProjectionMatrix().print("Projection Matrix", ILogger::instance());
  getModelViewMatrix().print("ModelView Matrix", ILogger::instance());
  ILogger::instance()->logInfo("Width: %d, Height %d\n", _width, _height);
}

void Camera::render(const RenderContext* rc) const {

  GL *gl = rc->getGL();
  gl->setProjection(getProjectionMatrix());
  gl->loadMatrixf(getModelMatrix());
    
  // TEMP: TEST TO SEE HALF SIZE FRUSTUM CLIPPING 
  if (false) {
    const MutableMatrix44D inversed = getModelMatrix().inversed();
    
    const FrustumData data = calculateFrustumData();
    const Vector3D p0(Vector3D(data._left/2, data._top/2, -data._znear-10).transformedBy(inversed, 1));
    const Vector3D p1(Vector3D(data._left/2, data._bottom/2, -data._znear-10).transformedBy(inversed, 1));
    const Vector3D p2(Vector3D(data._right/2, data._bottom/2, -data._znear-10).transformedBy(inversed, 1));
    const Vector3D p3(Vector3D(data._right/2, data._top/2, -data._znear-10).transformedBy(inversed, 1));
    
    const float v[] = {
      (float) p0.x(), (float) p0.y(), (float) p0.z(),
      (float) p1.x(), (float) p1.y(), (float) p1.z(),
      (float) p2.x(), (float) p2.y(), (float) p2.z(),
      (float) p3.x(), (float) p3.y(), (float) p3.z(),    
    };
    const int i[] = {0, 1, 2, 3};
    
#ifdef C_CODE
    FloatBufferBuilderFromCartesian3D vertices(NoCenter, Vector3D::zero());
#else
    FloatBufferBuilderFromCartesian3D vertices(CenterStrategy.NoCenter, Vector3D::zero());
#endif
    IntBufferBuilder index;
    
    for (unsigned int n=0; n<4; n++) 
      vertices.add(v[3*n], v[3*n+1], v[3*n+2]);
    
    for (unsigned int n=0; n<4; n++)
      index.add(i[n]);

    IIntBuffer* _indices = index.create();
    IFloatBuffer* _vertices = vertices.create();

    gl->enableVerticesPosition();
    gl->vertexPointer(3, 0, _vertices);
    gl->lineWidth(2);
    gl->color(1, 0, 1, 1);
    gl->drawLineLoop(_indices);
    
    gl->lineWidth(1);
    gl->color(1, 1, 1, 1);
  }
  

}


Vector3D Camera::pixel2Ray(const Vector2D& pixel) const {
  const int px = (int) pixel.x();
  const int py = _height - (int) pixel.y();
  const Vector3D pixel3D(px, py, 0);
    
  const Vector3D obj = getModelViewMatrix().unproject(pixel3D,
                                                      0, 0, _width, _height);
  if (obj.isNan()) {
    return obj; 
  }
    
  return obj.sub(_position.asVector3D());
}

Vector3D Camera::pixel2PlanetPoint(const Vector2D& pixel) const {
  return _planet->closestIntersection(_position.asVector3D(), pixel2Ray(pixel));
}

Vector2D Camera::point2Pixel(const Vector3D& point) const {  
  const Vector2D p = getModelViewMatrix().project(point,
                                                  0, 0, _width, _height);
  
  if (p.isNan()) {
    return p;
  }
  
  return Vector2D(p.x(), _height-p.y());
}

void Camera::applyTransform(const MutableMatrix44D& M) {
  setCartesianPosition( _position.transformedBy(M, 1.0) );
  setCenter( _center.transformedBy(M, 1.0) );
  
  setUp(  _up.transformedBy(M, 0.0) );
  
  //_dirtyFlags.setAll(true);
}

void Camera::dragCamera(const Vector3D& p0, const Vector3D& p1) {
  // compute the rotation axe
  const Vector3D rotationAxis = p0.cross(p1);
  
  // compute the angle
  //const Angle rotationDelta = Angle::fromRadians( - acos(p0.normalized().dot(p1.normalized())) );
  const Angle rotationDelta = Angle::fromRadians(-GMath.asin(rotationAxis.length()/p0.length()/p1.length()));
  
  if (rotationDelta.isNan()) {
    return; 
  }
  
  rotateWithAxis(rotationAxis, rotationDelta);
}


void Camera::rotateWithAxis(const Vector3D& axis, const Angle& delta) {
  applyTransform(MutableMatrix44D::createRotationMatrix(delta, axis));
}

void Camera::moveForward(double d) {
  const Vector3D view = _center.sub(_position).normalized().asVector3D();
  applyTransform(MutableMatrix44D::createTranslationMatrix(view.times(d)));
}

void Camera::pivotOnCenter(const Angle& a) {
  const Vector3D rotationAxis = _position.sub(_center).asVector3D();
  rotateWithAxis(rotationAxis, a);
}

void Camera::rotateWithAxisAndPoint(const Vector3D& axis, const Vector3D& point, const Angle& delta) {
  const MutableMatrix44D m = MutableMatrix44D::createGeneralRotationMatrix(delta, axis, point);
  applyTransform(m);
}

void Camera::setPosition(const Geodetic3D& g3d) {
  setCartesianPosition( _planet->toCartesian(g3d).asMutableVector3D() );
}

Vector3D Camera::centerOfViewOnPlanet() const {
  const Vector3D ray = _center.sub(_position).asVector3D();
  return _planet->closestIntersection(_position.asVector3D(), ray);
}

Vector3D Camera::getHorizontalVector() {
  int todo_remove_get_in_matrix;
  MutableMatrix44D M = getModelMatrix();
  return Vector3D(M.get(0), M.get(4), M.get(8));
}

Angle Camera::compute3DAngularDistance(const Vector2D& pixel0,
                                       const Vector2D& pixel1) {
  const Vector3D point0 = pixel2PlanetPoint(pixel0);
  if (point0.isNan()) {
    return Angle::nan();
  }
  
  const Vector3D point1 = pixel2PlanetPoint(pixel1);
  if (point1.isNan()) {
    return Angle::nan();
  }
  
  return point0.angleBetween(point1);
}

{'fraction_non_alphanumeric': 0.1400505852596906, 'fraction_numerical': 0.025469090053526263, 'mean_word_length': 4.2378311768330255, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4656114', 'n_tokens_mistral': 6253, 'n_tokens_neox': 6051, 'n_words': 1137}