Commit 0922bc3f authored by Markus Wiedemann's avatar Markus Wiedemann

-- added second project

parent 0954d207
This diff is collapsed.
#ifndef MAGNUM_GLM_INTEGRATION_H
#define MAGNUM_GLM_INTEGRATION_H
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/vector_relational.hpp>
#include <glm/matrix.hpp>
#include <glm/gtc/quaternion.hpp>
#include <Magnum/Math/RectangularMatrix.h>
#include <Magnum/Math/Quaternion.h>
namespace Magnum {
namespace Math {
namespace Implementation {
// Magnum::VectorX <> glm::vecX
template<> struct VectorConverter <2, float, glm::vec2> {
static Vector<2, Float> from(const glm::vec2& other) {
return{ other.x, other.y };
}
static glm::vec2 to(const Vector<2, Float>& other) {
return{ other[0], other[1] };
}
};
template<> struct VectorConverter <3, float, glm::vec3> {
static Vector<3, Float> from(const glm::vec3& other) {
return{ other.x, other.y, other.z };
}
static glm::vec3 to(const Vector<3, Float>& other) {
return{ other[0], other[1], other[2] };
}
};
template<> struct VectorConverter <4, float, glm::vec4> {
static Vector<4, Float> from(const glm::vec4& other) {
return{ other.x, other.y, other.z, other.w };
}
static glm::vec4 to(const Vector<4, Float>& other) {
return{ other[0], other[1], other[2], other[3] };
}
};
//
template<> struct VectorConverter <2, int, glm::ivec2> {
static Vector<2, Int> from(const glm::ivec2& other) {
return{ other.x, other.y };
}
static glm::ivec2 to(const Vector<2, Int>& other) {
return{ other[0], other[1] };
}
};
template<> struct VectorConverter <3, Int, glm::ivec3> {
static Vector<3, Int> from(const glm::ivec3& other) {
return{ other.x, other.y, other.z };
}
static glm::ivec3 to(const Vector<3, Int>& other) {
return{ other[0], other[1], other[2] };
}
};
template<> struct VectorConverter <4, Int, glm::ivec4> {
static Vector<4, Int> from(const glm::ivec4& other) {
return{ other.x, other.y, other.z , other.w };
}
static glm::ivec4 to(const Vector<4, Int>& other) {
return{ other[0], other[1], other[2], other[3] };
}
};
// Magnum::Matrix <> glm::mat
template<> struct RectangularMatrixConverter<3, 3, float, glm::mat3> {
static RectangularMatrix<3, 3, Float> from(const glm::mat3& other) {
return{ Vector<3, Float>(other[0]),
Vector<3, Float>(other[1]),
Vector<3, Float>(other[2]) };
}
static glm::mat3 to(const RectangularMatrix<3, 3, Float>& other) {
return{ other[0][0], other[0][1], other[0][2],
other[1][0], other[1][1], other[1][2],
other[2][0], other[2][1], other[2][2] };
}
};
template<> struct RectangularMatrixConverter<4, 4, float, glm::mat4> {
static RectangularMatrix<4, 4, Float> from(const glm::mat4& other) {
return{ Vector<4, Float>(other[0]),
Vector<4, Float>(other[1]),
Vector<4, Float>(other[2]),
Vector<4, Float>(other[3])};
}
static glm::mat4 to(const RectangularMatrix<4, 4, Float>& other) {
return{ other[0][0], other[0][1], other[0][2], other[0][3],
other[1][0], other[1][1], other[1][2], other[1][3],
other[2][0], other[2][1], other[2][2], other[2][3],
other[3][0], other[3][1], other[3][2], other[3][3]};
}
};
// Magnum::Quaternion <> glm::quat
// note:: glm elementwize constructor takes {wxyz} order
template<> struct QuaternionConverter<float, glm::quat> {
static Quaternion<Float> from(const glm::quat& other) {
return{ { other.x, other.y, other.z }, other.w };
}
static glm::quat to(const Quaternion<Float>& other) {
return{ other.scalar(), other.vector().x(), other.vector().y(), other.vector().z() };
}
};
}
}
}
#endif
\ No newline at end of file
#include <Magnum/MeshTools/Compile.h>
#include <Magnum/SceneGraph/Camera.h>
#include <Magnum/SceneGraph/Scene.h>
#include <Magnum/Trade/MeshData3D.h>
#include <Magnum/Primitives/UVSphere.h>
#include <Magnum/SceneGraph/Animable.h>
#include "Planet.h"
Planet::Planet(Object3D &parent, SceneGraph::DrawableGroup3D &group, SceneGraph::AnimableGroup3D &animableGroup, planetType name, Vector3 position, Vector3 velocity) :
TexturedSphere{ parent, group },
SceneGraph::Animable3D{ *this, &animableGroup },
_velocity{ velocity }, _name{ name }{
switch (name) {
// Real masses and radius are changed to make it atractive for the CAVE
case SUN:
_mass = 10000; // 1988500;
_radius = 696 * SUN_SCALE;
setTexture("sun.jpg");
setAmbientColorShader(Color3(1.0f));
break;
case MERCURY:
_mass = 1; //0.3302;
_radius = 2.440 * PLANET_SCALE;
setTexture("mercury.jpg");
break;
case VENUS:
_mass = 1; //0.48685;
_radius = 6.05184* PLANET_SCALE;
setTexture("venus_atmosphere.jpg"); //venus_surface.jpg
break;
case EARTH:
_mass = 5.97219;
_radius =6.37101* PLANET_SCALE;
setTexture("earth_realistic.jpg");
break;
case MARS:
_mass = 1; // 0.64171;
_radius = 3.38992* PLANET_SCALE;
setTexture("mars.jpg");
break;
case JUPITER:
_mass = 100; //1898.13;
_radius = 69.911 * PLANET_SCALE/4;
setTexture("jupiter.jpg");
break;
case SATURN:
_mass = 100; // 568.34;
_radius = 58.232* PLANET_SCALE/4;
setTexture("saturn.jpg");
break;
case URANUS:
_mass = 86.813;
_radius = 25.362* PLANET_SCALE/4;
setTexture("uranus.jpg");
break;
case NEPTUNE:
_mass = 90; // 102.413;
_radius = 24.624* PLANET_SCALE/4;
setTexture("neptune.jpg");
break;
case DEATH_STAR:
_mass = 1;
_radius = 1.5* PLANET_SCALE;
setTexture("deathstar-texture.jpg");
break;
default: break;
};
rescale();
this->translate(position);
_acceleration = Vector3(0, 0, 0);
this->setState(SceneGraph::AnimationState::Running);
}
void Planet::changePositionTo(Vector3 newPosition) {
auto actualPosition = this->transformation().translation();
this->translate(newPosition - actualPosition);
}
void Planet::animationStep(Float time, Float delta) {
float msDelata = delta / MS_TIME_DIVIDER;
this->rotateYLocal(PLANET_ROTOATION_SPEED * msDelata/_radius);
};
#pragma once
#ifndef PLANET_H
#define PLANET_H
#include <Magnum/GL/Mesh.h>
#include <Magnum/SceneGraph/Drawable.h>
#include <Magnum/SceneGraph/MatrixTransformation3D.h>
#include <Magnum/Shaders/Phong.h>
#include "types.h"
#include "TexturedSphere.h"
enum planetType { SUN, MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE, DEATH_STAR};
class Planet :public TexturedSphere, public SceneGraph::Animable3D {
public:
explicit Planet(Object3D &parent, SceneGraph::DrawableGroup3D &group, SceneGraph::AnimableGroup3D & animableGroup, planetType name, Vector3 position, Vector3 velocity);
Vector3 position() { return this->transformation().translation(); }
Vector3 velocity() { return _velocity; }
void velocity(Vector3 newVelocity) { _velocity = newVelocity; }
Vector3 acceleration() { return _acceleration; }
void acceleration(Vector3 newAcceleration) { _acceleration = newAcceleration; }
float mass() { return _mass; }
void mass(float newMass) { _mass = newMass; }
float radius() { return _radius; }
void radius(float newRadius) { _radius = newRadius; }
void rescale() { this->scaleLocal(Vector3(2 * _radius, 2 * _radius, 2 * _radius)); }
bool isSun(void) { return (_name == SUN); }
void changePositionTo(Vector3 newPosition);
private:
void animationStep(Float time, Float delta) override;
float _mass, _radius;
Vector3 _velocity, _acceleration;
planetType _name;
};
#endif // PLANET_H
\ No newline at end of file
#include "SolarSystem.h"
SolarSystem::SolarSystem(Object3D &scene, SceneGraph::DrawableGroup3D &drawGroup, SceneGraph::AnimableGroup3D & animablePhysics, SceneGraph::AnimableGroup3D & animablePlanets) :
Object3D(&scene),
SceneGraph::Animable3D{ *this, &animablePhysics },
_parentScene{ &scene },
_drawableGroup{ &drawGroup },
_animablePlanets{ &animablePlanets } {
addPlanet(SUN, Vector3(SUN_X_POSITION, SUN_Y_POSITION, SUN_Z_POSITION), Vector3(0));
#ifndef CAVE_BUILD
for (auto i = 1; i <= PLANET_NUMBER*4; i++)
if((i % PLANET_NUMBER) != 0)
addPlanet((planetType) (i % PLANET_NUMBER),
Vector3(std::fmod(std::rand() - (RAND_MAX / 2.0f), 200) + SUN_X_POSITION, SUN_Y_POSITION, std::fmod(std::rand() - (RAND_MAX / 2.0f), 200) + SUN_Z_POSITION),
Vector3(std::fmod(std::rand() - (RAND_MAX / 2.0f), 15), 0.0, std::fmod(std::rand() - (RAND_MAX / 2.0f), 15))
);
#endif
}
// Real Data for planets position ans speed at the 20th of September 2018 00:00hs
// Because of the scale it is not used. the distance and size rlations are too big for the CAVE
void SolarSystem::crateSolarSystem(void) {
// UNITS: 1000km(radius, position) 10^24Kg Km/s velocity
// Sun
addPlanet(SUN, Vector3(0, 0, 0), Vector3(0, 0, 0));
// Mercury
addPlanet(MERCURY, KM_SCALE * Vector3(-55951.31376164873, 6505.356825148592, 5664.451778776714), Vector3(-15.74804703579815, -46.29531491101928, -2.338252221404112));
// Venus
addPlanet(VENUS, KM_SCALE *Vector3(98208.51483299191, -46593.31565682072, -6306.411522406572), Vector3(14.80983348227688, 31.49194277621033, -0.4226152372329910));
// Earth
addPlanet(EARTH, KM_SCALE *Vector3(150012.6523928148, -8550.390685626360, -0.2661723460517824), Vector3(1.200838240517373, 29.62286549704665, -0.002333564693390855));
// Mars
addPlanet(MARS, KM_SCALE *Vector3(1.920600785903122E+05, -7.607343499123040E+04, -6.306791988720104E+03), Vector3(9.845184358865064E+00, 2.459754681173505E+01, 2.738418495860966E-01));
// Jupiter
addPlanet(JUPITER, KM_SCALE *Vector3(-4.209903844914538E+05, -6.855350135611911E+05, 1.226714709343639E+04), Vector3(1.098702977315013E+01, -6.227521318801336E+00, -2.199636635297502E-01));
// Saturn
addPlanet(SATURN, KM_SCALE *Vector3(2.130383050866511E+05, -1.490256838402048E+06, 1.742423959308326E+04), Vector3(9.044478290163623E+00, 1.331406696597614E+00, -3.826833656939383E-01));
// Uranus
addPlanet(URANUS, KM_SCALE *Vector3(2.576654726248682E+06, 1.482992270675215E+06, -2.785755580056030E+04), Vector3(-3.435807313921672E+00, 5.578834296410563E+00, 6.492213406020664E-02));
// Neptune
addPlanet(NEPTUNE, KM_SCALE *Vector3(4.323563633199759E+06, -1.167302628486269E+06, -7.561319239306915E+04), Vector3(1.392064358609194E+00, 5.275631776178466E+00, -1.401382406053540E-01));
}
void SolarSystem::removeAllPlanets() {
for (std::list<Planet *>::iterator itr = planets.begin(); itr != planets.end(); /*nothing*/){
if (itr != planets.begin()) {
delete (*itr);
itr = planets.erase(itr);
}
else
itr++;
}
}
void SolarSystem::animationStep(Float time, Float delta) {
// do the Pysics!!!
#ifdef CAVE_BUILD
delta = 1000 / SYSTEM_FPS;
#endif
if (delta > 100)
return;
float msDelata = delta / MS_TIME_DIVIDER;
Vector3 a, d;
for (auto &i : planets) {
a = Vector3(0, 0, 0);
for (std::list<Planet *>::iterator itr = planets.begin(); itr != planets.end(); /*nothing*/) {
if (i != *itr) {
// Calculate Distance and acceleration (F/m) component from every planet
d = (*itr)->position() - i->position();
auto modDist = d.length();
// Detect collition. The bigest planet gets the mass of the smallest
if (modDist < std::max(std::max(i->radius(), (*itr)->radius()), ((float)0.8 * (i->radius() + (*itr)->radius())))) {
// Collision
if (i->radius() < (*itr)->radius()) {
Planet *aux = i;
i = (*itr);
(*itr) = aux;
}
auto finalMass = i->mass() + (*itr)->mass();
i->velocity(((i->mass() * i->velocity()) + ((*itr)->mass() * (*itr)->velocity())) / finalMass);
i->changePositionTo(i->position() + (*itr)->mass() / i->mass() * d);
i->mass(finalMass);
i->radius(sqrt((i->radius()* i->radius()) + ((*itr)->radius() * (*itr)->radius())));
delete (*itr);
itr = planets.erase(itr);
continue;
}
else {
a += (*itr)->mass() * d / pow(modDist, 3);
}
}
++itr;
}
// Calculate and save the acceleration for every planet
a *= GRAVITY;
i->acceleration(a);
}
// Compute the new Position and velocity
for (auto const &i : planets) {
if (!(i->isSun())) {
i->changePositionTo(i->position() + i->velocity() * msDelata + 0.5 * i->acceleration() * pow(msDelata, 2));
i->velocity(i->velocity() + i->acceleration() * msDelata);
}
}
}
#pragma once
#ifndef SOLARSYSTEM_H
#define SOLARSYSTEM_H
#include <Magnum/SceneGraph/Animable.h>
#include "types.h"
#include "Planet.h"
#include <list>
// Class for administraiting the positions, speed and forces between planets.
class SolarSystem :public Object3D, public SceneGraph::Animable3D {
public:
explicit SolarSystem(Object3D &scene, SceneGraph::DrawableGroup3D &drawGroup, SceneGraph::AnimableGroup3D &animablePhysics, SceneGraph::AnimableGroup3D &animablePlanets);
void addPlanet(planetType type, Vector3 position, Vector3 velocity) {
planets.push_back(new Planet{ *this, *_drawableGroup, *_animablePlanets, type, position, velocity });
}
void addPlanet(Planet *newPlanet) {
newPlanet->setParent(this);
planets.push_back(newPlanet);
}
void crateSolarSystem(void);
void removeAllPlanets(void);
private:
void animationStep(Float time, Float delta) override;
Object3D *_parentScene;
SceneGraph::DrawableGroup3D *_drawableGroup;
SceneGraph::AnimableGroup3D * _animablePlanets;
std::list < Planet* > planets;
};
#endif //SOLARSYSTEM_H
\ No newline at end of file
#include "TexturedSphere.h"
#include <Magnum/GL/Buffer.h>
#include <Magnum/GL/Mesh.h>
#include <Magnum/GL/Texture.h>
#include <Magnum/GL/TextureFormat.h>
#include <Magnum/MeshTools/CompressIndices.h>
#include <Magnum/MeshTools/Interleave.h>
#include <Magnum/MeshTools/FlipNormals.h>
#include <Magnum/Primitives/UVSphere.h>
#include <Magnum/SceneGraph/Camera.h>
#include <Magnum/Trade/AbstractImporter.h>
#include <Magnum/Trade/ImageData.h>
#include <Magnum/Trade/MeshData3D.h>
TexturedSphere& TexturedSphere::setTexture(const std::string& textureFile) {
SolarSystemResourceManager& resourceManager = SolarSystemResourceManager::instance();
if (_background) {
_sphere = resourceManager.get<GL::Mesh>("background");
}
else {
_sphere = resourceManager.get<GL::Mesh>("sphere");
_shaderPhong.setShininess(1000.0f);
}
/* Create the Sphere mesh and save it in the Resource manager*/
if (!_sphere) {
Trade::MeshData3D sphereData = Primitives::uvSphereSolid(16 * 10, 10 * 32, Primitives::UVSphereTextureCoords::Generate);
GL::Buffer* buffer = new GL::Buffer;
// For the background use the texture on the inside
if (_background) {
MeshTools::flipFaceWinding(sphereData.indices());
buffer->setData(MeshTools::interleave(sphereData.positions(0), sphereData.textureCoords2D(0)), GL::BufferUsage::StaticDraw);
}
else
buffer->setData(MeshTools::interleave(sphereData.positions(0), sphereData.normals(0), sphereData.textureCoords2D(0)), GL::BufferUsage::StaticDraw);
Containers::Array<char> indexData;
MeshIndexType indexType;
UnsignedInt indexStart, indexEnd;
std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(sphereData.indices());
GL::Buffer* indexBuffer = new GL::Buffer;
indexBuffer->setData(indexData, GL::BufferUsage::StaticDraw);
GL::Mesh* mesh = new GL::Mesh;
if (_background) {
mesh->setPrimitive(sphereData.primitive())
.setCount(sphereData.indices().size())
.addVertexBuffer(*buffer, 0, Shaders::Flat3D::Position{}, Shaders::Flat3D::TextureCoordinates{})
.setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd);
resourceManager.set("background-buffer", buffer, ResourceDataState::Final, ResourcePolicy::Resident)
.set("background-index-buffer", indexBuffer, ResourceDataState::Final, ResourcePolicy::Resident)
.set(_sphere.key(), mesh, ResourceDataState::Final, ResourcePolicy::Resident);
}
else {
mesh->setPrimitive(sphereData.primitive())
.setCount(sphereData.indices().size())
.addVertexBuffer(*buffer, 0,
Shaders::Phong::Position{},
Shaders::Phong::Normal{},
Shaders::Phong::TextureCoordinates{})
.setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd);
resourceManager.set("sphere-buffer", buffer, ResourceDataState::Final, ResourcePolicy::Resident)
.set("sphere-index-buffer", indexBuffer, ResourceDataState::Final, ResourcePolicy::Resident)
.set(_sphere.key(), mesh, ResourceDataState::Final, ResourcePolicy::Resident);
}
}
/* Load the Texture in the resource manager if it isn't allready loaded */
if (!(_texture = resourceManager.get<GL::Texture2D>(textureFile))) {
Resource<Trade::AbstractImporter> importer = resourceManager.get<Trade::AbstractImporter>("jpeg-importer");
importer->openFile(TEXTURES_PATH + textureFile);
Containers::Optional<Trade::ImageData2D> image = importer->image2D(0);
CORRADE_INTERNAL_ASSERT(image);
auto texture = new GL::Texture2D;
texture->setWrapping(GL::SamplerWrapping::ClampToEdge)
.setMagnificationFilter(GL::SamplerFilter::Linear)
.setMinificationFilter(GL::SamplerFilter::Linear, GL::SamplerMipmap::Linear)
.setStorage(Math::log2(image->size().min()) + 1, GL::TextureFormat::RGB8, image->size())
.setSubImage(0, {}, *image)
.generateMipmap();
resourceManager.set<GL::Texture2D>(_texture.key(), texture, ResourceDataState::Final, ResourcePolicy::Resident);
}
}
void TexturedSphere::draw(const Matrix4& transformationMatrix, SceneGraph::Camera3D& camera) {
// Use the flat shader for the background
if (_background) {
_shaderFlat.setTransformationProjectionMatrix(camera.projectionMatrix()*transformationMatrix)
.bindTexture(*_texture);
_sphere->draw(_shaderFlat);
}
else {
_shaderPhong
.setLightPosition(camera.cameraMatrix().transformPoint(Vector3(SUN_X_POSITION, SUN_Y_POSITION, SUN_Z_POSITION)))
.setTransformationMatrix(transformationMatrix)
.setNormalMatrix(transformationMatrix.rotationScaling())
.setProjectionMatrix(camera.projectionMatrix())
.setAmbientColor(_color)
.bindAmbientTexture(*_texture)
.bindDiffuseTexture(*_texture);
_sphere->draw(_shaderPhong);
}
}
#pragma once
#ifndef TexturedSphere_h
#define TexturedSphere_h
#include <Magnum/SceneGraph/Drawable.h>
#include <Magnum/Shaders/Phong.h>
#include <Magnum/Shaders/Flat.h>
#include "types.h"
class TexturedSphere:public Object3D, public SceneGraph::Drawable3D {
public:
TexturedSphere(Object3D &scene, SceneGraph::DrawableGroup3D &drawGroup, bool background = false):
Object3D(&scene),
SceneGraph::Drawable3D{ *this, &drawGroup },
_background{ background } { _color = Color3(0.2f); }
void draw(const Matrix4& transformationMatrix, SceneGraph::Camera3D& camera) override;
TexturedSphere& setTexture(const std::string& textureFile);
void setAmbientColorShader(Color3 color) { _color = color; };
private:
bool _background, _shaderType;
Resource<GL::Mesh> _sphere;
Resource<GL::Texture2D> _texture;
Color3 _color;
Shaders::Phong _shaderPhong{ Shaders::Phong::Flag::DiffuseTexture | Shaders::Phong::Flag::AmbientTexture };
Shaders::Flat3D _shaderFlat{ Shaders::Flat3D::Flag::Textured };
};
#endif
\ No newline at end of file
#include "types.h"
#include <Magnum/GL/Buffer.h>
#include <Magnum/GL/Mesh.h>
#include <Magnum/GL/Texture.h>
#include <Magnum/Trade/AbstractImporter.h>
template class ResourceManager<GL::Buffer, GL::Mesh, Trade::AbstractImporter, GL::Texture2D>;
#pragma once
#ifndef TYPES_H
#define TYPES_H
#include <Magnum/SceneGraph/Scene.h>
#include <Magnum/SceneGraph/MatrixTransformation3D.h>
#include <Magnum/ResourceManager.h>
#include <Magnum/GL/GL.h>
#include <Magnum/Trade/Trade.h>
#include <Magnum/GL/Buffer.h>
#include <Magnum/GL/Mesh.h>
#include <Magnum/GL/Texture.h>
#include <Magnum/Trade/AbstractImporter.h>
using namespace Magnum;
using namespace Math::Literals;
extern template class ResourceManager<GL::Buffer, GL::Mesh, Trade::AbstractImporter, GL::Texture2D>;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
typedef ResourceManager<GL::Buffer, GL::Mesh, Trade::AbstractImporter, GL::Texture2D> SolarSystemResourceManager;
#define CAVE_BUILD
#define GRAVITY 1.0f //6.67408 10-11 m3 kg-1 s-2
#define VEL_SCALE 100.0f
#define KM_SCALE (1/1000.0f)
#define MS_TIME_DIVIDER (100.0f)
#define PLANET_NUMBER 9
#define PLANET_ROTOATION_SPEED (0.2* 360.0_degf/1000.0*MS_TIME_DIVIDER)
#define MENU_DISTANCE 110
#define MENU_ANGLE (180.0_degf/(PLANET_NUMBER-1))
#define SPACE_SIZE (10000)
#define SUN_SCALE (15/696.0f)
#define PLANET_SCALE (1/2.5f)
#define SUN_X_POSITION (0.0f)
#define SUN_Y_POSITION (100.0f)
#define SUN_Z_POSITION (-110.0f)
#define SYSTEM_FPS (60.0)
#ifndef CAVE_BUILD
#define TEXTURES_PATH "..\\src\\textures\\"
#else
#define TEXTURES_PATH "src/textures/"
#endif //CAVE_BUILD