done
.dae integrated
This commit is contained in:
+107
-7
@@ -1,7 +1,18 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "ColladaModel.h"
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
#define DEG2RAD PI/180
|
||||
|
||||
ColladaModel::ColladaModel(const char* filename) : faces_(), vertices_(), normals_()
|
||||
{
|
||||
Transform = Matrix::identity();
|
||||
Rotation = Matrix::identity();
|
||||
Scale = Matrix::identity();
|
||||
Translation = Matrix::identity();
|
||||
|
||||
tinyxml2::XMLDocument doc;
|
||||
doc.LoadFile(filename);
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -56,23 +67,112 @@ ColladaModel::ColladaModel(const char* filename) : faces_(), vertices_(), normal
|
||||
str_normal >> temp.z;
|
||||
normals_.push_back(temp);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
texcoord_count = 0;
|
||||
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);
|
||||
std::stringstream str_texcoord(xml_texture->GetText());
|
||||
|
||||
for (int i = 0; i < texcoord_count / 2; i++)
|
||||
{
|
||||
Vec2f temp;
|
||||
str_texcoord >> temp.x;
|
||||
str_texcoord >> temp.y;
|
||||
textureco_.push_back(temp);
|
||||
}
|
||||
|
||||
load_texture(filename, "_diffuse.tga", diffusemap_);
|
||||
load_texture(filename, "_nm_tangent.tga", normalmap_);
|
||||
}
|
||||
|
||||
ColladaModel::~ColladaModel() {
|
||||
}
|
||||
|
||||
std::vector<Vec3i> ColladaModel::face(int idx) {
|
||||
return faces_[idx];
|
||||
void ColladaModel::ApplyTransform() {
|
||||
Transform = Translation * Scale * Rotation;
|
||||
}
|
||||
|
||||
Vec3f ColladaModel::vertex(int i) {
|
||||
return vertices_[i];
|
||||
void ColladaModel::translate(Vec3f tr) {
|
||||
Translation[0][3] += tr.x;
|
||||
Translation[1][3] += tr.y;
|
||||
Translation[2][3] += tr.z;
|
||||
}
|
||||
void ColladaModel::rotate(Vec3f rot) {
|
||||
rot = rot * DEG2RAD;
|
||||
|
||||
int ColladaModel::nvertices() {
|
||||
return vertex_count;
|
||||
Rotation[0][0] = cosf(rot.y) * cosf(rot.z);
|
||||
Rotation[0][1] = -cosf(rot.y) * sinf(rot.z);
|
||||
Rotation[0][2] = sinf(rot.y);
|
||||
Rotation[1][0] = sinf(rot.x) * sinf(rot.y) * cosf(rot.z) + cosf(rot.x) * sinf(rot.z);
|
||||
Rotation[1][1] = -sinf(rot.x) * sinf(rot.y) * sinf(rot.z) + cosf(rot.x) * cosf(rot.z);
|
||||
Rotation[1][2] = -sinf(rot.x) * cosf(rot.y);
|
||||
Rotation[2][0] = -cosf(rot.x) * sinf(rot.y) * cosf(rot.z) + sinf(rot.x) * sinf(rot.z);
|
||||
Rotation[2][1] = cosf(rot.x) * sinf(rot.y) * sinf(rot.z) + sinf(rot.x) * cosf(rot.z);
|
||||
Rotation[2][2] = cosf(rot.x) * cosf(rot.y);
|
||||
}
|
||||
void ColladaModel::scale(Vec3f scl) {
|
||||
Scale[0][0] = scl.x;
|
||||
Scale[1][1] = scl.y;
|
||||
Scale[2][2] = scl.z;
|
||||
}
|
||||
|
||||
int ColladaModel::nfaces() {
|
||||
return face_count;
|
||||
}
|
||||
}
|
||||
int ColladaModel::nvertices() {
|
||||
return vertex_count;
|
||||
}
|
||||
|
||||
std::vector<int> ColladaModel::face(int idx) {
|
||||
std::vector<int> face;
|
||||
for (int i = 0; i < (int)faces_[idx].size(); i++) face.push_back(faces_[idx][i][0]);
|
||||
return face;
|
||||
}
|
||||
|
||||
Vec3f ColladaModel::vertix(int i) {
|
||||
return vertices_[i];
|
||||
}
|
||||
|
||||
Vec3f ColladaModel::vertix(int iface, int nthvert) {
|
||||
return vertices_[faces_[iface][nthvert][0]];
|
||||
}
|
||||
|
||||
void ColladaModel::load_texture(std::string filename, const char* suffix, TGAImage& img) {
|
||||
std::string texfile(filename);
|
||||
size_t dot = texfile.find_last_of(".");
|
||||
if (dot != std::string::npos) {
|
||||
texfile = texfile.substr(0, dot) + std::string(suffix);
|
||||
std::cerr << "texture file " << texfile << " loading " << (img.read_tga_file(texfile.c_str()) ? "ok" : "failed") << std::endl;
|
||||
img.flip_vertically();
|
||||
}
|
||||
}
|
||||
|
||||
TGAColor ColladaModel::diffuse(Vec2f uvf) {
|
||||
Vec2i uv(uvf[0] * diffusemap_.get_width(), uvf[1] * diffusemap_.get_height());
|
||||
return diffusemap_.get(uv[0], uv[1]);
|
||||
}
|
||||
|
||||
Vec3f ColladaModel::normal(Vec2f uvf) {
|
||||
Vec2i uv(uvf[0] * normalmap_.get_width(), uvf[1] * normalmap_.get_height());
|
||||
TGAColor c = normalmap_.get(uv[0], uv[1]);
|
||||
Vec3f res;
|
||||
for (int i = 0; i < 3; i++)
|
||||
res[2 - i] = (float)c[i] / 255.f * 2.f - 1.f;
|
||||
return res;
|
||||
}
|
||||
|
||||
Vec2f ColladaModel::uv(int iface, int nthvert) {
|
||||
return textureco_[faces_[iface][nthvert][2]];
|
||||
}
|
||||
|
||||
float ColladaModel::specular(Vec2f uvf) {
|
||||
Vec2i uv(uvf[0] * specularmap_.get_width(), uvf[1] * specularmap_.get_height());
|
||||
return specularmap_.get(uv[0], uv[1])[0] / 1.f;
|
||||
}
|
||||
|
||||
Vec3f ColladaModel::normal(int iface, int nthvert) {
|
||||
int idx = faces_[iface][nthvert][1];
|
||||
return normals_[idx].normalize();
|
||||
}
|
||||
|
||||
+33
-13
@@ -1,11 +1,12 @@
|
||||
#ifndef __MODEL_s__
|
||||
#define __MODEL_s__
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ColladaModel.h"
|
||||
#include "tinyxml2.h"
|
||||
#include "geometry.h"
|
||||
#include "tgaimage.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
@@ -16,31 +17,50 @@
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class ColladaModel {
|
||||
private:
|
||||
int face_count;
|
||||
int vertex_count;
|
||||
int normal_count;
|
||||
int textureco_count;
|
||||
int texcoord_count;
|
||||
|
||||
std::vector<std::vector<Vec3i> > faces_;
|
||||
std::vector<std::vector<Vec3i> > faces_; //vertex/normal/uv
|
||||
std::vector<Vec3f> vertices_;
|
||||
std::vector<Vec3f> normals_;
|
||||
std::vector<Vec3f> textureco_;
|
||||
std::vector<Vec2f> textureco_;
|
||||
|
||||
TGAImage diffusemap_;
|
||||
TGAImage normalmap_;
|
||||
TGAImage specularmap_;
|
||||
|
||||
void load_texture(std::string filename, const char* suffix, TGAImage& img);
|
||||
public:
|
||||
ColladaModel(const char* filename);
|
||||
~ColladaModel();
|
||||
|
||||
std::vector<Vec3i> face(int idx);
|
||||
Vec3f vertex(int i);
|
||||
Vec3f normal(int i);
|
||||
Vec3f textureco(int i);
|
||||
|
||||
int nfaces();
|
||||
int nvertices();
|
||||
int nnormals();
|
||||
int ntextureco();
|
||||
};
|
||||
|
||||
Vec3f vertix(int iface, int nthvert);
|
||||
Vec3f vertix(int i);
|
||||
|
||||
Vec3f normal(int iface, int nthvert);
|
||||
Vec3f normal(Vec2f uv);
|
||||
|
||||
Vec2f uv(int iface, int nthvert);
|
||||
|
||||
Matrix Transform;
|
||||
Matrix Rotation;
|
||||
Matrix Scale;
|
||||
Matrix Translation;
|
||||
|
||||
void translate(Vec3f tr);
|
||||
void rotate(Vec3f rot);
|
||||
void scale(Vec3f scl);
|
||||
void ApplyTransform();
|
||||
|
||||
TGAColor diffuse(Vec2f uv);
|
||||
float specular(Vec2f uv);
|
||||
std::vector<int> face(int idx);
|
||||
};
|
||||
#endif
|
||||
+31
-70
@@ -87,7 +87,7 @@ Vec3f barycentric(Vec3f* pts, Vec3f P)
|
||||
|
||||
void triangle(
|
||||
Vec3f* pts, // Needed
|
||||
Model* model, // Should be removed
|
||||
ColladaModel* model, // Should be removed
|
||||
Vec2f* diff_pts, // Should be removed
|
||||
float* intensities,
|
||||
Vec3f camera_pos) // Not really sure yet
|
||||
@@ -186,77 +186,38 @@ Matrix lookat(Vec3f eye, Vec3f center, Vec3f up) {
|
||||
return Minv * Tr;
|
||||
}
|
||||
|
||||
void my_triangle(Vec2i t0, Vec2i t1, Vec2i t2, TGAImage& image, TGAColor color) {
|
||||
if (t0.y == t1.y && t0.y == t2.y) return; // i dont care about degenerate triangles
|
||||
if (t0.y > t1.y) std::swap(t0, t1);
|
||||
if (t0.y > t2.y) std::swap(t0, t2);
|
||||
if (t1.y > t2.y) std::swap(t1, t2);
|
||||
int total_height = t2.y - t0.y;
|
||||
for (int i = 0; i < total_height; i++) {
|
||||
bool second_half = i > t1.y - t0.y || t1.y == t0.y;
|
||||
int segment_height = second_half ? t2.y - t1.y : t1.y - t0.y;
|
||||
float alpha = (float)i / total_height;
|
||||
float beta = (float)(i - (second_half ? t1.y - t0.y : 0)) / segment_height; // be careful: with above conditions no division by zero here
|
||||
Vec2i A = t0 + (t2 - t0) * alpha;
|
||||
Vec2i B = second_half ? t1 + (t2 - t1) * beta : t0 + (t1 - t0) * beta;
|
||||
if (A.x > B.x) std::swap(A, B);
|
||||
for (int j = A.x; j <= B.x; j++) {
|
||||
image.set(j, t0.y + i, color); // attention, due to int casts t0.y+i != A.y
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void render()
|
||||
{
|
||||
//Model* model = new Model("african_head.obj");
|
||||
//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);
|
||||
// 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->vert(face[j]);
|
||||
// Vec4f v4(v);
|
||||
// Vec3f coord(z * v4);
|
||||
|
||||
// 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));
|
||||
//}
|
||||
|
||||
ColladaModel* model = new ColladaModel("african_head.dae");
|
||||
TGAImage image(800, 800, TGAImage::RGB);
|
||||
Vec3f light_dir(0, 0, -1);
|
||||
for (int i = 0; i < model->nfaces(); i++) {
|
||||
std::vector<Vec3i> face = model->face(i);
|
||||
Vec2i screen_coords[3];
|
||||
Vec3f world_coords[3];
|
||||
for (int j = 0; j < 3; j++) {
|
||||
Vec3f v = model->vertex(face[j][0]);
|
||||
screen_coords[j] = Vec2i((v.x + 1.) * 800 / 2., (v.y + 1.) * 800 / 2.);
|
||||
world_coords[j] = v;
|
||||
}
|
||||
my_triangle(screen_coords[0], screen_coords[1], screen_coords[2], image, white);
|
||||
}
|
||||
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));
|
||||
|
||||
image.flip_vertically(); // i want to have the origin at the left bottom corner of the image
|
||||
image.write_tga_file("output.tga");
|
||||
delete model;
|
||||
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);
|
||||
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]);
|
||||
Vec4f v4(v);
|
||||
Vec3f coord(z * v4);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user