Skip to content

Instantly share code, notes, and snippets.

@PompiPompi
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PompiPompi/a7e183a4d1beb7d2bae1 to your computer and use it in GitHub Desktop.
Save PompiPompi/a7e183a4d1beb7d2bae1 to your computer and use it in GitHub Desktop.
Decal source code from the Fatal Framework
class GenerateQuadMeshShader: public Graphics3D::GeometryShader {
public:
GenerateQuadMeshShader(std::vector<math::Triangle> & Triangles, Graphics2D::Position StartLeft, Graphics2D::Position StartRight, Graphics2D::Position EndLeft, Graphics2D::Position EndRight):Triangles(Triangles), StartLeft(StartLeft), StartRight(StartRight), EndLeft(EndLeft), EndRight(EndRight)
{
StartLeft.y = 0;
StartRight.y = 0;
EndLeft.y = 0;
EndRight.y = 0;
}
void Init()
{
}
Graphics3D::GeometryVertex GenerateVertex(unsigned int i, unsigned int n)
{
Graphics3D::GeometryVertex v;
float3 Vertex = Triangles[i/3].Vertex(i%3);
Graphics2D::Position v1(Vertex.x, Vertex.y, Vertex.z);
v.pos.x = v1.x;
v.pos.y = v1.y;
v.pos.z = v1.z;
v1.y = 0;
// double t1;
// double t2 = (v1.x-(StartLeft.x*(1.0-t1)+StartRight.x*t1))/((EndLeft.x*(1.0-t1)+EndRight.x*t1)-(StartLeft.x*(1.0-t1)+StartRight.x*t1));
double a = (StartLeft.x-StartRight.x)*(-EndLeft.z+EndRight.z+StartLeft.z-StartRight.z)-(StartLeft.z-StartRight.z)*(-EndLeft.x+EndRight.x+StartLeft.x-StartRight.x);
double b = (v1.x-StartLeft.x)*(-EndLeft.z+EndRight.z+StartLeft.z-StartRight.z)-(v1.z-StartLeft.z)*(-EndLeft.x+EndRight.x+StartLeft.x-StartRight.x)+(StartLeft.x-StartRight.x)*(EndLeft.z-StartLeft.z)-(StartLeft.z-StartRight.z)*(EndLeft.x-StartLeft.x);
double c = (v1.x-StartLeft.x)*(EndLeft.z-StartLeft.z)-(v1.z-StartLeft.z)*(EndLeft.x-StartLeft.x);
double t1 = 0;
if (fabs(a)<0.000001)
{
t1 = -c/b;
}
else
{
double delta = b*b-4*a*c;
t1 = -b/(2.0*a);
if (delta>0.)
{
t1 = (-b+sqrt(delta))/(2.0*a);
// Fix
double Solution2 = (-b-sqrt(delta))/(2.0*a);
if (fabs(Solution2-0.5)<fabs(t1-0.5))
t1 = Solution2;
//if (t1<0.0)
// t1 = (-b-sqrt(delta))/(2.0*a);
}
}
double x1 = ((EndLeft.x*(1.0-t1)+EndRight.x*t1)-(StartLeft.x*(1.0-t1)+StartRight.x*t1));
double t2 = 0;
if (fabs(x1)<0.0001)
{
double z1 = ((EndLeft.z*(1.0-t1)+EndRight.z*t1)-(StartLeft.z*(1.0-t1)+StartRight.z*t1));
t2 = (v1.z-(StartLeft.z*(1.0-t1)+StartRight.z*t1))/z1;
}
else
t2 = (v1.x-(StartLeft.x*(1.0-t1)+StartRight.x*t1))/x1;
v.u = t1;
v.v = t2;
return v;
}
unsigned int VertexAmount(unsigned int n)
{
return (unsigned int)Triangles.size()*3;
}
unsigned int SurfaceAmount()
{
return 1;
}
std::vector<math::Triangle> & Triangles;
Graphics2D::Position StartLeft, StartRight, EndLeft, EndRight;
};
class DecalMesh {
public:
DecalMesh (Graphics3D::Factory & f, Graphics3D::Mesh m1):Map(m1), f(f)
{
std::vector <Graphics2D::Position> & p1 = m1->GetPosition(0);
std::vector <unsigned int> & i1 = m1->GetIndex(0);
Triangles.resize(i1.size()/3);
for (unsigned int i=0; i<Triangles.size(); i++)
{
unsigned int j = i*3;
Triangles[i] = math::Triangle(float3(p1[i1[j]].x, p1[i1[j]].y, p1[i1[j]].z), float3(p1[i1[j+1]].x, p1[i1[j+1]].y, p1[i1[j+1]].z), float3(p1[i1[j+2]].x, p1[i1[j+2]].y, p1[i1[j+2]].z));
}
DecalMat = f.LoadMaterial(0.0);
DecalMat->SetResource (f.LoadResourceEx ("Resource/DecalSS.png", true));
DecalMat->SetBlend(Graphics3D::BlendMode_Normal);
DecalMat->SetDecal(true);
DecalMat->SetSpecular (f.LoadResourceEx ("Resource/White.IC", true));
DecalMat->SetSpecular(Graphics3D::Float4D(1., 1., 0.8, 8.0));
DecalMat->SetAmbient(Graphics3D::Float4D(1, 1, 1., 0));
DecalMat->SetDiffuse(Graphics3D::Float4D(0, 0, 0, 1));
DecalMat->SetBaked(Graphics3D::BakedType_Color);
}
void AddStripe (Graphics2D::Position StartLeft, Graphics2D::Position StartRight, Graphics2D::Position EndLeft, Graphics2D::Position EndRight)
{
Graphics2D::Position Min = StartLeft;
Graphics2D::Position Max = StartLeft;
Min = PosMin(Min, StartRight);
Max = PosMax(Max, StartRight);
Min = PosMin(Min, EndLeft);
Max = PosMax(Max, EndLeft);
Min = PosMin(Min, EndRight);
Max = PosMax(Max, EndRight);
std::vector<unsigned int> List1 = Map.GetPositionRangeTriangles(Min, Max);
std::vector<math::Triangle> FinalList;
for (unsigned int i=0; i<List1.size(); i++)
{
std::list<math::Triangle> TriangleList;
TriangleList.push_back(Triangles[List1[i]]);
std::vector<Graphics2D::Position> p1;
p1.resize(4);
p1[0] = StartLeft;
p1[1] = EndLeft;
p1[2] = EndRight;
p1[3] = StartRight;
std::vector<math::Plane> Planes;
Planes.resize(p1.size());
for (unsigned int k=0; k<p1.size(); k++)
p1[k].y = 0;
for (unsigned int k=0; k<p1.size(); k++)
{
float3 a3(p1[k].x, p1[k].y, p1[k].z);
Graphics2D::Position q = Graphics2D::Position(0, 1, 0).Cross((p1[(k+1)%p1.size()]-p1[k]).Normalize()).Normalize();
Planes[k] = math::Plane(a3, float3(q.x, q.y, q.z));
}
for (unsigned int j=0; j<Planes.size() && TriangleList.size()>0; j++)
{
std::list<math::Triangle> NextList;
math::Plane Plane1 = Planes[j];
std::list<math::Triangle>::iterator q;
for (q=TriangleList.begin(); q!=TriangleList.end(); q++)
{
math::Triangle t1 = *q;
math::Triangle ResultT1, ResultT2;
float3 Factor1, Factor2;
unsigned int Cycle1 = 0;
unsigned int Type = Plane1.Clip2(t1, ResultT1, ResultT2, Factor1, Factor2, Cycle1);
if (Type==0)
continue;
if (Type==3)
NextList.push_front(*q);
else if (Type==1)
{
NextList.push_front(ResultT1);
} else
{
NextList.push_front(ResultT1);
NextList.push_front(ResultT2);
}
}
TriangleList = NextList;
}
while (!TriangleList.empty())
{
FinalList.push_back(TriangleList.front());
TriangleList.pop_front();
}
}
GenerateQuadMeshShader g(FinalList, StartLeft, StartRight, EndLeft, EndRight);
Graphics3D::Mesh Result = f.GenerateMesh(g);
CurrentMesh = Result;
}
Graphics3D::Mesh CurrentMesh;
Graphics3D::Material DecalMat;
private:
Graphics2D::Position PosMin(Graphics2D::Position p1, Graphics2D::Position p2)
{
Graphics2D::Position Result = p1;
Result.x = std::min(Result.x, p2.x);
Result.y = std::min(Result.y, p2.y);
Result.z = std::min(Result.z, p2.z);
return Result;
}
Graphics2D::Position PosMax(Graphics2D::Position p1, Graphics2D::Position p2)
{
Graphics2D::Position Result = p1;
Result.x = std::max(Result.x, p2.x);
Result.y = std::max(Result.y, p2.y);
Result.z = std::max(Result.z, p2.z);
return Result;
}
SurfaceTriangleMap Map;
std::vector <math::Triangle> Triangles;
Graphics3D::Factory & f;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment