Skip to content

Commit d55cb8a

Browse files
committed
Some tweaks to HW3D
1 parent 4903c9b commit d55cb8a

1 file changed

Lines changed: 240 additions & 8 deletions

File tree

utilities/olcUTIL_Hardware3D.h

Lines changed: 240 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@
5555
dandistine
5656
5757
Changes:
58-
v1.0: Here we go, 3D stuff but fast! (ish)
58+
v1.00: Here we go, 3D stuff but fast! (ish)
5959
+CreateCube() - Creates a 6-face fully defined cuboid of a set size (with optional offset)
60+
v1.01: +CreateSanityCube() - stops insanity
61+
+Rudimentary Camera
62+
+Made OBJ file loader convert to LH on load
6063
*/
6164

6265

@@ -496,11 +499,11 @@ namespace olc
496499
identity();
497500
auto& me = (*this);
498501
T invFOV = T(1) / tan(fov * T(0.5));
499-
me(0, 0) = ratio * invFOV;
502+
me(0, 0) = -invFOV / ratio;
500503
me(1, 1) = invFOV;
501-
me(2, 2) = farplane / (farplane - nearplane);
502-
me(3, 2) = (-farplane * nearplane) / (farplane - nearplane);
503-
me(2, 3) = T(1);
504+
me(2, 2) = -farplane / (farplane - nearplane);
505+
me(3, 2) = -(farplane * nearplane) / (farplane - nearplane);
506+
me(2, 3) = T(-1);
504507
me(3, 3) = T(0);
505508
}
506509

@@ -675,6 +678,62 @@ namespace olc::utils::hw3d
675678
olc::DecalStructure layout = olc::DecalStructure::LIST;
676679
};
677680

681+
682+
olc::utils::hw3d::mesh CreateSanityCube()
683+
{
684+
olc::utils::hw3d::mesh m;
685+
686+
// South
687+
m.pos.push_back({ 0,0,0 }); m.norm.push_back({ 0, 0, -1, 0 }); m.uv.push_back({ 0.25, 0.5 }); m.col.push_back(olc::WHITE);
688+
m.pos.push_back({ 1,0,0 }); m.norm.push_back({ 0, 0, -1, 0 }); m.uv.push_back({ 0.5, 0.5 }); m.col.push_back(olc::WHITE);
689+
m.pos.push_back({ 1,1,0 }); m.norm.push_back({ 0, 0, -1, 0 }); m.uv.push_back({ 0.5, 0.25 }); m.col.push_back(olc::WHITE);
690+
m.pos.push_back({ 0,0,0 }); m.norm.push_back({ 0, 0, -1, 0 }); m.uv.push_back({ 0.25, 0.5 }); m.col.push_back(olc::WHITE);
691+
m.pos.push_back({ 1,1,0 }); m.norm.push_back({ 0, 0, -1, 0 }); m.uv.push_back({ 0.5, 0.25 }); m.col.push_back(olc::WHITE);
692+
m.pos.push_back({ 0,1,0 }); m.norm.push_back({ 0, 0, -1, 0 }); m.uv.push_back({ 0.25, 0.25 }); m.col.push_back(olc::WHITE);
693+
694+
// East
695+
m.pos.push_back({ 1,0,0 }); m.norm.push_back({ 1, 0, 0, 0 }); m.uv.push_back({ 0.5, 0.5 }); m.col.push_back(olc::WHITE);
696+
m.pos.push_back({ 1,0,1 }); m.norm.push_back({ 1, 0, 0, 0 }); m.uv.push_back({ 0.75, 0.5 }); m.col.push_back(olc::WHITE);
697+
m.pos.push_back({ 1,1,1 }); m.norm.push_back({ 1, 0, 0, 0 }); m.uv.push_back({ 0.75, 0.25 }); m.col.push_back(olc::WHITE);
698+
m.pos.push_back({ 1,0,0 }); m.norm.push_back({ 1, 0, 0, 0 }); m.uv.push_back({ 0.5, 0.5 }); m.col.push_back(olc::WHITE);
699+
m.pos.push_back({ 1,1,1 }); m.norm.push_back({ 1, 0, 0, 0 }); m.uv.push_back({ 0.75, 0.25 }); m.col.push_back(olc::WHITE);
700+
m.pos.push_back({ 1,1,0 }); m.norm.push_back({ 1, 0, 0, 0 }); m.uv.push_back({ 0.5, 0.25 }); m.col.push_back(olc::WHITE);
701+
702+
// North
703+
m.pos.push_back({ 1,0,1 }); m.norm.push_back({ 0, 0, 1, 0 }); m.uv.push_back({ 0.75, 0.5 }); m.col.push_back(olc::WHITE);
704+
m.pos.push_back({ 0,0,1 }); m.norm.push_back({ 0, 0, 1, 0 }); m.uv.push_back({ 1.0, 0.5 }); m.col.push_back(olc::WHITE);
705+
m.pos.push_back({ 0,1,1 }); m.norm.push_back({ 0, 0, 1, 0 }); m.uv.push_back({ 1.0, 0.25 }); m.col.push_back(olc::WHITE);
706+
m.pos.push_back({ 1,0,1 }); m.norm.push_back({ 0, 0, 1, 0 }); m.uv.push_back({ 0.75, 0.5 }); m.col.push_back(olc::WHITE);
707+
m.pos.push_back({ 0,1,1 }); m.norm.push_back({ 0, 0, 1, 0 }); m.uv.push_back({ 1.0, 0.25 }); m.col.push_back(olc::WHITE);
708+
m.pos.push_back({ 1,1,1 }); m.norm.push_back({ 0, 0, 1, 0 }); m.uv.push_back({ 0.75, 0.25 }); m.col.push_back(olc::WHITE);
709+
710+
// West
711+
m.pos.push_back({ 0,0,1 }); m.norm.push_back({ -1, 0, 0, 0 }); m.uv.push_back({ 0.0, 0.5 }); m.col.push_back(olc::WHITE);
712+
m.pos.push_back({ 0,0,0 }); m.norm.push_back({ -1, 0, 0, 0 }); m.uv.push_back({ 0.25, 0.5 }); m.col.push_back(olc::WHITE);
713+
m.pos.push_back({ 0,1,0 }); m.norm.push_back({ -1, 0, 0, 0 }); m.uv.push_back({ 0.25, 0.25 }); m.col.push_back(olc::WHITE);
714+
m.pos.push_back({ 0,0,1 }); m.norm.push_back({ -1, 0, 0, 0 }); m.uv.push_back({ 0.0, 0.5 }); m.col.push_back(olc::WHITE);
715+
m.pos.push_back({ 0,1,0 }); m.norm.push_back({ -1, 0, 0, 0 }); m.uv.push_back({ 0.25, 0.25 }); m.col.push_back(olc::WHITE);
716+
m.pos.push_back({ 0,1,1 }); m.norm.push_back({ -1, 0, 0, 0 }); m.uv.push_back({ 0.0, 0.25 }); m.col.push_back(olc::WHITE);
717+
718+
// Top
719+
m.pos.push_back({ 0,1,0 }); m.norm.push_back({ 0, 1, 0, 0 }); m.uv.push_back({ 0.25, 0.25 }); m.col.push_back(olc::WHITE);
720+
m.pos.push_back({ 1,1,0 }); m.norm.push_back({ 0, 1, 0, 0 }); m.uv.push_back({ 0.5, 0.25 }); m.col.push_back(olc::WHITE);
721+
m.pos.push_back({ 1,1,1 }); m.norm.push_back({ 0, 1, 0, 0 }); m.uv.push_back({ 0.5, 0.0 }); m.col.push_back(olc::WHITE);
722+
m.pos.push_back({ 0,1,0 }); m.norm.push_back({ 0, 1, 0, 0 }); m.uv.push_back({ 0.25, 0.25 }); m.col.push_back(olc::WHITE);
723+
m.pos.push_back({ 1,1,1 }); m.norm.push_back({ 0, 1, 0, 0 }); m.uv.push_back({ 0.5, 0.0 }); m.col.push_back(olc::WHITE);
724+
m.pos.push_back({ 0,1,1 }); m.norm.push_back({ 0, 1, 0, 0 }); m.uv.push_back({ 0.25, 0.0 }); m.col.push_back(olc::WHITE);
725+
726+
// Bottom
727+
m.pos.push_back({ 0,0,1 }); m.norm.push_back({ 0, -1, 0, 0 }); m.uv.push_back({ 0.25, 0.75 }); m.col.push_back(olc::WHITE);
728+
m.pos.push_back({ 1,0,1 }); m.norm.push_back({ 0, -1, 0, 0 }); m.uv.push_back({ 0.5, 0.75 }); m.col.push_back(olc::WHITE);
729+
m.pos.push_back({ 1,0,0 }); m.norm.push_back({ 0, -1, 0, 0 }); m.uv.push_back({ 0.5, 0.5 }); m.col.push_back(olc::WHITE);
730+
m.pos.push_back({ 0,0,1 }); m.norm.push_back({ 0, -1, 0, 0 }); m.uv.push_back({ 0.25, 0.75 }); m.col.push_back(olc::WHITE);
731+
m.pos.push_back({ 1,0,0 }); m.norm.push_back({ 0, -1, 0, 0 }); m.uv.push_back({ 0.5, 0.5 }); m.col.push_back(olc::WHITE);
732+
m.pos.push_back({ 0,0,0 }); m.norm.push_back({ 0, -1, 0, 0 }); m.uv.push_back({ 0.25, 0.5 }); m.col.push_back(olc::WHITE);
733+
734+
return m;
735+
}
736+
678737
olc::utils::hw3d::mesh CreateCube(const olc::vf3d& vSize, const olc::vf3d& vOffset = { 0,0,0 })
679738
{
680739
olc::utils::hw3d::mesh m;
@@ -782,13 +841,13 @@ namespace olc::utils::hw3d
782841
{
783842
// Line is a 3D normal
784843
s >> junk >> junk >> x >> y >> z;
785-
norms.push_back({ x, y, z });
844+
norms.push_back({ -x, y, z });
786845
}
787846
else
788847
{
789848
// Line is a 3D vertex
790849
s >> junk >> x >> y >> z;
791-
verts.push_back({ x, y, z });
850+
verts.push_back({ -x, y, z });
792851
}
793852
}
794853

@@ -829,10 +888,13 @@ namespace olc::utils::hw3d
829888
}
830889

831890
// Process into mesh
832-
for (const auto& face : faces)
891+
for (auto& face : faces)
833892
{
834893
if (face.size() == 3)
835894
{
895+
896+
//std::reverse(face.begin(), face.end());
897+
836898
// Triangle
837899
for (const auto& index : face)
838900
{
@@ -868,4 +930,174 @@ namespace olc::utils::hw3d
868930
return m;
869931
}
870932

933+
934+
935+
class Camera3D
936+
{
937+
public:
938+
Camera3D()
939+
{
940+
vecPosition = &vecLocalPosition;
941+
vecTarget = &vecLocalTarget;
942+
RegenerateProjectionMatrix();
943+
RegenerateViewMatrix();
944+
}
945+
946+
protected:
947+
948+
949+
950+
olc::vf3d* vecPosition = nullptr;
951+
olc::vf3d vecLocalPosition = { 0,0,0 };
952+
olc::vf3d* vecTarget = nullptr;
953+
olc::vf3d vecLocalTarget = { 0,0,1 };
954+
955+
olc::mf4d matView;
956+
olc::vf3d vecViewUp;
957+
olc::vf3d vecViewForward;
958+
olc::vf3d vecViewRight;
959+
960+
olc::mf4d matProjection;
961+
float fProjection_FieldOfView = 3.14159f;
962+
float fProjection_AspectRatio = 1.333333f;
963+
float fProjection_NearPlane = 0.1f;
964+
float fProjection_FarPlane = 1000.0f;
965+
966+
void RegenerateProjectionMatrix()
967+
{
968+
matProjection.projection(
969+
fProjection_FieldOfView,
970+
fProjection_AspectRatio,
971+
fProjection_NearPlane,
972+
fProjection_FarPlane
973+
);
974+
}
975+
976+
void RegenerateViewMatrix()
977+
{
978+
// Reframe Coordinate System
979+
const auto& pos = GetPosition();
980+
vecViewForward = (GetTarget() - pos).norm();
981+
vecViewUp = (olc::vf3d(0.0f, 1.0f, 0.0) - (olc::vf3d(0.0f, 1.0f, 0.0f).dot(vecViewForward) * vecViewForward)).norm();
982+
vecViewRight = vecViewUp.cross(vecViewForward);
983+
984+
// Manual "Point-At" Matrix
985+
matView(0,0) = vecViewRight.x; matView(0,1) = vecViewRight.y; matView(0,2) = vecViewRight.z; matView(0,3) = 0.0f;
986+
matView(1,0) = vecViewUp.x; matView(1,1) = vecViewUp.y; matView(1,2) = vecViewUp.z; matView(1,3) = 0.0f;
987+
matView(2,0) = vecViewForward.x; matView(2,1) = vecViewForward.y; matView(2,2) = vecViewForward.z; matView(2,3) = 0.0f;
988+
matView(3,0) = pos.x; matView(3,1) = pos.y; matView(3,2) = pos.z; matView(3,3) = 1.0f;
989+
990+
//matView(0, 0) = vecViewRight.x; matView(1, 0) = vecViewRight.y; matView(2, 0) = vecViewRight.z; matView(3, 0) = 0.0f;
991+
//matView(0, 1) = vecViewUp.x; matView(1, 1) = vecViewUp.y; matView(2, 1) = vecViewUp.z; matView(3, 1) = 0.0f;
992+
//matView(0, 2) = vecViewForward.x; matView(1, 2) = vecViewForward.y; matView(2, 2) = vecViewForward.z; matView(3, 2) = 0.0f;
993+
//matView(0, 3) = pos.x; matView(1, 3) = pos.y; matView(2, 3) = pos.z; matView(3, 3) = 1.0f;
994+
995+
996+
997+
// "Look-At" Matrix
998+
matView = matView.quickinvert();
999+
}
1000+
1001+
public:
1002+
const olc::mf4d& GetProjectionMatrix() const
1003+
{
1004+
return matProjection;
1005+
}
1006+
1007+
const olc::mf4d& GetViewMatrix() const
1008+
{
1009+
return matView;
1010+
}
1011+
1012+
const olc::vf3d& GetViewUp() const
1013+
{
1014+
return vecViewUp;
1015+
}
1016+
1017+
const olc::vf3d& GetViewRight() const
1018+
{
1019+
return vecViewRight;
1020+
}
1021+
1022+
const olc::vf3d& GetViewForward() const
1023+
{
1024+
return vecViewForward;
1025+
}
1026+
1027+
inline void SetPosition(olc::vf3d& vPosition)
1028+
{
1029+
vecPosition = &vPosition;
1030+
}
1031+
1032+
inline void SetPosition(const olc::vf3d&& vPosition)
1033+
{
1034+
vecLocalPosition = vPosition;
1035+
vecPosition = &vecLocalPosition;
1036+
}
1037+
1038+
inline void SetPosition(const float x, const float y, const float z)
1039+
{
1040+
SetPosition({ x, y, z });
1041+
}
1042+
1043+
const olc::vf3d& GetPosition() const
1044+
{
1045+
return *vecPosition;
1046+
}
1047+
1048+
1049+
inline void SetTarget(olc::vf3d& vTarget)
1050+
{
1051+
vecTarget = &vTarget;
1052+
}
1053+
1054+
inline void SetTarget(const olc::vf3d&& vTarget)
1055+
{
1056+
vecLocalTarget = vTarget;
1057+
vecTarget = &vecLocalTarget;
1058+
}
1059+
1060+
inline void SetTarget(const float x, const float y, const float z)
1061+
{
1062+
SetTarget({ x, y, z });
1063+
}
1064+
1065+
const olc::vf3d& GetTarget() const
1066+
{
1067+
return *vecTarget;
1068+
}
1069+
1070+
void Update()
1071+
{
1072+
RegenerateViewMatrix();
1073+
}
1074+
1075+
1076+
1077+
void SetFieldOfView(const float fTheta)
1078+
{
1079+
fProjection_FieldOfView = fTheta;
1080+
RegenerateProjectionMatrix();
1081+
}
1082+
1083+
void SetAspectRatio(const float fRatio)
1084+
{
1085+
fProjection_AspectRatio = fRatio;
1086+
RegenerateProjectionMatrix();
1087+
}
1088+
1089+
void SetClippingPlanes(const float fNear, const float fFar)
1090+
{
1091+
fProjection_NearPlane = fNear;
1092+
fProjection_FarPlane = fFar;
1093+
RegenerateProjectionMatrix();
1094+
}
1095+
1096+
1097+
1098+
1099+
protected:
1100+
1101+
};
1102+
8711103
}

0 commit comments

Comments
 (0)