Last active
August 29, 2015 14:10
-
-
Save PompiPompi/a7e183a4d1beb7d2bae1 to your computer and use it in GitHub Desktop.
Decal source code from the Fatal Framework
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
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