Last active
February 4, 2017 17:30
-
-
Save kunugibaru/47956b52ef0d0268e51c16ad5f24cb8d to your computer and use it in GitHub Desktop.
三角バッファ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
/** | |
Triangle Buffer を使って頂点indexを作成する。 | |
*/ | |
#include<iostream> | |
//#include <Eigen\Core> | |
#include <string> | |
#include <vector> | |
#include <sstream> | |
#include <array> | |
#include <map> | |
namespace ku | |
{ | |
namespace detail | |
{ | |
//template<typename T> | |
//struct Vec3Impl : std::array<T, 3> | |
//{ | |
// T x() const { return this->at(0); } | |
// T y() const { return this->at(1); } | |
// T z() const { return this->at(2); } | |
// void set(const T x, const T y, const T z) | |
// { | |
// this->swap(std::array<T, 3>({ x,y,z })); | |
// } | |
//}; | |
//template<typename T> | |
//struct Vec2Impl : std::array<T, 2> | |
//{ | |
// T x() const { return this->at(0); } | |
// T y() const { return this->at(1); } | |
// void set(const T x, const T y) | |
// { | |
// this[0] = x; | |
// this[1] = y; | |
// } | |
//}; | |
template<typename T> | |
struct Vec3Impl | |
{ | |
std::array<T, 3> comps_; | |
T x() const { return this->comps_.at(0); } | |
T y() const { return this->comps_.at(1); } | |
T z() const { return this->comps_.at(2); } | |
void set(const T x, const T y, const T z) | |
{ | |
comps_.swap(std::array<T, 3>({ x,y,z })); | |
} | |
Vec3Impl(const T x, const T y, const T z) : comps_({ x,y,z }) {} | |
Vec3Impl() {} | |
}; | |
template<typename T> | |
struct Vec2Impl | |
{ | |
std::array<T, 2> comps_; | |
T x() const { return this->comps_.at(0); } | |
T y() const { return this->comps_.at(1); } | |
void set(const T x, const T y) | |
{ | |
comps_.swap(std::array<T, 2>({ x,y })); | |
} | |
Vec2Impl(const T x, const T y) : comps_({ x,y }) {} | |
Vec2Impl() {} | |
}; | |
} | |
//using Vec3 = Eigen::Vector3f; | |
//using Vec2 = Eigen::Vector2f; | |
using Vec3 = detail::Vec3Impl<float>; | |
using Vec2 = detail::Vec2Impl<float>; | |
namespace detail | |
{ | |
std::string dumps(const Vec3& v) | |
{ | |
std::stringstream sout; | |
sout << v.x() << "," << v.y() << "," << v.z(); | |
return sout.str(); | |
} | |
std::string dumps(const Vec2& v) | |
{ | |
std::stringstream sout; | |
sout << v.x() << "," << v.y(); | |
return sout.str(); | |
} | |
} | |
using HashKey = std::string; | |
struct BasicVert | |
{ | |
Vec3 pos_; | |
Vec3 normal_; | |
Vec3 color_; | |
Vec2 uv_; | |
HashKey make_hash() const | |
{ | |
using namespace detail; | |
return dumps(pos_) + dumps(normal_) + dumps(color_) + dumps(uv_); | |
} | |
}; | |
struct BasicSurf | |
{ | |
std::string shader_; | |
std::string make_hash() const | |
{ | |
return shader_; | |
} | |
}; | |
template<typename Vert, typename Surf> | |
struct TriangleImpl | |
{ | |
using verttype_ = Vert; | |
using surftype_ = Surf; | |
std::array<Vert, 3> verts_; | |
Surf surf_; | |
template<int index> | |
HashKey make_hash() const | |
{ | |
return std::get<index>(this->verts_).make_hash() + this->surf_.shader_; | |
} | |
}; | |
using Triangle = TriangleImpl<BasicVert, BasicSurf>; | |
template<typename TriImp> | |
struct TriangleBuffer | |
{ | |
using tritype_ = TriImp; | |
using verttype_ = typename TriImp::verttype_; | |
using surftype_ = typename TriImp::surftype_; | |
using Index = int; | |
//std::map<HashKey, verttype_> cache_; | |
using TriIndex = TriangleImpl<Index, BasicSurf>; | |
std::vector<TriIndex> tri_cache_; // {<0,1,2 "mat1">, <3,1,2 "mat2">} | |
std::map<Index, verttype_> index_cache_; // {1:<Vert>, 2:<Vert>} | |
std::map<HashKey, Index> hash_cache_; // {"hash": 0, "hash2": 1}; | |
void add_tri(const TriImp& tri) | |
{ | |
tri_cache_.push_back( | |
TriIndex{ | |
{ | |
add_vert<0>(tri), | |
add_vert<1>(tri), | |
add_vert<2>(tri) | |
}, | |
tri.surf_ | |
}); | |
} | |
template<int Vrt> | |
Index add_vert(const TriImp& tri) | |
{ | |
const HashKey& hash = tri.make_hash<Vrt>(); | |
try { | |
return this->hash_cache_.at(hash); | |
} | |
catch (std::out_of_range e) { | |
const Index& ind = index_cache_.size(); | |
this->hash_cache_[hash] = ind; | |
index_cache_[ind] = tri.verts_.at(Vrt); | |
return ind; | |
} | |
} | |
}; | |
/** | |
TEST ==== | |
*/ | |
struct PosVert | |
{ | |
Vec3 pos_; | |
HashKey make_hash() const | |
{ | |
return detail::dumps(this->pos_); | |
} | |
}; | |
class TestBuffer : public TriangleBuffer<TriangleImpl<PosVert, BasicSurf>> | |
{ | |
public: | |
}; | |
} | |
void te() | |
{ | |
using namespace ku; | |
TestBuffer::tritype_ tri; | |
tri.verts_[0].pos_.set(0, 1, 0); | |
tri.verts_[1].pos_.set(1, 0, 1); | |
tri.verts_[2].pos_.set(0, 0, 1); | |
tri.surf_.shader_ = "test"; | |
TestBuffer buff; | |
buff.add_tri(tri); | |
tri.verts_[0].pos_.set(0, -1, 0); | |
tri.verts_[1].pos_.set(1, 0, 1); | |
tri.verts_[2].pos_.set(0, 0, 1); | |
tri.surf_.shader_ = "test"; | |
buff.add_tri(tri); | |
} | |
#include "mikktspace.h" | |
namespace ku | |
{ | |
namespace mk | |
{ | |
using Vec3 = detail::Vec3Impl<float>; | |
using Tri = std::array<Vec3, 3>; | |
class MktDelegate | |
{ | |
public: | |
using Context = SMikkTSpaceContext; | |
using Interface = SMikkTSpaceInterface; | |
static int faces_count(const Context* context) { return 3; } | |
static int verts_count(const Context* context, const int iFace) { return 3; } | |
static std::vector<Tri>* get_tries(const Context* context) | |
{ | |
return (std::vector<Tri>*)(context->m_pUserData); | |
} | |
static void get_position(const Context* context, float fvPosOut[], const int iFace, const int iVert) | |
{ | |
std::cout << iFace << iVert; | |
} | |
static void get_normal(const Context * pContext, float fvNormOut[], const int iFace, const int iVert) | |
{ | |
std::cout << iFace << iVert; | |
} | |
static void get_uv(const Context * pContext, float fvTexcOut[], const int iFace, const int iVert) | |
{ | |
std::cout << iFace << iVert; | |
} | |
static void set_tangspace(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) | |
{ | |
} | |
static std::vector<Tri> get_tangnts(std::vector<Tri>* inputs) | |
{ | |
Interface iface; | |
iface.m_getNumFaces = faces_count; | |
iface.m_getNumVerticesOfFace = verts_count; | |
iface.m_getPosition = get_position; | |
iface.m_getNormal = get_normal; | |
iface.m_getTexCoord = get_uv; | |
iface.m_setTSpaceBasic = set_tangspace; | |
std::vector<Tri> tris; | |
Context context; | |
context.m_pInterface = &iface; | |
context.m_pUserData = inputs; | |
genTangSpaceDefault(&context); | |
return tris; | |
} | |
}; | |
} | |
} | |
void temk() | |
{ | |
using namespace ku::mk; | |
Vec3 v({ 1,2,3 }); | |
std::vector<Tri> tris = { | |
Tri({ Vec3(1.0f, 2.0f, 3.0f), Vec3(2,3,4), Vec3(3,4,2) }), | |
}; | |
MktDelegate::get_tangnts(&tris); | |
} | |
void main() | |
{ | |
te(); | |
getchar(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
mikkt に関してだいたいのインターフェイスは書き終わった。値を渡す処理がまだ。