Skip to content

Instantly share code, notes, and snippets.

@kunugibaru
Last active February 4, 2017 17:30
Show Gist options
  • Save kunugibaru/47956b52ef0d0268e51c16ad5f24cb8d to your computer and use it in GitHub Desktop.
Save kunugibaru/47956b52ef0d0268e51c16ad5f24cb8d to your computer and use it in GitHub Desktop.
三角バッファ
#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();
}
@kunugibaru
Copy link
Author

mikkt に関してだいたいのインターフェイスは書き終わった。値を渡す処理がまだ。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment