Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c2882035b5 | |||
| 23dd149d48 | |||
| 9057c94af9 | |||
| 8b1546cb54 | |||
| 26a7e48784 | |||
| b936db0ce9 | |||
| b51c63ea0c | |||
| ad56096eb3 | |||
| 2f5437396c |
@@ -13,9 +13,6 @@
|
|||||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
*.userprefs
|
*.userprefs
|
||||||
|
|
||||||
# Mono auto generated files
|
|
||||||
mono_crash.*
|
|
||||||
|
|
||||||
# Build results
|
# Build results
|
||||||
[Dd]ebug/
|
[Dd]ebug/
|
||||||
[Dd]ebugPublic/
|
[Dd]ebugPublic/
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
#include "COLLADA.h"
|
|
||||||
|
|
||||||
COLLADA::COLLADA(const char* filename)
|
|
||||||
{
|
|
||||||
tinyxml2::XMLDocument doc;
|
|
||||||
doc.LoadFile(filename);
|
|
||||||
tinyxml2::XMLElement* xml = doc.FirstChildElement("COLLADA");
|
|
||||||
m_GeometryLibrary = GeometryLibrary(xml->FirstChildElement("library_geometries"));
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "GeometryLibrary.h"
|
|
||||||
class COLLADA
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
GeometryLibrary m_GeometryLibrary;
|
|
||||||
//ImagesLibrary m_ImagesLibrary;
|
|
||||||
//EffectsLibrary m_EffectsLibrary;
|
|
||||||
//MaterialLibrary m_MaterialLibrary;
|
|
||||||
//ControllerLibrary m_ControllerLibrary;
|
|
||||||
//AnimationLibrary m_AnimationLibrary;
|
|
||||||
VisualSceneLibrary m_VisualSceneLibrary;
|
|
||||||
|
|
||||||
public:
|
|
||||||
COLLADA() = default;
|
|
||||||
COLLADA(const char* filename);
|
|
||||||
};
|
|
||||||
|
|
||||||
+131
-12
@@ -6,7 +6,7 @@
|
|||||||
#define PI 3.14159265358979323846
|
#define PI 3.14159265358979323846
|
||||||
#define DEG2RAD PI/180
|
#define DEG2RAD PI/180
|
||||||
|
|
||||||
ColladaModel::ColladaModel(const char* filename) : faces_(), vertices_(), normals_()
|
ColladaModel::ColladaModel(const char* filename) : faces_(), vertices_(), normals_(), rootjoint()
|
||||||
{
|
{
|
||||||
Transform = Matrix::identity();
|
Transform = Matrix::identity();
|
||||||
Rotation = Matrix::identity();
|
Rotation = Matrix::identity();
|
||||||
@@ -15,11 +15,14 @@ ColladaModel::ColladaModel(const char* filename) : faces_(), vertices_(), normal
|
|||||||
|
|
||||||
tinyxml2::XMLDocument doc;
|
tinyxml2::XMLDocument doc;
|
||||||
doc.LoadFile(filename);
|
doc.LoadFile(filename);
|
||||||
|
|
||||||
|
load_texture(filename, "_diffuse.tga", diffusemap_);
|
||||||
|
load_texture(filename, "_nm_tangent.tga", normalmap_);
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////faces//////////////////////////////////////////////////
|
////////////////////////////////////////////////faces//////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
face_count = 0;
|
face_count = 0;
|
||||||
tinyxml2::XMLElement* xml_face = doc.FirstChildElement("COLLADA")->FirstChildElement("library_geometries")->FirstChildElement("geometry")->FirstChildElement("mesh")->FirstChildElement("triangles");
|
tinyxml2::XMLElement* xml_face = doc.FirstChildElement("COLLADA")->FirstChildElement("library_geometries")->FirstChildElement()->FirstChildElement()->FirstChildElement("triangles");
|
||||||
xml_face->QueryIntAttribute("count", &face_count); //get count
|
xml_face->QueryIntAttribute("count", &face_count); //get count
|
||||||
std::stringstream str_triangle(xml_face->FirstChildElement("p")->GetText()); //get values as a string
|
std::stringstream str_triangle(xml_face->FirstChildElement("p")->GetText()); //get values as a string
|
||||||
|
|
||||||
@@ -54,7 +57,7 @@ ColladaModel::ColladaModel(const char* filename) : faces_(), vertices_(), normal
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////normal////////////////////////////////////////////////////
|
/////////////////////////////////////////////normal////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
normal_count = 0;
|
int normal_count = 0;
|
||||||
tinyxml2::XMLElement* xml_normal = doc.FirstChildElement("COLLADA")->FirstChildElement("library_geometries")->FirstChildElement("geometry")->FirstChildElement("mesh")->FirstChildElement("source")->NextSiblingElement()->FirstChildElement("float_array");
|
tinyxml2::XMLElement* xml_normal = doc.FirstChildElement("COLLADA")->FirstChildElement("library_geometries")->FirstChildElement("geometry")->FirstChildElement("mesh")->FirstChildElement("source")->NextSiblingElement()->FirstChildElement("float_array");
|
||||||
xml_normal->QueryIntAttribute("count", &normal_count);
|
xml_normal->QueryIntAttribute("count", &normal_count);
|
||||||
std::stringstream str_normal(xml_normal->GetText());
|
std::stringstream str_normal(xml_normal->GetText());
|
||||||
@@ -68,9 +71,9 @@ ColladaModel::ColladaModel(const char* filename) : faces_(), vertices_(), normal
|
|||||||
normals_.push_back(temp);
|
normals_.push_back(temp);
|
||||||
}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////textcoord/////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
int texcoord_count = 0;
|
||||||
texcoord_count = 0;
|
|
||||||
tinyxml2::XMLElement* xml_texture = doc.FirstChildElement("COLLADA")->FirstChildElement("library_geometries")->FirstChildElement("geometry")->FirstChildElement("mesh")->FirstChildElement("source")->NextSiblingElement()->NextSiblingElement()->FirstChildElement("float_array");
|
tinyxml2::XMLElement* xml_texture = doc.FirstChildElement("COLLADA")->FirstChildElement("library_geometries")->FirstChildElement("geometry")->FirstChildElement("mesh")->FirstChildElement("source")->NextSiblingElement()->NextSiblingElement()->FirstChildElement("float_array");
|
||||||
xml_texture->QueryIntAttribute("count", &texcoord_count);
|
xml_texture->QueryIntAttribute("count", &texcoord_count);
|
||||||
std::stringstream str_texcoord(xml_texture->GetText());
|
std::stringstream str_texcoord(xml_texture->GetText());
|
||||||
@@ -80,20 +83,105 @@ ColladaModel::ColladaModel(const char* filename) : faces_(), vertices_(), normal
|
|||||||
Vec2f temp;
|
Vec2f temp;
|
||||||
str_texcoord >> temp.x;
|
str_texcoord >> temp.x;
|
||||||
str_texcoord >> temp.y;
|
str_texcoord >> temp.y;
|
||||||
textureco_.push_back(temp);
|
texturecos_.push_back(temp);
|
||||||
|
}
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
int vertexweights_count = 0;
|
||||||
|
tinyxml2::XMLElement* xml_vertexweights = doc.FirstChildElement("COLLADA")->FirstChildElement("library_controllers")->FirstChildElement()->FirstChildElement()->FirstChildElement("vertex_weights");
|
||||||
|
xml_vertexweights->QueryIntAttribute("count", &vertexweights_count);
|
||||||
|
std::stringstream str_vertexweights(xml_vertexweights->FirstChildElement("vcount")->GetText());
|
||||||
|
std::stringstream str_vertexweights1(xml_vertexweights->FirstChildElement("v")->GetText());
|
||||||
|
|
||||||
|
for (int i = 0; i < vertexweights_count; i++)
|
||||||
|
{
|
||||||
|
int temp;
|
||||||
|
Vec2i temp1;
|
||||||
|
vertexweights_.push_back(std::vector<Vec2i>());
|
||||||
|
str_vertexweights >> temp;
|
||||||
|
|
||||||
|
for (int j = 0; j < temp; j++)
|
||||||
|
{
|
||||||
|
str_vertexweights1 >> temp1.x;
|
||||||
|
str_vertexweights1 >> temp1.y;
|
||||||
|
vertexweights_[i].push_back(temp1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
int weight_count = 0;
|
||||||
|
tinyxml2::XMLElement* xml_weight = doc.FirstChildElement("COLLADA")->FirstChildElement("library_controllers")->FirstChildElement()->FirstChildElement()->FirstChildElement("source")->NextSiblingElement()->NextSiblingElement()->FirstChildElement();
|
||||||
|
xml_weight->QueryIntAttribute("count", &weight_count);
|
||||||
|
std::stringstream str_weight(xml_weight->GetText());
|
||||||
|
|
||||||
|
for (int i = 0; i < weight_count; i++)
|
||||||
|
{
|
||||||
|
float temp;
|
||||||
|
str_weight >> temp;
|
||||||
|
weights_.push_back(temp);
|
||||||
|
}
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*joint_count = 0;
|
||||||
|
tinyxml2::XMLElement* xml_joint = doc.FirstChildElement("COLLADA")->FirstChildElement("library_controllers")->FirstChildElement()->FirstChildElement()->FirstChildElement("source")->FirstChildElement();
|
||||||
|
xml_joint->QueryIntAttribute("count", &joint_count);
|
||||||
|
std::stringstream str_joint(xml_joint->GetText());
|
||||||
|
*/
|
||||||
|
/*for (int i = 0; i < joint_count; i++)
|
||||||
|
{
|
||||||
|
Vec2f temp;
|
||||||
|
str_texcoord >> temp.x;
|
||||||
|
str_texcoord >> temp.y;
|
||||||
|
texturecos_.push_back(temp);
|
||||||
|
}*/
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//tinyxml2::XMLElement* xml_hierachy = doc.FirstChildElement("COLLADA")->FirstChildElement("library_visual_scenes")->FirstChildElement("visual_scene")->FirstChildElement("node")->FirstChildElement("node");
|
||||||
|
//std::stringstream str_hierachy(xml_hierachy->GetText());
|
||||||
|
|
||||||
|
//ColladaModel::rootjoint = buildjoint(xml_hierachy);
|
||||||
|
joint_count = 0;
|
||||||
|
tinyxml2::XMLElement* xml_joint = doc.FirstChildElement("COLLADA")->FirstChildElement("library_controllers")->FirstChildElement("controller")->FirstChildElement("skin")->FirstChildElement("source")->FirstChildElement("Name_array");
|
||||||
|
xml_joint->QueryIntAttribute("count", &joint_count);
|
||||||
|
std::stringstream str_joint(xml_joint->GetText());
|
||||||
|
|
||||||
|
for (int i = 0; i < vertex_count / 3; i++)
|
||||||
|
{
|
||||||
|
std::string temp;
|
||||||
|
str_vertex >> temp;
|
||||||
|
|
||||||
|
jointIDs_.push_back(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
load_texture(filename, "_diffuse.tga", diffusemap_);
|
|
||||||
load_texture(filename, "_nm_tangent.tga", normalmap_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Joint buildjoint(tinyxml2::XMLElement* xml_hierachy)
|
||||||
|
//{
|
||||||
|
// const char* name;
|
||||||
|
// xml_hierachy->QueryStringAttribute("name", &name);
|
||||||
|
// std::stringstream str_transform(xml_hierachy->FirstChildElement("matrix")->GetText());
|
||||||
|
// Matrix transform;
|
||||||
|
//
|
||||||
|
// if (xml_hierachy->FirstChildElement("node") != NULL)
|
||||||
|
// {
|
||||||
|
// xml_hierachy = xml_hierachy->FirstChildElement("node");
|
||||||
|
// do
|
||||||
|
// {
|
||||||
|
//// buildjoint
|
||||||
|
// } while (xml_hierachy->NextSiblingElement() != NULL);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
ColladaModel::~ColladaModel() {
|
ColladaModel::~ColladaModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaModel::ApplyTransform() {
|
void ColladaModel::ApplyTransform() {
|
||||||
Transform = Translation * Scale * Rotation;
|
Transform = Translation * Scale * Rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaModel::translate(Vec3f tr) {
|
void ColladaModel::translate(Vec3f tr) {
|
||||||
Translation[0][3] += tr.x;
|
Translation[0][3] += tr.x;
|
||||||
Translation[1][3] += tr.y;
|
Translation[1][3] += tr.y;
|
||||||
@@ -130,11 +218,9 @@ std::vector<int> ColladaModel::face(int idx) {
|
|||||||
for (int i = 0; i < (int)faces_[idx].size(); i++) face.push_back(faces_[idx][i][0]);
|
for (int i = 0; i < (int)faces_[idx].size(); i++) face.push_back(faces_[idx][i][0]);
|
||||||
return face;
|
return face;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3f ColladaModel::vertix(int i) {
|
Vec3f ColladaModel::vertix(int i) {
|
||||||
return vertices_[i];
|
return vertices_[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3f ColladaModel::vertix(int iface, int nthvert) {
|
Vec3f ColladaModel::vertix(int iface, int nthvert) {
|
||||||
return vertices_[faces_[iface][nthvert][0]];
|
return vertices_[faces_[iface][nthvert][0]];
|
||||||
}
|
}
|
||||||
@@ -164,7 +250,7 @@ Vec3f ColladaModel::normal(Vec2f uvf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vec2f ColladaModel::uv(int iface, int nthvert) {
|
Vec2f ColladaModel::uv(int iface, int nthvert) {
|
||||||
return textureco_[faces_[iface][nthvert][2]];
|
return texturecos_[faces_[iface][nthvert][2]];
|
||||||
}
|
}
|
||||||
|
|
||||||
float ColladaModel::specular(Vec2f uvf) {
|
float ColladaModel::specular(Vec2f uvf) {
|
||||||
@@ -176,3 +262,36 @@ Vec3f ColladaModel::normal(int iface, int nthvert) {
|
|||||||
int idx = faces_[iface][nthvert][1];
|
int idx = faces_[iface][nthvert][1];
|
||||||
return normals_[idx].normalize();
|
return normals_[idx].normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Joint ColladaModel::getrootjoint()
|
||||||
|
{
|
||||||
|
return rootjoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColladaModel::doanimation(Animation animation)
|
||||||
|
{
|
||||||
|
//animator.doanimation(animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColladaModel::updateanimator()
|
||||||
|
{
|
||||||
|
//animator.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Matrix> ColladaModel::getjointtransforms()
|
||||||
|
{
|
||||||
|
std::vector<Matrix> jointMat(joint_count);
|
||||||
|
addjointtoarray(rootjoint, jointMat);
|
||||||
|
return jointMat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColladaModel::addjointtoarray(Joint parent, std::vector<Matrix> jointMat)
|
||||||
|
{
|
||||||
|
jointMat[parent.index] = parent.getTransform();
|
||||||
|
|
||||||
|
for (auto& child : parent.children)
|
||||||
|
{
|
||||||
|
addjointtoarray(child, jointMat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
#include "tinyxml2.h"
|
#include "tinyxml2.h"
|
||||||
#include "geometry.h"
|
#include "geometry.h"
|
||||||
#include "tgaimage.h"
|
#include "tgaimage.h"
|
||||||
|
#include "joint.h"
|
||||||
|
#include "animator.h"
|
||||||
|
#include "animation.h"
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@@ -21,13 +24,41 @@ class ColladaModel {
|
|||||||
private:
|
private:
|
||||||
int face_count;
|
int face_count;
|
||||||
int vertex_count;
|
int vertex_count;
|
||||||
int normal_count;
|
int joint_count;
|
||||||
int texcoord_count;
|
|
||||||
|
Joint rootjoint;
|
||||||
|
int rootindex=0;
|
||||||
|
char* rootname;
|
||||||
|
Matrix root_transform;
|
||||||
|
|
||||||
|
//Animator animator;
|
||||||
|
|
||||||
std::vector<std::vector<Vec3i> > faces_; //vertex/normal/uv
|
std::vector<std::vector<Vec3i> > faces_; //vertex/normal/uv
|
||||||
std::vector<Vec3f> vertices_;
|
std::vector<Vec3f> vertices_;
|
||||||
std::vector<Vec3f> normals_;
|
std::vector<Vec3f> normals_;
|
||||||
std::vector<Vec2f> textureco_;
|
std::vector<Vec2f> texturecos_;
|
||||||
|
|
||||||
|
// #include <map>
|
||||||
|
// map<const char*, int> joint_names;
|
||||||
|
// joints.add(pair<const char*, int>("TORSO", 0));
|
||||||
|
|
||||||
|
// {TORSO, 0}
|
||||||
|
// {LEG, 1}
|
||||||
|
// {HAND, 2}
|
||||||
|
|
||||||
|
//joint_names.get("TORSO");
|
||||||
|
|
||||||
|
// 1. Get jointnames and map them to ids
|
||||||
|
// 2. get each joint and fill in the Joint class
|
||||||
|
// 3. get inversebindtransforms
|
||||||
|
|
||||||
|
// Vector -> Vectors -> (joint , weight)
|
||||||
|
std::vector<std::vector<Vec2i>> vertexweights_; //joint/weight
|
||||||
|
std::vector<std::string> jointIDs_;
|
||||||
|
// { TORSO , LEG, TEZ}
|
||||||
|
// { 0, 1, 2}
|
||||||
|
// jointIDs[0]
|
||||||
|
std::vector<float> weights_;
|
||||||
|
|
||||||
TGAImage diffusemap_;
|
TGAImage diffusemap_;
|
||||||
TGAImage normalmap_;
|
TGAImage normalmap_;
|
||||||
@@ -35,6 +66,7 @@ private:
|
|||||||
|
|
||||||
void load_texture(std::string filename, const char* suffix, TGAImage& img);
|
void load_texture(std::string filename, const char* suffix, TGAImage& img);
|
||||||
public:
|
public:
|
||||||
|
ColladaModel() = default;
|
||||||
ColladaModel(const char* filename);
|
ColladaModel(const char* filename);
|
||||||
~ColladaModel();
|
~ColladaModel();
|
||||||
|
|
||||||
@@ -50,6 +82,7 @@ public:
|
|||||||
Vec2f uv(int iface, int nthvert);
|
Vec2f uv(int iface, int nthvert);
|
||||||
|
|
||||||
Matrix Transform;
|
Matrix Transform;
|
||||||
|
|
||||||
Matrix Rotation;
|
Matrix Rotation;
|
||||||
Matrix Scale;
|
Matrix Scale;
|
||||||
Matrix Translation;
|
Matrix Translation;
|
||||||
@@ -62,5 +95,16 @@ public:
|
|||||||
TGAColor diffuse(Vec2f uv);
|
TGAColor diffuse(Vec2f uv);
|
||||||
float specular(Vec2f uv);
|
float specular(Vec2f uv);
|
||||||
std::vector<int> face(int idx);
|
std::vector<int> face(int idx);
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
Joint getrootjoint();
|
||||||
|
|
||||||
|
void doanimation(Animation animation);
|
||||||
|
|
||||||
|
void updateanimator();
|
||||||
|
|
||||||
|
std::vector<Matrix> getjointtransforms();
|
||||||
|
|
||||||
|
void addjointtoarray(Joint parent, std::vector<Matrix>);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#include "GeometryLibrary.h"
|
|
||||||
|
|
||||||
GeometryLibrary::GeometryLibrary(tinyxml2::XMLElement* xml)
|
|
||||||
{
|
|
||||||
auto xm = xml;
|
|
||||||
auto g = Geometry(xml->FirstChildElement("geometry"));
|
|
||||||
m_Geometries.push_back(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <vector>
|
|
||||||
#include "geometry.h"
|
|
||||||
|
|
||||||
class GeometryLibrary
|
|
||||||
{
|
|
||||||
std::vector<Geometry> m_Geometries;
|
|
||||||
|
|
||||||
public:
|
|
||||||
GeometryLibrary() = default;
|
|
||||||
GeometryLibrary(tinyxml2::XMLElement * xml);
|
|
||||||
};
|
|
||||||
|
|
||||||
class VisualSceneLibrary
|
|
||||||
{
|
|
||||||
Visualscene m_visual_scene;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VisualSceneLibrary() = default;
|
|
||||||
VisualSceneLibrary(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#include "Joint.h"
|
||||||
|
|
||||||
|
Joint::Joint(int index, Matrix transform, char* name) {
|
||||||
|
Joint::index = index;
|
||||||
|
_transform = transform;
|
||||||
|
Joint::name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
Joint::~Joint() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Joint::addChild(Joint child) {
|
||||||
|
children.push_back(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix Joint::getTransform() {
|
||||||
|
return _transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Joint::setTransform(Matrix transform) {
|
||||||
|
_transform = transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix Joint::getInverseBindTransform() {
|
||||||
|
return _inverseBindtransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Joint::calculateInverseBindTransform(Matrix parentBindTransform) {
|
||||||
|
Matrix bindTransform = parentBindTransform * _localBindTransform;
|
||||||
|
_inverseBindtransform = bindTransform.invert();
|
||||||
|
|
||||||
|
for (auto &child : children)
|
||||||
|
{
|
||||||
|
child.calculateInverseBindTransform(bindTransform);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
#include "geometry.h"
|
||||||
|
class Joint
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Matrix _transform; //model space
|
||||||
|
Matrix _localBindTransform;
|
||||||
|
Matrix _inverseBindtransform;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int index;
|
||||||
|
char* name;
|
||||||
|
std::vector<Joint> children;
|
||||||
|
|
||||||
|
Joint() = default;
|
||||||
|
Joint(int index,Matrix transform,char* name);
|
||||||
|
~Joint();
|
||||||
|
|
||||||
|
void addChild(Joint child);
|
||||||
|
|
||||||
|
Matrix getTransform();
|
||||||
|
void setTransform(Matrix transform);
|
||||||
|
|
||||||
|
Matrix getInverseBindTransform();
|
||||||
|
void calculateInverseBindTransform(Matrix parentBindTransform);
|
||||||
|
};
|
||||||
|
|
||||||
@@ -115,28 +115,38 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="COLLADA.cpp" />
|
<ClCompile Include="animation.cpp" />
|
||||||
<ClCompile Include="ColladaModel.cpp" />
|
<ClCompile Include="animator.cpp" />
|
||||||
<ClCompile Include="data.cpp" />
|
<ClCompile Include="camera.cpp" />
|
||||||
|
<ClCompile Include="colladamodel.cpp" />
|
||||||
<ClCompile Include="geometry.cpp" />
|
<ClCompile Include="geometry.cpp" />
|
||||||
<ClCompile Include="GeometryLibrary.cpp" />
|
<ClCompile Include="joint.cpp" />
|
||||||
|
<ClCompile Include="jointtransform.cpp" />
|
||||||
|
<ClCompile Include="keyframe.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="model.cpp" />
|
<ClCompile Include="model.cpp" />
|
||||||
|
<ClCompile Include="quaternion.cpp" />
|
||||||
<ClCompile Include="renderer.cpp" />
|
<ClCompile Include="renderer.cpp" />
|
||||||
<ClCompile Include="tgaimage.cpp" />
|
<ClCompile Include="tgaimage.cpp" />
|
||||||
<ClCompile Include="tinyxml2.cpp" />
|
<ClCompile Include="tinyxml2.cpp" />
|
||||||
|
<ClCompile Include="util_renderer.cpp" />
|
||||||
<ClCompile Include="util_window.cpp" />
|
<ClCompile Include="util_window.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="COLLADA.h" />
|
<ClInclude Include="animation.h" />
|
||||||
<ClInclude Include="ColladaModel.h" />
|
<ClInclude Include="animator.h" />
|
||||||
<ClInclude Include="data.h" />
|
<ClInclude Include="colladamodel.h" />
|
||||||
<ClInclude Include="geometry.h" />
|
<ClInclude Include="geometry.h" />
|
||||||
<ClInclude Include="GeometryLibrary.h" />
|
<ClInclude Include="camera.h" />
|
||||||
|
<ClInclude Include="joint.h" />
|
||||||
|
<ClInclude Include="jointtransform.h" />
|
||||||
|
<ClInclude Include="keyframe.h" />
|
||||||
<ClInclude Include="model.h" />
|
<ClInclude Include="model.h" />
|
||||||
|
<ClInclude Include="quaternion.h" />
|
||||||
<ClInclude Include="renderer.h" />
|
<ClInclude Include="renderer.h" />
|
||||||
<ClInclude Include="tgaimage.h" />
|
<ClInclude Include="tgaimage.h" />
|
||||||
<ClInclude Include="tinyxml2.h" />
|
<ClInclude Include="tinyxml2.h" />
|
||||||
|
<ClInclude Include="util_renderer.h" />
|
||||||
<ClInclude Include="util_window.h" />
|
<ClInclude Include="util_window.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|||||||
@@ -33,19 +33,34 @@
|
|||||||
<ClCompile Include="renderer.cpp">
|
<ClCompile Include="renderer.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="ColladaModel.cpp">
|
<ClCompile Include="camera.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="util_renderer.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="colladamodel.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="tinyxml2.cpp">
|
<ClCompile Include="tinyxml2.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="COLLADA.cpp">
|
<ClCompile Include="joint.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="GeometryLibrary.cpp">
|
<ClCompile Include="animator.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="data.cpp">
|
<ClCompile Include="animation.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="keyframe.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="jointtransform.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="quaternion.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -65,19 +80,34 @@
|
|||||||
<ClInclude Include="renderer.h">
|
<ClInclude Include="renderer.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="ColladaModel.h">
|
<ClInclude Include="camera.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="util_renderer.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="colladamodel.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="tinyxml2.h">
|
<ClInclude Include="tinyxml2.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="COLLADA.h">
|
<ClInclude Include="joint.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="GeometryLibrary.h">
|
<ClInclude Include="animator.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="data.h">
|
<ClInclude Include="animation.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="keyframe.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="jointtransform.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="quaternion.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -0,0 +1,17 @@
|
|||||||
|
#include "animation.h"
|
||||||
|
|
||||||
|
Animation::Animation(float seconds, std::vector<Keyframe> keyframes)
|
||||||
|
{
|
||||||
|
length = seconds;
|
||||||
|
keyframes_ = keyframes;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Animation::getlength()
|
||||||
|
{
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Keyframe> Animation::getkeyframe()
|
||||||
|
{
|
||||||
|
return keyframes_;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "keyframe.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Animation {
|
||||||
|
private:
|
||||||
|
float length;
|
||||||
|
std::vector<Keyframe> keyframes_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Animation() = default;
|
||||||
|
Animation(float seconds, std::vector<Keyframe> keyframes);
|
||||||
|
float getlength();
|
||||||
|
std::vector<Keyframe>getkeyframe();
|
||||||
|
};
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
#include "animator.h"
|
||||||
|
#include "colladamodel.h"
|
||||||
|
|
||||||
|
void Animator::increaseAnimationTime()
|
||||||
|
{
|
||||||
|
animation_time_ += (1/60.f);
|
||||||
|
if (animation_time_ > current_animation_.getlength())
|
||||||
|
{
|
||||||
|
animation_time_ = (int)(animation_time_) % (int)(current_animation_.getlength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Animator::applyPoseToJoints(std::map<std::string, Matrix> currentPose, Joint joint, Matrix parentTransform)
|
||||||
|
{
|
||||||
|
Matrix currentLocalTransform = currentPose.at(joint.name);
|
||||||
|
Matrix currentTransform = parentTransform * currentLocalTransform;
|
||||||
|
for (Joint childJoint : joint.children) {
|
||||||
|
applyPoseToJoints(currentPose, childJoint, currentTransform);
|
||||||
|
}
|
||||||
|
currentTransform = currentTransform * joint.getInverseBindTransform();
|
||||||
|
joint.setTransform(currentTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Keyframe> Animator::getPreviousAndNextFrames()
|
||||||
|
{
|
||||||
|
std::vector<Keyframe> allFrames = current_animation_.getkeyframe();
|
||||||
|
Keyframe previousFrame = allFrames[0];
|
||||||
|
Keyframe nextFrame = allFrames[0];
|
||||||
|
for (int i = 1; i < allFrames.capacity(); i++) {
|
||||||
|
nextFrame = allFrames[i];
|
||||||
|
if (nextFrame.gettimestamp() > animation_time_) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
previousFrame = allFrames[i];
|
||||||
|
}
|
||||||
|
return std::vector<Keyframe>{ previousFrame, nextFrame };
|
||||||
|
}
|
||||||
|
|
||||||
|
float Animator::calculateProgression(Keyframe previousFrame, Keyframe nextFrame)
|
||||||
|
{
|
||||||
|
float totalTime = nextFrame.gettimestamp() - previousFrame.gettimestamp();
|
||||||
|
float currentTime = animation_time_ - previousFrame.gettimestamp();
|
||||||
|
return currentTime / totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, Matrix> Animator::interpolatePoses(Keyframe previousFrame, Keyframe nextFrame, float progression)
|
||||||
|
{
|
||||||
|
std::map<std::string, Matrix> currentPose ;
|
||||||
|
std::set<std::string> key_set;
|
||||||
|
make_key_set(previousFrame.getJointKeyFrames(), key_set);
|
||||||
|
for (std::string jointName : key_set)
|
||||||
|
{
|
||||||
|
JointTransform previousTransform = previousFrame.getJointKeyFrames().at(jointName);
|
||||||
|
JointTransform nextTransform = nextFrame.getJointKeyFrames().at(jointName);
|
||||||
|
JointTransform currentTransform = JointTransform::interpolate(previousTransform, nextTransform, progression);
|
||||||
|
currentPose.insert_or_assign(jointName, currentTransform.getlocationtransform());
|
||||||
|
make_key_set(previousFrame.getJointKeyFrames(), key_set);
|
||||||
|
}
|
||||||
|
return currentPose;
|
||||||
|
}
|
||||||
|
|
||||||
|
Animator::Animator(ColladaModel entity)
|
||||||
|
{
|
||||||
|
entity_ = &entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animator::doanimation(Animation animation)
|
||||||
|
{
|
||||||
|
animation_time_ = 0;
|
||||||
|
current_animation_ = animation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animator::update()
|
||||||
|
{
|
||||||
|
if (¤t_animation_ == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
increaseAnimationTime();
|
||||||
|
std::map<std::string, Matrix> currentPose = calculateCurrentAnimationPose();
|
||||||
|
applyPoseToJoints(currentPose, entity_->getrootjoint(), Matrix());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, Matrix> Animator::calculateCurrentAnimationPose()
|
||||||
|
{
|
||||||
|
std::vector<Keyframe> frames = getPreviousAndNextFrames();
|
||||||
|
float progression = calculateProgression(frames[0], frames[1]);
|
||||||
|
return interpolatePoses(frames[0], frames[1], progression);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TK, typename TV>
|
||||||
|
std::vector<TK> extract_keys(std::map<TK, TV> const& input_map) {
|
||||||
|
std::vector<TK> retval;
|
||||||
|
for (auto const& element : input_map) {
|
||||||
|
retval.push_back(element.first);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TK, typename TV>
|
||||||
|
std::vector<TV> extract_values(std::map<TK, TV> const& input_map) {
|
||||||
|
std::vector<TV> retval;
|
||||||
|
for (auto const& element : input_map) {
|
||||||
|
retval.push_back(element.second);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "animation.h"
|
||||||
|
#include "geometry.h"
|
||||||
|
#include "keyframe.h"
|
||||||
|
#include "jointtransform.h"
|
||||||
|
#include "joint.h"
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
class ColladaModel;
|
||||||
|
|
||||||
|
class Animator {
|
||||||
|
private:
|
||||||
|
ColladaModel* entity_;
|
||||||
|
Animation current_animation_;
|
||||||
|
float animation_time_;
|
||||||
|
|
||||||
|
void increaseAnimationTime();
|
||||||
|
std::map<std::string,Matrix> calculateCurrentAnimationPose();
|
||||||
|
void applyPoseToJoints(std::map<std::string, Matrix> currentPose, Joint joint, Matrix parentTransform);
|
||||||
|
std::vector<Keyframe> getPreviousAndNextFrames();
|
||||||
|
float calculateProgression(Keyframe previousFrame, Keyframe nextFrame);
|
||||||
|
std::map<std::string, Matrix> interpolatePoses(Keyframe previousFrame, Keyframe nextFrame, float progression);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Animator(ColladaModel entity);
|
||||||
|
void doanimation(Animation animation);
|
||||||
|
void update();
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Key,
|
||||||
|
class T,
|
||||||
|
class Comparator,
|
||||||
|
class MapAllocator,
|
||||||
|
class SetAllocator>
|
||||||
|
void make_key_set(const std::map<Key, T, Comparator, MapAllocator>& map,
|
||||||
|
std::set<Key, Comparator, SetAllocator>& set)
|
||||||
|
{
|
||||||
|
set.clear();
|
||||||
|
typedef typename std::map<Key, T, Comparator, MapAllocator> map_type;
|
||||||
|
typename map_type::const_iterator itr = map.begin();
|
||||||
|
while (map.end() != itr)
|
||||||
|
{
|
||||||
|
set.insert((itr++)->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
Camera::Camera()
|
||||||
|
{
|
||||||
|
fov = 30;
|
||||||
|
position = Vec3f(0, 0, 0);
|
||||||
|
rotation = Vec3f(0, 0, 0);
|
||||||
|
up = Vec3f(0, 0, 0);
|
||||||
|
right = Vec3f(0, 0, 0);
|
||||||
|
forward = Vec3f(0, 0, 0);
|
||||||
|
|
||||||
|
near_plane = 0;
|
||||||
|
far_plane = 15;
|
||||||
|
horizontal_camera_speed = 0.5;
|
||||||
|
vertical_camera_speed = 0.5;
|
||||||
|
vertical_camera_clamp_up = 90;
|
||||||
|
vertical_camera_clamp_down = -90;
|
||||||
|
movement_speed = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f Camera::GetForward() {
|
||||||
|
return forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::Move(Vec3f move_vec) {
|
||||||
|
position = position + move_vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::SetPosition(Vec3f pos) {
|
||||||
|
position = pos;
|
||||||
|
}
|
||||||
|
void Camera::Rotate(Vec3f rot_vec) {
|
||||||
|
rotation = rotation + rot_vec;
|
||||||
|
}
|
||||||
|
void Camera::SetRotation(Vec3f rot) {
|
||||||
|
rotation = rot;
|
||||||
|
}
|
||||||
|
void Camera::SetFOV(int angle) {
|
||||||
|
fov = angle;
|
||||||
|
}
|
||||||
|
void Camera::SetVerticalRotSpeed(float speed) {
|
||||||
|
vertical_camera_speed = speed;
|
||||||
|
}
|
||||||
|
void Camera::SetHorizontalRotSpeed(float speed) {
|
||||||
|
horizontal_camera_speed = speed;
|
||||||
|
}
|
||||||
|
void Camera::SetClampRotUp(float angle) {
|
||||||
|
vertical_camera_clamp_up = angle;
|
||||||
|
}
|
||||||
|
void Camera::SetClampRotDown(float angle) {
|
||||||
|
vertical_camera_clamp_down = angle;
|
||||||
|
}
|
||||||
|
void Camera::SetNearPlane(float near_val) {
|
||||||
|
near_plane = near_val;
|
||||||
|
}
|
||||||
|
void Camera::SetFarPlane(float far_val) {
|
||||||
|
far_plane = far_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::rotate_hor(float d_angle) {
|
||||||
|
rotation.y += d_angle * horizontal_camera_speed;
|
||||||
|
}
|
||||||
|
void Camera::rotate_ver(float d_angle) {
|
||||||
|
rotation.x += d_angle * vertical_camera_speed;
|
||||||
|
rotation.x = std::fmin(rotation.x, vertical_camera_clamp_up);
|
||||||
|
rotation.x = std::fmax(rotation.x, vertical_camera_clamp_down);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Camera::move_camera_left() {
|
||||||
|
position = position - right * movement_speed;
|
||||||
|
}
|
||||||
|
void Camera::move_camera_right() {
|
||||||
|
position = position + right * movement_speed;
|
||||||
|
}
|
||||||
|
void Camera::move_camera_forward() {
|
||||||
|
position = position + forward * movement_speed;
|
||||||
|
}
|
||||||
|
void Camera::move_camera_backward() {
|
||||||
|
position = position - forward * movement_speed;
|
||||||
|
}
|
||||||
|
void Camera::rise() {
|
||||||
|
position = position + Vec3f(0, movement_speed, 0);
|
||||||
|
}
|
||||||
|
void Camera::fall() {
|
||||||
|
position = position - Vec3f(0, movement_speed, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::SetMovementSpeed(float speed) {
|
||||||
|
movement_speed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::ApplyChanges() {
|
||||||
|
forward = Vec3f(sin(rotation.y * DEG2RAD), -sin(rotation.x * DEG2RAD), -cosf(rotation.y*DEG2RAD) * cosf(rotation.x*DEG2RAD)).normalize();
|
||||||
|
right = Vec3f(cos(rotation.y*DEG2RAD), 0, sin(rotation.y * DEG2RAD)).normalize();
|
||||||
|
up = cross(right, forward).normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix Camera::GetModelViewMatrix() {
|
||||||
|
Vec3f center = position + forward;
|
||||||
|
Vec3f z = forward * -1;
|
||||||
|
Matrix Minv = Matrix::identity();
|
||||||
|
Matrix Tr = Matrix::identity();
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
Minv[0][i] = right[i];
|
||||||
|
Minv[1][i] = up[i];
|
||||||
|
Minv[2][i] = z[i];
|
||||||
|
Tr[i][3] = -center[i];
|
||||||
|
}
|
||||||
|
return Minv * Tr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix Camera::GetProjectionMatrix() {
|
||||||
|
Matrix Projection = Matrix::identity();
|
||||||
|
Projection[0][0] = 1 / tan(fov * DEG2RAD);
|
||||||
|
Projection[1][1] = 1 / tan(fov * DEG2RAD);
|
||||||
|
Projection[2][2] = (far_plane + near_plane) / (far_plane - near_plane);
|
||||||
|
Projection[2][3] = (-2 * far_plane * near_plane) / (far_plane - near_plane);
|
||||||
|
Projection[3][2] = -1;
|
||||||
|
return Projection;
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef __CAMERA_HEADER__
|
||||||
|
#define __CAMERA_HEADER__
|
||||||
|
#include "geometry.h"
|
||||||
|
|
||||||
|
class Camera {
|
||||||
|
private:
|
||||||
|
Vec3f position;
|
||||||
|
Vec3f rotation;
|
||||||
|
Vec3f up;
|
||||||
|
Vec3f right;
|
||||||
|
Vec3f forward;
|
||||||
|
float fov;
|
||||||
|
float near_plane;
|
||||||
|
float far_plane;
|
||||||
|
float horizontal_camera_speed;
|
||||||
|
float vertical_camera_speed;
|
||||||
|
float vertical_camera_clamp_up;
|
||||||
|
float vertical_camera_clamp_down;
|
||||||
|
float movement_speed;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Camera();
|
||||||
|
void SetPosition(Vec3f pos);
|
||||||
|
void SetRotation(Vec3f rot);
|
||||||
|
void Move(Vec3f move_vec);
|
||||||
|
void Rotate(Vec3f rot_vec);
|
||||||
|
void SetFOV(int angle);
|
||||||
|
void SetNearPlane(float near_val);
|
||||||
|
void SetFarPlane(float far_val);
|
||||||
|
void SetVerticalRotSpeed(float speed);
|
||||||
|
void SetHorizontalRotSpeed(float speed);
|
||||||
|
void SetClampRotUp(float angle);
|
||||||
|
void SetClampRotDown(float angle);
|
||||||
|
void SetMovementSpeed(float speed);
|
||||||
|
Vec3f GetForward();
|
||||||
|
|
||||||
|
void rotate_hor(float d_angle);
|
||||||
|
void rotate_ver(float d_angle);
|
||||||
|
void move_camera_left();
|
||||||
|
void move_camera_right();
|
||||||
|
void move_camera_forward();
|
||||||
|
void move_camera_backward();
|
||||||
|
void rise();
|
||||||
|
void fall();
|
||||||
|
|
||||||
|
void ApplyChanges();
|
||||||
|
Matrix GetModelViewMatrix();
|
||||||
|
Matrix GetProjectionMatrix();
|
||||||
|
};
|
||||||
|
#endif
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
#include "data.h"
|
|
||||||
|
|
||||||
Float_Array::Float_Array(tinyxml2::XMLElement* xml)
|
|
||||||
{
|
|
||||||
xml->QueryIntAttribute("count", (int*)&m_Count);
|
|
||||||
|
|
||||||
const char* ch;
|
|
||||||
xml->QueryStringAttribute("count", &ch);
|
|
||||||
std::string s(ch);
|
|
||||||
m_ID = s;
|
|
||||||
|
|
||||||
std::stringstream str(xml->GetText());
|
|
||||||
m_Floats = new float[m_Count];
|
|
||||||
|
|
||||||
for (int i = 0; i < m_Count; i++)
|
|
||||||
{
|
|
||||||
str >> m_Floats[i];
|
|
||||||
}
|
|
||||||
float f = m_Floats[55358];
|
|
||||||
}
|
|
||||||
|
|
||||||
Name_Array::Name_Array(tinyxml2::XMLElement* xml)
|
|
||||||
{
|
|
||||||
xml->QueryIntAttribute("count", (int*)&m_Count);
|
|
||||||
|
|
||||||
const char* ch;
|
|
||||||
xml->QueryStringAttribute("count", &ch);
|
|
||||||
std::string s(ch);
|
|
||||||
m_ID = s;
|
|
||||||
|
|
||||||
std::stringstream str(xml->GetText());
|
|
||||||
for (int i = 0; i < m_Count; i++)
|
|
||||||
{
|
|
||||||
str >> m_Names[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Param::Param(tinyxml2::XMLElement* xml)
|
|
||||||
{
|
|
||||||
const char* ch;
|
|
||||||
xml->QueryStringAttribute("name", &ch);
|
|
||||||
std::string s(ch);
|
|
||||||
m_Name = s;
|
|
||||||
|
|
||||||
const char* ch1;
|
|
||||||
xml->QueryStringAttribute("type", &ch1);
|
|
||||||
std::string s1(ch1);
|
|
||||||
m_Type = s1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Accessor::Accessor(tinyxml2::XMLElement* xml)
|
|
||||||
{
|
|
||||||
const char* ch;
|
|
||||||
xml->QueryStringAttribute("source", &ch);
|
|
||||||
std::string s(ch);
|
|
||||||
m_Source = s;
|
|
||||||
|
|
||||||
xml->QueryIntAttribute("count", (int*)&m_Count);
|
|
||||||
|
|
||||||
xml->QueryIntAttribute("stride", (int*)&m_Stride);
|
|
||||||
|
|
||||||
for (tinyxml2::XMLElement* child = xml->FirstChildElement("param"); child != NULL; child = child->NextSiblingElement("param"))
|
|
||||||
{
|
|
||||||
Param p(child);
|
|
||||||
m_Params.push_back(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Technique_Common::Technique_Common(tinyxml2::XMLElement* xml)
|
|
||||||
{
|
|
||||||
m_Accessor = Accessor(xml->FirstChildElement("accessor"));
|
|
||||||
}
|
|
||||||
|
|
||||||
Source::Source(tinyxml2::XMLElement* xml)
|
|
||||||
{
|
|
||||||
const char* ch;
|
|
||||||
xml->QueryStringAttribute("id", &ch);
|
|
||||||
std::string s(ch);
|
|
||||||
m_ID = s;
|
|
||||||
|
|
||||||
tinyxml2::XMLElement* fa = xml->FirstChildElement("float_array");
|
|
||||||
if (fa != NULL)
|
|
||||||
{
|
|
||||||
m_Float_Array = Float_Array(fa);
|
|
||||||
}
|
|
||||||
|
|
||||||
tinyxml2::XMLElement* na = xml->FirstChildElement("Name_array");
|
|
||||||
if (na != NULL)
|
|
||||||
{
|
|
||||||
m_Name_Array = Name_Array(na);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_TechniqueCommon = Technique_Common(xml->FirstChildElement("technique_common"));
|
|
||||||
}
|
|
||||||
|
|
||||||
Input::Input(tinyxml2::XMLElement* xml)
|
|
||||||
{
|
|
||||||
const char* ch;
|
|
||||||
xml->QueryStringAttribute("semantic", &ch);
|
|
||||||
std::string s(ch);
|
|
||||||
m_Semantic = s;
|
|
||||||
|
|
||||||
const char* ch1;
|
|
||||||
xml->QueryStringAttribute("source", &ch1);
|
|
||||||
std::string s1(ch1);
|
|
||||||
m_Source = s1;
|
|
||||||
|
|
||||||
if (xml->FindAttribute("offset"))
|
|
||||||
{
|
|
||||||
const char* ch2;
|
|
||||||
xml->QueryStringAttribute("offset", &ch2);
|
|
||||||
std::string s2(ch2);
|
|
||||||
m_Offset = s2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xml->FindAttribute("set"))
|
|
||||||
{
|
|
||||||
const char* ch3;
|
|
||||||
xml->QueryStringAttribute("set", &ch3);
|
|
||||||
std::string s3(ch3);
|
|
||||||
m_Set = s3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vertices::Vertices(tinyxml2::XMLElement* xml)
|
|
||||||
{
|
|
||||||
const char* ch;
|
|
||||||
xml->QueryStringAttribute("id", &ch);
|
|
||||||
std::string s(ch);
|
|
||||||
m_ID = s;
|
|
||||||
|
|
||||||
for (tinyxml2::XMLElement* child = xml->FirstChildElement("input"); child != NULL; child = child->NextSiblingElement("input"))
|
|
||||||
{
|
|
||||||
Input in(child);
|
|
||||||
m_Inputs.push_back(in);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
P::P(tinyxml2::XMLElement* xml, unsigned int count)
|
|
||||||
{
|
|
||||||
m_Count = count;
|
|
||||||
std::stringstream str(xml->GetText());
|
|
||||||
m_Indices = new unsigned short[count * 9];
|
|
||||||
for (int i = 0; i < count * 9; i++)
|
|
||||||
{
|
|
||||||
str >> m_Indices[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Triangles::Triangles(tinyxml2::XMLElement* xml)
|
|
||||||
{
|
|
||||||
xml->QueryIntAttribute("count", (int*)&m_Count);
|
|
||||||
|
|
||||||
const char* ch;
|
|
||||||
xml->QueryStringAttribute("count", &ch);
|
|
||||||
std::string s(ch);
|
|
||||||
m_Material = s;
|
|
||||||
|
|
||||||
for (tinyxml2::XMLElement* child = xml->FirstChildElement("input"); child != NULL; child = child->NextSiblingElement("input"))
|
|
||||||
{
|
|
||||||
Input in(child);
|
|
||||||
m_Inputs.push_back(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
tinyxml2::XMLElement* mp = xml->FirstChildElement("p");
|
|
||||||
if (mp != NULL)
|
|
||||||
{
|
|
||||||
m_P = P(mp, m_Count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Mesh::Mesh(tinyxml2::XMLElement* xml)
|
|
||||||
{
|
|
||||||
for (tinyxml2::XMLElement* child = xml->FirstChildElement("source"); child != NULL; child = child->NextSiblingElement("source"))
|
|
||||||
{
|
|
||||||
Source sc(child);
|
|
||||||
m_Sources.push_back(sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Vertices = Vertices(xml->FirstChildElement("vertices"));
|
|
||||||
|
|
||||||
for (tinyxml2::XMLElement* child = xml->FirstChildElement("triangles"); child != NULL; child = child->NextSiblingElement("triangles"))
|
|
||||||
{
|
|
||||||
Triangles tr(child);
|
|
||||||
m_Triangles.push_back(tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include "tinyxml2.h"
|
|
||||||
//----------------------------------------------//
|
|
||||||
class Float_Array
|
|
||||||
{
|
|
||||||
unsigned int m_Count;
|
|
||||||
std::string m_ID;
|
|
||||||
float* m_Floats;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Float_Array() = default;
|
|
||||||
Float_Array(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
class Name_Array
|
|
||||||
{
|
|
||||||
unsigned int m_Count;
|
|
||||||
std::string m_ID;
|
|
||||||
std::string* m_Names;
|
|
||||||
public:
|
|
||||||
Name_Array() = default;
|
|
||||||
Name_Array(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
class Param
|
|
||||||
{
|
|
||||||
std::string m_Name;
|
|
||||||
std::string m_Type;
|
|
||||||
public:
|
|
||||||
Param() = default;
|
|
||||||
Param(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
class Accessor
|
|
||||||
{
|
|
||||||
std::string m_Source;
|
|
||||||
unsigned int m_Count;
|
|
||||||
unsigned int m_Stride;
|
|
||||||
std::vector<Param> m_Params;
|
|
||||||
public:
|
|
||||||
Accessor () = default;
|
|
||||||
Accessor(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
class Technique_Common
|
|
||||||
{
|
|
||||||
Accessor m_Accessor;
|
|
||||||
public:
|
|
||||||
Technique_Common() = default;
|
|
||||||
Technique_Common(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
class Source
|
|
||||||
{
|
|
||||||
std::string m_ID;
|
|
||||||
Float_Array m_Float_Array;
|
|
||||||
Name_Array m_Name_Array;
|
|
||||||
Technique_Common m_TechniqueCommon;
|
|
||||||
public:
|
|
||||||
Source() = default;
|
|
||||||
Source(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
class Input
|
|
||||||
{
|
|
||||||
std::string m_Semantic;
|
|
||||||
std::string m_Source;
|
|
||||||
std::string m_Offset;
|
|
||||||
std::string m_Set;
|
|
||||||
public:
|
|
||||||
Input() = default;
|
|
||||||
Input(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
class Vertices
|
|
||||||
{
|
|
||||||
std::string m_ID;
|
|
||||||
std::vector<Input> m_Inputs;
|
|
||||||
public:
|
|
||||||
Vertices() = default;
|
|
||||||
Vertices(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
class P
|
|
||||||
{
|
|
||||||
unsigned int m_Count;
|
|
||||||
unsigned short* m_Indices;
|
|
||||||
public:
|
|
||||||
P() = default;
|
|
||||||
P(tinyxml2::XMLElement* xml, unsigned int count);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
class Triangles
|
|
||||||
{
|
|
||||||
unsigned int m_Count;
|
|
||||||
std::string m_Material;
|
|
||||||
std::vector<Input> m_Inputs;
|
|
||||||
P m_P;
|
|
||||||
public:
|
|
||||||
Triangles() = default;
|
|
||||||
Triangles(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
class Mesh
|
|
||||||
{
|
|
||||||
std::vector<Source> m_Sources;
|
|
||||||
Vertices m_Vertices;
|
|
||||||
std::vector<Triangles> m_Triangles;
|
|
||||||
public:
|
|
||||||
Mesh() = default;
|
|
||||||
Mesh(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
class Node
|
|
||||||
{
|
|
||||||
std::string m_ID;
|
|
||||||
std::string m_name;
|
|
||||||
std::string m_type;
|
|
||||||
std::string m_sid;
|
|
||||||
public:
|
|
||||||
Node() = default;
|
|
||||||
Node(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
class Matrix
|
|
||||||
{
|
|
||||||
std::string m_sid;
|
|
||||||
public:
|
|
||||||
Node() = default;
|
|
||||||
Node(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
//----------------------------------------------//
|
|
||||||
@@ -5,7 +5,3 @@ template <> template <> vec<3,float>::vec(const vec<3,int> &v) : x(v.x),y(v.y)
|
|||||||
template <> template <> vec<2,int> ::vec(const vec<2,float> &v) : x(int(v.x+.5f)),y(int(v.y+.5f)) {}
|
template <> template <> vec<2,int> ::vec(const vec<2,float> &v) : x(int(v.x+.5f)),y(int(v.y+.5f)) {}
|
||||||
template <> template <> vec<2,float>::vec(const vec<2,int> &v) : x(v.x),y(v.y) {}
|
template <> template <> vec<2,float>::vec(const vec<2,int> &v) : x(v.x),y(v.y) {}
|
||||||
|
|
||||||
Geometry::Geometry(tinyxml2::XMLElement* xml)
|
|
||||||
{
|
|
||||||
m_Mesh = Mesh(xml->FirstChildElement("mesh"));
|
|
||||||
}
|
|
||||||
|
|||||||
+3
-42
@@ -1,10 +1,12 @@
|
|||||||
#ifndef __GEOMETRY_H__
|
#ifndef __GEOMETRY_H__
|
||||||
#define __GEOMETRY_H__
|
#define __GEOMETRY_H__
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "data.h"
|
|
||||||
|
#define DEG2RAD M_PI/180
|
||||||
|
|
||||||
template<size_t DimCols,size_t DimRows,typename T> class mat;
|
template<size_t DimCols,size_t DimRows,typename T> class mat;
|
||||||
|
|
||||||
@@ -234,46 +236,5 @@ typedef vec<3, float> Vec3f;
|
|||||||
typedef vec<3, int> Vec3i;
|
typedef vec<3, int> Vec3i;
|
||||||
typedef vec<4, float> Vec4f;
|
typedef vec<4, float> Vec4f;
|
||||||
typedef mat<4,4,float> Matrix;
|
typedef mat<4,4,float> Matrix;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Geometry
|
|
||||||
{
|
|
||||||
Mesh m_Mesh;
|
|
||||||
public:
|
|
||||||
Geometry() = default;
|
|
||||||
Geometry(tinyxml2::XMLElement * xml);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Visualscene
|
|
||||||
{
|
|
||||||
node m_Mesh;
|
|
||||||
public:
|
|
||||||
Visualscene() = default;
|
|
||||||
Visualscene(tinyxml2::XMLElement* xml);
|
|
||||||
};
|
|
||||||
#endif //__GEOMETRY_H__
|
#endif //__GEOMETRY_H__
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#include "jointtransform.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
JointTransform::JointTransform(Vec3f position, Quaternion rotation)
|
||||||
|
{
|
||||||
|
position_ = position;
|
||||||
|
rotation_ = rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix JointTransform::getlocationtransform()
|
||||||
|
{
|
||||||
|
Matrix matrix;
|
||||||
|
Vec4f column = Vec4f(position_.x, position_.y, position_.z, 1);
|
||||||
|
matrix.set_col(3, column);
|
||||||
|
matrix = matrix * rotation_.toRotationMatrix();
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
JointTransform JointTransform::interpolate(JointTransform frame1, JointTransform frame2, float progression)
|
||||||
|
{
|
||||||
|
Vec3f pos = interpolate(frame1.position_, frame2.position_, progression);
|
||||||
|
Quaternion rot = Quaternion::interpolate(frame1.rotation_, frame2.rotation_, progression);
|
||||||
|
return JointTransform(pos, rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f JointTransform::interpolate(Vec3f start, Vec3f end, float progression)
|
||||||
|
{
|
||||||
|
float x = start.x + (end.x - start.x) * progression;
|
||||||
|
float y = start.y + (end.y - start.y) * progression;
|
||||||
|
float z = start.z + (end.z - start.z) * progression;
|
||||||
|
|
||||||
|
return Vec3f(x,y,z);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "quaternion.h"
|
||||||
|
#include "geometry.h"
|
||||||
|
|
||||||
|
class JointTransform
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Vec3f position_;
|
||||||
|
|
||||||
|
Quaternion rotation_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
JointTransform() = default;
|
||||||
|
JointTransform(Vec3f position,Quaternion rotation);
|
||||||
|
|
||||||
|
Matrix getlocationtransform();
|
||||||
|
|
||||||
|
static JointTransform interpolate(JointTransform frame1, JointTransform frame2, float progression);
|
||||||
|
|
||||||
|
static Vec3f interpolate(Vec3f start,Vec3f end, float progression);
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#include "keyframe.h"
|
||||||
|
|
||||||
|
Keyframe::Keyframe(float timestamp, std::map<std::string, JointTransform> pose)
|
||||||
|
{
|
||||||
|
timestamp_ = timestamp;
|
||||||
|
pose_ = pose;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Keyframe::gettimestamp()
|
||||||
|
{
|
||||||
|
return timestamp_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, JointTransform> Keyframe::getJointKeyFrames()
|
||||||
|
{
|
||||||
|
return pose_;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef HI
|
||||||
|
#define HI
|
||||||
|
|
||||||
|
// your declarations (and certain types of definitions) here
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include "jointtransform.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Keyframe{
|
||||||
|
private:
|
||||||
|
float timestamp_;
|
||||||
|
std::map<std::string, JointTransform> pose_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Keyframe() = default;
|
||||||
|
Keyframe(float timestamp,std::map<std::string, JointTransform> pose);
|
||||||
|
float gettimestamp();
|
||||||
|
std::map<std::string, JointTransform> getJointKeyFrames();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
+51
-11
@@ -3,26 +3,29 @@
|
|||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "ctime"
|
#include "ctime"
|
||||||
|
|
||||||
const int width = 800;
|
const int screen_width = 1000;
|
||||||
const int height = 800;
|
const int screen_height = 1000;
|
||||||
|
|
||||||
|
#define TARGET_FRAMERATE 30
|
||||||
|
|
||||||
|
int prev_mouse_x = screen_width/2;
|
||||||
|
int prev_mouse_y = screen_height/2;
|
||||||
|
|
||||||
|
float TIME = 0;
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||||
{
|
{
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
MSG Msg;
|
MSG Msg;
|
||||||
|
|
||||||
hwnd = create_window(width, height, hInstance);
|
hwnd = create_window(hInstance);
|
||||||
|
ShowCursor(false);
|
||||||
ShowWindow(hwnd, nCmdShow);
|
ShowWindow(hwnd, nCmdShow);
|
||||||
|
|
||||||
char debug_str[100];
|
init_camera();
|
||||||
|
|
||||||
clock_t first_time = clock();
|
|
||||||
render();
|
|
||||||
clock_t end_time = clock();
|
|
||||||
Update();
|
|
||||||
|
|
||||||
sprintf_s(debug_str, "%f\n", (double)(end_time - first_time) / CLOCKS_PER_SEC);
|
SetTimer(hwnd, NULL, 1000 / TARGET_FRAMERATE, (TIMERPROC)FixedUpdate);
|
||||||
OutputDebugString(debug_str);
|
|
||||||
|
|
||||||
while (GetMessage(&Msg, NULL, 0, 0))
|
while (GetMessage(&Msg, NULL, 0, 0))
|
||||||
{
|
{
|
||||||
@@ -32,14 +35,51 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||||||
return Msg.wParam;
|
return Msg.wParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleMouseMovement() {
|
||||||
|
POINT point;
|
||||||
|
GetCursorPos(&point);
|
||||||
|
|
||||||
|
camera.rotate_hor(point.x - prev_mouse_x);
|
||||||
|
camera.rotate_ver(point.y - prev_mouse_y);
|
||||||
|
|
||||||
|
SetCursorPos(prev_mouse_x, prev_mouse_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HandleButtonPressed() {
|
||||||
|
if (GetAsyncKeyState(VK_UP) & 0x8000)
|
||||||
|
camera.move_camera_forward();
|
||||||
|
if (GetAsyncKeyState(VK_DOWN) & 0x8000)
|
||||||
|
camera.move_camera_backward();
|
||||||
|
if (GetAsyncKeyState(VK_RIGHT) & 0x8000)
|
||||||
|
camera.move_camera_right();
|
||||||
|
if (GetAsyncKeyState(VK_LEFT) & 0x8000)
|
||||||
|
camera.move_camera_left();
|
||||||
|
if (GetAsyncKeyState(VK_SPACE) & 0x8000)
|
||||||
|
camera.rise();
|
||||||
|
if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
|
||||||
|
camera.fall();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CALLBACK FixedUpdate(HWND hwnd, UINT message, UINT uInt, DWORD dWord)
|
||||||
|
{
|
||||||
|
TIME += 0.167;
|
||||||
|
HandleButtonPressed();
|
||||||
|
camera.ApplyChanges();
|
||||||
|
render();
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
|
HandleMouseMovement();
|
||||||
|
break;
|
||||||
case WM_RBUTTONDOWN:
|
case WM_RBUTTONDOWN:
|
||||||
break;
|
break;
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
Update();
|
|
||||||
break;
|
break;
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
DestroyWindow(hwnd);
|
DestroyWindow(hwnd);
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ Model::Model(const char *filename) : verts_(), faces_(), norms_(), uv_(), diffus
|
|||||||
std::cerr << "# v# " << verts_.size() << " f# " << faces_.size() << " vt# " << uv_.size() << " vn# " << norms_.size() << std::endl;
|
std::cerr << "# v# " << verts_.size() << " f# " << faces_.size() << " vt# " << uv_.size() << " vn# " << norms_.size() << std::endl;
|
||||||
load_texture(filename, "_diffuse.tga", diffusemap_);
|
load_texture(filename, "_diffuse.tga", diffusemap_);
|
||||||
load_texture(filename, "_nm_tangent.tga", normalmap_);
|
load_texture(filename, "_nm_tangent.tga", normalmap_);
|
||||||
//load_texture(filename, "_spec.tga", specularmap_);
|
load_texture(filename, "_spec.tga", specularmap_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Model::~Model() {}
|
Model::~Model() {}
|
||||||
@@ -58,9 +58,9 @@ void Model::ApplyTransform() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Model::translate(Vec3f tr) {
|
void Model::translate(Vec3f tr) {
|
||||||
Translation[0][3] += tr.x;
|
Translation[0][3] = tr.x;
|
||||||
Translation[1][3] += tr.y;
|
Translation[1][3] = tr.y;
|
||||||
Translation[2][3] += tr.z;
|
Translation[2][3] = tr.z;
|
||||||
}
|
}
|
||||||
void Model::rotate(Vec3f rot) {
|
void Model::rotate(Vec3f rot) {
|
||||||
rot = rot * DEG2RAD;
|
rot = rot * DEG2RAD;
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,104 @@
|
|||||||
|
#include "quaternion.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
Quaternion::Quaternion(float x, float y, float z, float w)
|
||||||
|
{
|
||||||
|
x_ = x;
|
||||||
|
y_ = y;
|
||||||
|
z_ = z;
|
||||||
|
w_ = w;
|
||||||
|
normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Quaternion::normalize()
|
||||||
|
{
|
||||||
|
float mag = (float)sqrt(w_ * w_ + x_ * x_ + y_ * y_ + z_ * z_);
|
||||||
|
w_ /= mag;
|
||||||
|
x_ /= mag;
|
||||||
|
y_ /= mag;
|
||||||
|
z_ /= mag;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix Quaternion::toRotationMatrix()
|
||||||
|
{
|
||||||
|
Matrix matrix;
|
||||||
|
float xy = x_ * y_;
|
||||||
|
float xz = x_ * z_;
|
||||||
|
float xw = x_ * w_;
|
||||||
|
float yz = y_ * z_;
|
||||||
|
float yw = y_ * w_;
|
||||||
|
float zw = z_ * w_;
|
||||||
|
float xSquared = x_ * x_;
|
||||||
|
float ySquared = y_ * y_;
|
||||||
|
float zSquared = z_ * z_;
|
||||||
|
|
||||||
|
Vec4f c0 = Vec4f(1 - 2 * (ySquared + zSquared), 2 * (xy - zw), 2 * (xz + yw),0);
|
||||||
|
Vec4f c1 = Vec4f(2 * (xy + zw), 1 - 2 * (xSquared + zSquared), 2 * (yz - xw), 0);
|
||||||
|
Vec4f c2 = Vec4f(2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xSquared + ySquared), 0);
|
||||||
|
Vec4f c3 = Vec4f(0,0,0,1);
|
||||||
|
|
||||||
|
matrix.set_col(0,c0);
|
||||||
|
matrix.set_col(1, c1);
|
||||||
|
matrix.set_col(2, c2);
|
||||||
|
matrix.set_col(3, c3);
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion Quaternion::fromMatrix(Matrix matrix)
|
||||||
|
{
|
||||||
|
float w_, x_, y_, z_;
|
||||||
|
float diagonal = matrix[0][0] + matrix[1][1] + matrix[2][2];
|
||||||
|
if (diagonal > 0) {
|
||||||
|
float w4 = (float)(sqrt(diagonal + 1.f) * 2.f);
|
||||||
|
w_ = w4 / 4.f;
|
||||||
|
x_ = (matrix[2][1] - matrix[1][2]) / w4;
|
||||||
|
y_ = (matrix[0][2] - matrix[2][0]) / w4;
|
||||||
|
z_ = (matrix[1][0] - matrix[0][1]) / w4;
|
||||||
|
}
|
||||||
|
else if ((matrix[0][0] > matrix[1][1]) && (matrix[0][0] > matrix[2][2])) {
|
||||||
|
float x4 = (float)(sqrt(1.f + matrix[0][0] - matrix[1][1] - matrix[2][2]) * 2.f);
|
||||||
|
w_ = (matrix[2][1] - matrix[1][2]) / x4;
|
||||||
|
x_ = x4 / 4.f;
|
||||||
|
y_ = (matrix[0][1] + matrix[1][0]) / x4;
|
||||||
|
z_ = (matrix[0][2] + matrix[2][0]) / x4;
|
||||||
|
}
|
||||||
|
else if (matrix[1][1] > matrix[2][2]) {
|
||||||
|
float y4 = (float)(sqrt(1.f + matrix[1][1] - matrix[0][0] - matrix[2][2]) * 2.f);
|
||||||
|
w_ = (matrix[0][2] - matrix[2][0]) / y4;
|
||||||
|
x_ = (matrix[0][1] + matrix[1][0]) / y4;
|
||||||
|
y_ = y4 / 4.f;
|
||||||
|
z_ = (matrix[1][2] + matrix[2][1]) / y4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float z4 = (float)(sqrt(1.f + matrix[2][2] - matrix[0][0] - matrix[1][1]) * 2.f);
|
||||||
|
w_ = (matrix[1][0] - matrix[0][1]) / z4;
|
||||||
|
x_ = (matrix[0][2] + matrix[2][0]) / z4;
|
||||||
|
y_ = (matrix[1][2] + matrix[2][1]) / z4;
|
||||||
|
z_ = z4 / 4.f;
|
||||||
|
}
|
||||||
|
return Quaternion(x_, y_, z_, w_);
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion Quaternion::interpolate(Quaternion a, Quaternion b, float blend)
|
||||||
|
{
|
||||||
|
Quaternion result(0, 0, 0, 1);
|
||||||
|
float dot = a.w_ * b.w_ + a.x_ * b.x_ + a.y_ * b.y_ + a.z_ * b.z_;
|
||||||
|
float blendI = 1.f - blend;
|
||||||
|
if (dot < 0) {
|
||||||
|
result.w_ = blendI * a.w_ + blend * -b.w_;
|
||||||
|
result.x_ = blendI * a.x_ + blend * -b.x_;
|
||||||
|
result.y_ = blendI * a.y_ + blend * -b.y_;
|
||||||
|
result.z_ = blendI * a.z_ + blend * -b.z_;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.w_ = blendI * a.w_ + blend * b.w_;
|
||||||
|
result.x_ = blendI * a.x_ + blend * b.x_;
|
||||||
|
result.y_ = blendI * a.y_ + blend * b.y_;
|
||||||
|
result.z_ = blendI * a.z_ + blend * b.z_;
|
||||||
|
}
|
||||||
|
result.normalize();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "geometry.h"
|
||||||
|
class Quaternion
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
float x_, y_, z_, w_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
Quaternion() = default;
|
||||||
|
Quaternion(float x, float y, float z, float w);
|
||||||
|
void normalize();
|
||||||
|
Matrix toRotationMatrix();
|
||||||
|
static Quaternion fromMatrix(Matrix matrix);
|
||||||
|
static Quaternion interpolate(Quaternion a, Quaternion b, float blend);
|
||||||
|
};
|
||||||
|
|
||||||
+88
-196
@@ -1,225 +1,117 @@
|
|||||||
#define _USE_MATH_DEFINES
|
#include "model.h"
|
||||||
#include <vector>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <limits>
|
|
||||||
#include "tgaimage.h"
|
|
||||||
#include "model.h"
|
|
||||||
#include "geometry.h"
|
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "util_window.h"
|
#include "util_window.h"
|
||||||
#include <ctime>
|
#include "camera.h"
|
||||||
#include "ColladaModel.h"
|
#include "util_renderer.h"
|
||||||
#include "COLLADA.h"
|
#include "colladamodel.h"
|
||||||
|
|
||||||
|
#define HORIZONTAL_CAMERA_SPEED 0.1
|
||||||
|
#define VERTICAL_CAMERA_SPEED 0.1
|
||||||
|
#define VERTICAL_CAMERA_CLAMP_UP 90
|
||||||
|
#define VERTICAL_CAMERA_CLAMP_DOWN -90
|
||||||
|
#define NEAR_CLIP_PLANE 0
|
||||||
|
#define FAR_CLIP_PLANE 10
|
||||||
|
#define FOV 30
|
||||||
|
#define CAMERA_MOVEMENT_SPEED 0.05f
|
||||||
|
#define DEFAULT_CAMERA_POS Vec3f(0, 0, 5)
|
||||||
|
#define DEFAULT_CAMERA_ROT Vec3f(0, 0, 0)
|
||||||
|
#define LIGHT_INTENSITY 2.f
|
||||||
|
|
||||||
const TGAColor white = TGAColor(255, 255, 255, 255);
|
const TGAColor white = TGAColor(255, 255, 255, 255);
|
||||||
const TGAColor red = TGAColor(255, 0, 0, 255);
|
const TGAColor red = TGAColor(255, 0, 0, 255);
|
||||||
const TGAColor green = TGAColor(0, 255, 0, 255);
|
const TGAColor green = TGAColor(0, 255, 0, 255);
|
||||||
const TGAColor blue = TGAColor(0, 0, 255, 255);
|
const TGAColor blue = TGAColor(0, 0, 255, 255);
|
||||||
|
|
||||||
const int depth = 255;
|
Matrix ViewPort = Matrix::identity();
|
||||||
|
Matrix ModelView = Matrix::identity();
|
||||||
|
Matrix Projection = Matrix::identity();
|
||||||
|
|
||||||
float* z_buffer;
|
ColladaModel* model = new ColladaModel("sssssssssssss.dae");
|
||||||
Vec3f light_dir = Vec3f(0, 0, 1).normalize();
|
Camera camera;
|
||||||
Vec3f eye(0, 0, 3);
|
|
||||||
Vec3f center(0, 0, 0);
|
|
||||||
|
|
||||||
Matrix viewport(int x, int y, int w, int h) {
|
Vec3f light_dir = Vec3f(1, 1, 1).normalize();
|
||||||
Matrix m = Matrix::identity();
|
|
||||||
m[0][3] = x + w / 2.f;
|
|
||||||
m[1][3] = y + h / 2.f;
|
|
||||||
m[2][3] = depth / 2.f;
|
|
||||||
|
|
||||||
m[0][0] = w / 2.f;
|
void init_camera() {
|
||||||
m[1][1] = h / 2.f;
|
camera.SetPosition(DEFAULT_CAMERA_POS);
|
||||||
m[2][2] = depth / 2.f;
|
camera.SetRotation(DEFAULT_CAMERA_ROT);
|
||||||
return m;
|
camera.SetFOV(FOV);
|
||||||
|
camera.SetNearPlane(NEAR_CLIP_PLANE);
|
||||||
|
camera.SetFarPlane(FAR_CLIP_PLANE);
|
||||||
|
camera.SetClampRotDown(VERTICAL_CAMERA_CLAMP_DOWN);
|
||||||
|
camera.SetClampRotUp(VERTICAL_CAMERA_CLAMP_UP);
|
||||||
|
camera.SetHorizontalRotSpeed(HORIZONTAL_CAMERA_SPEED);
|
||||||
|
camera.SetVerticalRotSpeed(VERTICAL_CAMERA_SPEED);
|
||||||
|
camera.SetMovementSpeed(CAMERA_MOVEMENT_SPEED);
|
||||||
|
camera.ApplyChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
void line(Vec2i p0, Vec2i p1, TGAImage &image, TGAColor color)
|
void clear_zbuffer()
|
||||||
{
|
{
|
||||||
bool steep = false;
|
|
||||||
|
|
||||||
if (std::abs(p0[0] - p1[0]) < std::abs(p0[1] - p1[1])) {
|
|
||||||
std::swap(p0[0], p0[1]);
|
|
||||||
std::swap(p1[0], p1[1]);
|
|
||||||
steep = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p0[0] > p1[0]) {
|
|
||||||
std::swap(p0[0], p1[0]);
|
|
||||||
std::swap(p0[1], p1[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int dx = p1[0] - p0[0];
|
|
||||||
int dy = p1[1] - p0[1];
|
|
||||||
int derror2 = std::abs(dy) * 2;
|
|
||||||
int error2 = 0;
|
|
||||||
int y = p0[1];
|
|
||||||
int y_step = p1[1] > p0[1] ? 1 : -1;
|
|
||||||
int dx_2 = 2 * dx;
|
|
||||||
|
|
||||||
for (int x = p0[0]; x <= p1[0]; x++) {
|
|
||||||
if (steep) {
|
|
||||||
image.set(y, x, color);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
image.set(x, y, color);
|
|
||||||
}
|
|
||||||
error2 += derror2;
|
|
||||||
if (error2 > dx) {
|
|
||||||
y += (y_step);
|
|
||||||
error2 -= dx_2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3f barycentric(Vec3f* pts, Vec3f P)
|
|
||||||
{
|
|
||||||
Vec3f u = cross(
|
|
||||||
Vec3f(pts[2][0] - pts[0][0], pts[1][0] - pts[0][0], pts[0][0] - P[0]), // AC_x, AB_x, distance_x
|
|
||||||
Vec3f(pts[2][1] - pts[0][1], pts[1][1] - pts[0][1], pts[0][1] - P[1]) // AC_y, AB_y, distance_y
|
|
||||||
);
|
|
||||||
|
|
||||||
if (std::abs(u[2]) < 1) return Vec3f(-1, 1, 1);
|
|
||||||
return Vec3f(1.f - (u.x + u.y) / u.z, u.y / u.z, u.x / u.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void triangle(
|
|
||||||
Vec3f* pts, // Needed
|
|
||||||
ColladaModel* model, // Should be removed
|
|
||||||
Vec2f* diff_pts, // Should be removed
|
|
||||||
float* intensities,
|
|
||||||
Vec3f camera_pos) // Not really sure yet
|
|
||||||
{
|
|
||||||
|
|
||||||
if (pts[0].y == pts[1].y && pts[0].y == pts[2].y) return; // i dont care about degenerate triangles
|
|
||||||
if (pts[0].y > pts[1].y) {
|
|
||||||
std::swap(pts[0], pts[1]);
|
|
||||||
std::swap(diff_pts[0], diff_pts[1]);
|
|
||||||
std::swap(intensities[0], intensities[1]);
|
|
||||||
}
|
|
||||||
if (pts[0].y > pts[2].y) {
|
|
||||||
std::swap(pts[0], pts[2]);
|
|
||||||
std::swap(diff_pts[0], diff_pts[2]);
|
|
||||||
std::swap(intensities[0], intensities[2]);
|
|
||||||
}
|
|
||||||
if (pts[1].y > pts[2].y) {
|
|
||||||
std::swap(pts[1], pts[2]);
|
|
||||||
std::swap(diff_pts[1], diff_pts[2]);
|
|
||||||
std::swap(intensities[1], intensities[2]);
|
|
||||||
}
|
|
||||||
Vec2i bounding_box_min(screen_width - 1, screen_height - 1);
|
|
||||||
Vec2i bounding_box_max(0, 0);
|
|
||||||
Vec2i clamp(screen_width - 1, screen_height - 1);
|
|
||||||
TGAColor color = white;
|
|
||||||
|
|
||||||
for(int i = 0; i < 3; i++) {
|
|
||||||
for(int j =0; j < 2; j++) {
|
|
||||||
bounding_box_min[j] = std::fmax(0, std::fmin(bounding_box_min[j], (int)pts[i][j]));
|
|
||||||
bounding_box_max[j] = std::fmin(clamp[j], std::fmax(bounding_box_max[j], (int)pts[i][j]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3f P;
|
|
||||||
for(P.x = bounding_box_min.x; P.x <= bounding_box_max.x; P.x++) {
|
|
||||||
for(P.y = bounding_box_min.y; P.y <= bounding_box_max.y; P.y++) {
|
|
||||||
Vec3f bc_coord = barycentric(pts, P);
|
|
||||||
if(bc_coord.x < 0 || bc_coord.y < 0 || bc_coord.z < 0) continue;
|
|
||||||
|
|
||||||
|
|
||||||
float intensity =
|
|
||||||
intensities[0]
|
|
||||||
+ (intensities[1] - intensities[0]) * bc_coord[1]
|
|
||||||
+ (intensities[2] - intensities[0]) * bc_coord[2];
|
|
||||||
|
|
||||||
|
|
||||||
// Interpolating Z using the barycentric coordinates
|
|
||||||
P.z = 0;
|
|
||||||
for(int i = 0; i < 3; i++) P.z += pts[i][2] * bc_coord[i];
|
|
||||||
|
|
||||||
// Coloring according to the Z-Buffer
|
|
||||||
if (P.z > z_buffer[(int)(P.x + P.y * screen_width)])
|
|
||||||
{
|
|
||||||
z_buffer[(int)(P.x + P.y * screen_width)] = P.z;
|
|
||||||
|
|
||||||
// If diff_pts (Diffusemap Points) were passed, then find the
|
|
||||||
// color of the current pixel
|
|
||||||
if(diff_pts) {
|
|
||||||
Vec2f diff_pt =
|
|
||||||
diff_pts[0]
|
|
||||||
+ (diff_pts[1] - diff_pts[0]) * bc_coord[1]
|
|
||||||
+ (diff_pts[2] - diff_pts[0]) * bc_coord[2];
|
|
||||||
|
|
||||||
color = model->diffuse(diff_pt);
|
|
||||||
}
|
|
||||||
color = color * intensity;
|
|
||||||
set_pixel(P.x, P.y, color_to_int(color));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int color_to_int(TGAColor col) {
|
|
||||||
return (col[2] << 16) | (col[1] << 8) | col[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_zbuffer()
|
|
||||||
{
|
|
||||||
z_buffer = new float[screen_width*screen_height];
|
|
||||||
for (int i = 0; i < screen_width * screen_height; i++)
|
for (int i = 0; i < screen_width * screen_height; i++)
|
||||||
z_buffer[i] = INT_MIN;
|
z_buffer[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix lookat(Vec3f eye, Vec3f center, Vec3f up) {
|
|
||||||
Vec3f z = (eye - center).normalize();
|
struct TextureShader : public IShader {
|
||||||
Vec3f x = cross(up, z).normalize();
|
mat<2, 3, float> varying_uv_coords;
|
||||||
Vec3f y = cross(z, x).normalize();
|
Matrix uniform_mit;
|
||||||
Matrix Minv = Matrix::identity();
|
Matrix uniform_m;
|
||||||
Matrix Tr = Matrix::identity();
|
|
||||||
for (int i = 0; i < 3; i++) {
|
virtual Vec4f vertex(int iface, int nthvert) {
|
||||||
Minv[0][i] = x[i];
|
varying_uv_coords.set_col(nthvert, model->uv(iface, nthvert));
|
||||||
Minv[1][i] = y[i];
|
Vec4f gl_Vertex = embed<4>(model->vertix(iface, nthvert));
|
||||||
Minv[2][i] = z[i];
|
return ViewPort * Projection * ModelView * gl_Vertex; // transform it to screen coordinates
|
||||||
Tr[i][3] = -center[i];
|
|
||||||
}
|
}
|
||||||
return Minv * Tr;
|
|
||||||
|
virtual bool fragment(Vec3f bar, TGAColor &color) {
|
||||||
|
Vec2f uv = varying_uv_coords * bar;
|
||||||
|
Vec3f normal = Vec3f(uniform_mit * Vec4f(model->normal(uv))).normalize();
|
||||||
|
Vec3f light = Vec3f(uniform_m * Vec4f(light_dir)).normalize();
|
||||||
|
Vec3f reflection = (normal * (normal*light*2.f) - light).normalize();
|
||||||
|
float spec_intensity = pow(std::fmax(reflection.z, 0.f), model->specular(uv));
|
||||||
|
float diff_intensity = std::fmax(0.f, (normal*light));
|
||||||
|
TGAColor c = model->diffuse(uv);
|
||||||
|
color = c;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
color[i] = std::fmin(1 + c[i] * (diff_intensity + 0.8 * spec_intensity), 255) * LIGHT_INTENSITY;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void render()
|
void render()
|
||||||
{
|
{
|
||||||
COLLADA C("sssssssssssss.dae");
|
|
||||||
ColladaModel* model = new ColladaModel("african_head.dae");
|
|
||||||
Matrix ViewPort = viewport(screen_width / 8, screen_height / 8, screen_width * 3 / 4, screen_height * 3 / 4);
|
|
||||||
Matrix Projection = Matrix::identity();
|
|
||||||
Matrix ModelView = lookat(eye, center, Vec3f(0, 1, 0));
|
|
||||||
|
|
||||||
Projection[3][2] = -1.f / (eye - center).norm();
|
|
||||||
|
|
||||||
Matrix z = ViewPort * Projection * ModelView * model->Transform;
|
|
||||||
|
|
||||||
init_zbuffer();
|
|
||||||
for (int i = 0; i < model->nfaces(); i++)
|
|
||||||
{
|
{
|
||||||
std::vector<int> face = model->face(i);
|
//light_dir = camera.GetForward().normalize() * -1;
|
||||||
Vec3f screen_coords[3];
|
}
|
||||||
Vec3f world_coords[3];
|
|
||||||
Vec2f diffuse_coords[3];
|
|
||||||
float intensities[3];
|
|
||||||
|
|
||||||
for (int j = 0; j < 3; j++)
|
|
||||||
{
|
{
|
||||||
Vec3f v = model->vertix(face[j]);
|
viewport(0, 0, screen_width, screen_height, FAR_CLIP_PLANE, NEAR_CLIP_PLANE);
|
||||||
Vec4f v4(v);
|
Projection = camera.GetProjectionMatrix();
|
||||||
Vec3f coord(z * v4);
|
ModelView = camera.GetModelViewMatrix();
|
||||||
|
|
||||||
screen_coords[j] = coord;
|
|
||||||
world_coords[j] = v;
|
|
||||||
diffuse_coords[j] = model->uv(i, j);
|
|
||||||
intensities[j] = model->normal(i, j) * light_dir;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
triangle(screen_coords, model, diffuse_coords, intensities, Vec3f(0, 0, 5));
|
|
||||||
|
//Matrix z = ViewPort * Projection * ModelView * model->Transform;
|
||||||
|
|
||||||
|
clear_zbuffer();
|
||||||
|
TextureShader shader;
|
||||||
|
shader.uniform_m = (Projection);
|
||||||
|
shader.uniform_mit = (Projection).invert_transpose();
|
||||||
|
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (int i = 0; i < model->nfaces(); i++) {
|
||||||
|
Vec4f screen_coords[3];
|
||||||
|
bool out = true;
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
screen_coords[j] = shader.vertex(i, j);
|
||||||
|
Vec3f screen3(screen_coords[j]);
|
||||||
|
|
||||||
|
if (screen3.x > 0 && screen3.x < screen_width && screen3.y > 0 && screen3.y < screen_height) out = false;
|
||||||
|
}
|
||||||
|
if(!out)
|
||||||
|
triangle(screen_coords, shader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
#ifndef RENDERER_HEADER
|
#ifndef RENDERER_HEADER
|
||||||
#define RENDERER_HEADER
|
#define RENDERER_HEADER
|
||||||
#include "tgaimage.h"
|
#include "tgaimage.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern float* z_buffer;
|
||||||
|
extern Camera camera;
|
||||||
|
extern float TIME;
|
||||||
|
|
||||||
|
void init_camera();
|
||||||
void render();
|
void render();
|
||||||
int color_to_int(TGAColor col);
|
int color_to_int(TGAColor col);
|
||||||
#endif
|
#endif
|
||||||
+742
-2009
File diff suppressed because one or more lines are too long
@@ -0,0 +1,73 @@
|
|||||||
|
#include "util_renderer.h"
|
||||||
|
#include "util_window.h"
|
||||||
|
|
||||||
|
IShader::~IShader() {}
|
||||||
|
|
||||||
|
float* z_buffer = new float[screen_width * screen_height];
|
||||||
|
|
||||||
|
void viewport(int x, int y, int w, int h, int far_plane, int near_plane) {
|
||||||
|
ViewPort[0][3] = x + w / 2.f;
|
||||||
|
ViewPort[1][3] = y + h / 2.f;
|
||||||
|
ViewPort[2][3] = (far_plane-near_plane) / 2.f;
|
||||||
|
|
||||||
|
ViewPort[0][0] = w / 2.f;
|
||||||
|
ViewPort[1][1] = h / 2.f;
|
||||||
|
ViewPort[2][2] = (far_plane+near_plane) / 2.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int color_to_int(TGAColor col) {
|
||||||
|
return (col[2] << 16) | (col[1] << 8) | col[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f barycentric(Vec3f* pts, Vec3f P)
|
||||||
|
{
|
||||||
|
Vec3f u = cross(
|
||||||
|
Vec3f(pts[2][0] - pts[0][0], pts[1][0] - pts[0][0], pts[0][0] - P[0]), // AC_x, AB_x, distance_x
|
||||||
|
Vec3f(pts[2][1] - pts[0][1], pts[1][1] - pts[0][1], pts[0][1] - P[1]) // AC_y, AB_y, distance_y
|
||||||
|
);
|
||||||
|
|
||||||
|
if (std::abs(u[2]) < 1) return Vec3f(-1, 1, 1);
|
||||||
|
return Vec3f(1.f - (u.x + u.y) / u.z, u.y / u.z, u.x / u.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void triangle( Vec4f* pts, IShader &shader)
|
||||||
|
{
|
||||||
|
Vec3f pts3[3];
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
pts3[i] = Vec3f(pts[i]);
|
||||||
|
|
||||||
|
if (pts3[0].y == pts3[1].y && pts3[0].y == pts3[2].y) return; // i dont care about degenerate triangles
|
||||||
|
//if (pts3[0].y > pts3[1].y) { std::swap(pts3[0], pts3[1]); }
|
||||||
|
//if (pts3[0].y > pts3[2].y) { std::swap(pts3[0], pts3[2]); }
|
||||||
|
//if (pts3[1].y > pts3[2].y) { std::swap(pts3[1], pts3[2]); }
|
||||||
|
|
||||||
|
Vec2i bounding_box_min(screen_width - 1, screen_height - 1);
|
||||||
|
Vec2i bounding_box_max(0, 0);
|
||||||
|
Vec2i clamp(screen_width - 1, screen_height - 1);
|
||||||
|
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
for (int j = 0; j < 2; j++) {
|
||||||
|
bounding_box_min[j] = std::fmax(0, std::fmin(bounding_box_min[j], (int)pts3[i][j]));
|
||||||
|
bounding_box_max[j] = std::fmin(clamp[j], std::fmax(bounding_box_max[j], (int)pts3[i][j]));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vec3i P;
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (P.x = bounding_box_min.x; P.x <= bounding_box_max.x; P.x++) {
|
||||||
|
for (P.y = bounding_box_min.y; P.y <= bounding_box_max.y; P.y++) {
|
||||||
|
Vec3f bc_coord = barycentric(pts3, P);
|
||||||
|
float frag_depth = 0;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
frag_depth += pts3[i][2] * bc_coord[i];
|
||||||
|
if (bc_coord.x < 0 || bc_coord.y < 0 || bc_coord.z < 0 || z_buffer[ P.x + P.y * screen_width ]>frag_depth) continue;
|
||||||
|
TGAColor color;
|
||||||
|
bool discard = shader.fragment(bc_coord, color);
|
||||||
|
if (!discard) {
|
||||||
|
z_buffer[P.x + P.y * screen_width] = frag_depth;
|
||||||
|
set_pixel(P.x, P.y, color_to_int(color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "tgaimage.h"
|
||||||
|
#include "model.h"
|
||||||
|
#include "geometry.h"
|
||||||
|
|
||||||
|
extern Matrix ModelView;
|
||||||
|
extern Matrix ViewPort;
|
||||||
|
extern Matrix Projection;
|
||||||
|
|
||||||
|
void viewport(int x, int y, int w, int h, int far, int near);
|
||||||
|
|
||||||
|
struct IShader {
|
||||||
|
virtual ~IShader();
|
||||||
|
virtual Vec4f vertex(int iface, int nthvert) = 0;
|
||||||
|
virtual bool fragment(Vec3f bar, TGAColor &color) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
//void triangle(Vec4f *pts, IShader &shader, TGAImage &image, TGAImage &zbuffer);
|
||||||
|
|
||||||
|
//void triangle( Vec3f* pts, Vec2f* diff_pts, Model* model, float* intensities)
|
||||||
|
|
||||||
|
void triangle(Vec4f* pts, IShader &shader);
|
||||||
@@ -8,8 +8,6 @@ BITMAPINFO info;
|
|||||||
HBITMAP hbm;
|
HBITMAP hbm;
|
||||||
const int BITCOUNT_PER_PIXEL = 24;
|
const int BITCOUNT_PER_PIXEL = 24;
|
||||||
const int title_height = 39;
|
const int title_height = 39;
|
||||||
int screen_width = 0;
|
|
||||||
int screen_height = 0;
|
|
||||||
long long bytes_per_row;
|
long long bytes_per_row;
|
||||||
bool screen_changed = false;
|
bool screen_changed = false;
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
@@ -17,15 +15,13 @@ HDRAWDIB hdd;
|
|||||||
HDC bitmap_dc;
|
HDC bitmap_dc;
|
||||||
HGDIOBJ old_obj;
|
HGDIOBJ old_obj;
|
||||||
|
|
||||||
HWND create_window(int width, int height, HINSTANCE &hInstance) {
|
HWND create_window(HINSTANCE &hInstance) {
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
WNDCLASSEX wnd_class = { 0 };
|
WNDCLASSEX wnd_class = { 0 };
|
||||||
init_wnd_class(wnd_class, hInstance);
|
init_wnd_class(wnd_class, hInstance);
|
||||||
|
|
||||||
RegisterClassEx(&wnd_class);
|
RegisterClassEx(&wnd_class);
|
||||||
|
|
||||||
screen_width = width;
|
|
||||||
screen_height = height;
|
|
||||||
create_hwnd(hWnd, hInstance);
|
create_hwnd(hWnd, hInstance);
|
||||||
init(hWnd);
|
init(hWnd);
|
||||||
|
|
||||||
@@ -107,6 +103,16 @@ void set_pixel(unsigned int x, unsigned int y, unsigned int color) {
|
|||||||
screen_changed = true;
|
screen_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update() {
|
void clear_screen() {
|
||||||
DrawDibDraw(hdd, hdc, 0, 0, screen_width, screen_height, &info.bmiHeader, pixels, 0, 0, screen_width, screen_height, 0);
|
for (int x = 0; x < screen_width; x++)
|
||||||
|
for (int y = 0; y < screen_height; y++)
|
||||||
|
set_pixel(x, y, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update() {
|
||||||
|
if (screen_changed) {
|
||||||
|
DrawDibDraw(hdd, hdc, 0, 0, screen_width, screen_height, &info.bmiHeader, pixels, 0, 0, screen_width, screen_height, 0);
|
||||||
|
clear_screen();
|
||||||
|
screen_changed = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,18 +18,19 @@ extern HDC hdc;
|
|||||||
extern HDRAWDIB hdd;
|
extern HDRAWDIB hdd;
|
||||||
extern HDC bitmap_dc;
|
extern HDC bitmap_dc;
|
||||||
extern HGDIOBJ old_obj;
|
extern HGDIOBJ old_obj;
|
||||||
extern int screen_width;
|
extern const int screen_width;
|
||||||
extern int screen_height;
|
extern const int screen_height;
|
||||||
|
|
||||||
|
|
||||||
void init(HWND &hWnd);
|
void init(HWND &hWnd);
|
||||||
void destroy_window();
|
void destroy_window();
|
||||||
HWND create_window(int width, int height, HINSTANCE &hInstance);
|
HWND create_window(HINSTANCE &hInstance);
|
||||||
void create_hwnd(HWND &hwnd, HINSTANCE &hInstance);
|
void create_hwnd(HWND &hwnd, HINSTANCE &hInstance);
|
||||||
void init_wnd_class(WNDCLASSEX &wndClass, HINSTANCE &hInstance);
|
void init_wnd_class(WNDCLASSEX &wndClass, HINSTANCE &hInstance);
|
||||||
void set_pixel(unsigned int x, unsigned int y, unsigned int color);
|
void set_pixel(unsigned int x, unsigned int y, unsigned int color);
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
void CALLBACK FixedUpdate(HWND hwnd, UINT message, UINT uInt, DWORD dWord);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user