<ClInclude Include="stb_dxt.h" />
<ClInclude Include="stb_image.h" />
<ClInclude Include="stb_image_write.h" />
+ <ClInclude Include="studiomdl.hpp" />
<ClInclude Include="tbsp.hpp" />
<ClInclude Include="TextFont.hpp" />
<ClInclude Include="Texture.hpp" />
<ClInclude Include="vpk.hpp">
<Filter>Header Files\valve</Filter>
</ClInclude>
+ <ClInclude Include="studiomdl.hpp">
+ <Filter>Header Files\valve</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
std::cout << "Rendering props\n";
shader_depth.setFloat("write_cover", 1.0f);
for (auto && s_prop : vmf_main.props) {
+ if (vmf_main.modelCache[s_prop.modelID] == NULL) continue; // Skip uncanched / errored models. This shouldn't happen if the vmf references everything normally and all files exist.
+
model = glm::mat4();
- model = glm::translate(model, s_prop.origin);
+ model = glm::translate(model, s_prop.origin); // Position
model = glm::rotate(model, glm::radians(s_prop.rotation.y), glm::vec3(0, 1, 0)); // Yaw
model = glm::rotate(model, glm::radians(s_prop.rotation.x), glm::vec3(0, 0, 1)); // ROOOOOLLLLL
model = glm::rotate(model, -glm::radians(s_prop.rotation.z), glm::vec3(1, 0, 0)); // Pitch
+ model = glm::scale(model, glm::vec3(s_prop.unifromScale)); // Scale
shader_depth.setMatrix("model", model);
vmf_main.modelCache[s_prop.modelID]->Draw();
#ifdef entry_point_testing
-#include "vpk.hpp"
-
-int main()
-{
-
- vpk::index test("D:/SteamLibrary/steamapps/common/Counter-Strike Global Offensive/csgo/pak01_dir.vpk");
-
+#include <glm\glm.hpp>
+#include <glm\gtc\matrix_transform.hpp>
+#include <glm\gtc\type_ptr.hpp>
+int main(){
+
system("PAUSE");
return 0;
{
"editorversion" "400"
"editorbuild" "8075"
- "mapversion" "130"
+ "mapversion" "145"
"formatversion" "100"
"prefab" "0"
}
world
{
"id" "1"
- "mapversion" "130"
+ "mapversion" "145"
"classname" "worldspawn"
"detailmaterial" "detail/detailsprites"
"detailvbsp" "detail.vbsp"
}
}
solid
- {
- "id" "185"
- side
- {
- "id" "597"
- "plane" "(-272 672 96) (-272 800 96) (-144 800 96)"
- "material" "RYAN_DEV/PURE_ORANGE2"
- "uaxis" "[1 0 0 -64] 0.25"
- "vaxis" "[0 -1 0 0] 0.25"
- "rotation" "0"
- "lightmapscale" "16"
- "smoothing_groups" "0"
- }
- side
- {
- "id" "596"
- "plane" "(-272 800 16) (-272 672 16) (-144 672 16)"
- "material" "RYAN_DEV/PURE_ORANGE2"
- "uaxis" "[1 0 0 -64] 0.25"
- "vaxis" "[0 -1 0 0] 0.25"
- "rotation" "0"
- "lightmapscale" "16"
- "smoothing_groups" "0"
- }
- side
- {
- "id" "595"
- "plane" "(-272 672 16) (-272 800 16) (-272 800 96)"
- "material" "RYAN_DEV/PURE_ORANGE2"
- "uaxis" "[0 1 0 0] 0.25"
- "vaxis" "[0 0 -1 0] 0.25"
- "rotation" "0"
- "lightmapscale" "16"
- "smoothing_groups" "0"
- }
- side
- {
- "id" "594"
- "plane" "(-144 800 16) (-144 672 16) (-144 672 96)"
- "material" "RYAN_DEV/PURE_ORANGE2"
- "uaxis" "[0 1 0 0] 0.25"
- "vaxis" "[0 0 -1 0] 0.25"
- "rotation" "0"
- "lightmapscale" "16"
- "smoothing_groups" "0"
- }
- side
- {
- "id" "593"
- "plane" "(-272 800 16) (-144 800 16) (-144 800 96)"
- "material" "RYAN_DEV/PURE_ORANGE2"
- "uaxis" "[1 0 0 -64] 0.25"
- "vaxis" "[0 0 -1 0] 0.25"
- "rotation" "0"
- "lightmapscale" "16"
- "smoothing_groups" "0"
- }
- side
- {
- "id" "592"
- "plane" "(-144 672 16) (-272 672 16) (-272 672 96)"
- "material" "RYAN_DEV/PURE_ORANGE2"
- "uaxis" "[1 0 0 -64] 0.25"
- "vaxis" "[0 0 -1 0] 0.25"
- "rotation" "0"
- "lightmapscale" "16"
- "smoothing_groups" "0"
- }
- editor
- {
- "color" "0 175 108"
- "visgroupid" "16"
- "visgroupshown" "1"
- "visgroupautoshown" "1"
- }
- }
- solid
{
"id" "40"
side
}
}
entity
+{
+ "id" "1185"
+ "classname" "prop_static"
+ "angles" "0 0 0"
+ "fademindist" "-1"
+ "fadescale" "1"
+ "model" "models/props_castle/stonestair.mdl"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "skin" "0"
+ "solid" "6"
+ "uniformscale" "1"
+ "origin" "-560 704 16"
+ editor
+ {
+ "color" "255 255 0"
+ "visgroupid" "14"
+ "visgroupid" "9"
+ "visgroupid" "16"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 0]"
+ }
+}
+entity
{
"id" "681"
"classname" "prop_static"
- "angles" "44.7565 317.939 -61.0452"
+ "angles" "0 0 0"
"fademindist" "-1"
"fadescale" "1"
"model" "models/props/de_nuke/truck_nuke.mdl"
"skin" "0"
"solid" "6"
"uniformscale" "1"
- "origin" "-480 752 0"
+ "origin" "-640 320 0"
editor
{
"color" "255 255 0"
"skin" "0"
"solid" "6"
"uniformscale" "1"
- "origin" "-608 416 16"
+ "origin" "-336 768 16"
editor
{
"color" "255 255 0"
+ "visgroupid" "14"
+ "visgroupid" "9"
"visgroupid" "16"
"visgroupshown" "1"
"visgroupautoshown" "1"
"rendercolor" "255 255 255"
"skin" "0"
"solid" "6"
- "uniformscale" "1"
- "origin" "-272 368 16"
+ "uniformscale" "2"
+ "origin" "-208 240 16"
editor
{
"color" "255 255 0"
}
}
entity
+{
+ "id" "1015"
+ "classname" "prop_static"
+ "angles" "0 0 0"
+ "fademindist" "-1"
+ "fadescale" "1"
+ "model" "models/terri/monaco/vehicles/f1.mdl"
+ "renderamt" "255"
+ "rendercolor" "255 255 255"
+ "skin" "0"
+ "solid" "6"
+ "uniformscale" "1"
+ "origin" "-624 560 16"
+ editor
+ {
+ "color" "255 255 0"
+ "visgroupid" "14"
+ "visgroupid" "9"
+ "visgroupid" "16"
+ "visgroupshown" "1"
+ "visgroupautoshown" "1"
+ "logicalpos" "[0 0]"
+ }
+}
+entity
{
"id" "484"
"classname" "tar_config"
#include <chrono>
+#include <io.h>
+
namespace vmf_parse {
//Pass Vector3
bool Vector3f(std::string str, glm::vec3* vec)
//Process entities list
std::vector<kv::DataBlock> EntitiesList = data.headNode.GetAllByName("entity");
for (auto && block : EntitiesList) {
-
- //if (block.Values["classname"] != "prop_static") continue; //Skip anything else than prop static for now
-
//Check wether origin can be resolved for entity
if ((block.GetFirstByName("solid") == NULL) && (block.Values.count("origin") == 0)) {
std::cout << "Origin could not be resolved for entity with ID " << block.Values["id"]; continue;
ent.ID = (int)::atof(block.Values["id"].c_str());
ent.keyValues = block.Values;
+ //Gather up the visgroups
+ kv::DataBlock* editorValues = block.GetFirstByName("editor");
+ int viscount = -1;
+ while (editorValues->Values.count("visgroupid" + (++viscount > 0 ? std::to_string(viscount) : ""))) {
+ ent.visgroupids.push_back(std::stoi(editorValues->Values["visgroupid" + (viscount > 0 ? std::to_string(viscount) : "")]));
+ }
+
glm::vec3 loc = glm::vec3();
if (block.Values.count("origin")) { //Start with hammer origin
vmf_parse::Vector3f(block.Values["origin"], &loc);
solid.faces.push_back(side);
}
- kv::DataBlock* editorValues = block.GetFirstByName("editor");
-
//Gather up the visgroups
+ //TODO: move this dupe code away from solid processing
+ // add reference to source entity, to provide link to visgroups.
int viscount = -1;
while (editorValues->Values.count("visgroupid" + (++viscount > 0 ? std::to_string(viscount) : ""))) {
solid.visgroupids.push_back(std::stoi(editorValues->Values["visgroupid" + (viscount > 0 ? std::to_string(viscount) : "")]));
return list;
}
- bool testIfInVisgroup(Entity* ent, std::string visgroup)
- {
+ bool testIfInVisgroup(Entity* ent, std::string visgroup){
for (auto && esvid : ent->visgroupids) {
if (this->visgroups[esvid] == visgroup) {
return true;
void populateModelDict(std::string pakDir) {
vpk::index pakIndex(pakDir + "pak01_dir.vpk"); // Open index
+ std::cout << "Populating model dictionary & caching model data...\n";
+
unsigned int mIndex = 0;
for (auto && ent : this->findEntitiesByClassName("prop_static")) {
std::string modelName = kv::tryGetStringValue(ent->keyValues, "model", "error.mdl");
std::string baseName = split(modelName, ".")[0];
if (this->modelDict.count(modelName)) continue; // Skip already defined models
- std::cout << "Processing model: " << modelName << "\n";
-
this->modelDict.insert({ modelName, mIndex++ }); // Add to our list
// Generate our model data and wham it into the model cache
vpk::vEntry* vEntry = pakIndex.find(modelName);
if (vEntry != NULL) {
- std::cout << "Found model in pakfile: " << modelName << "\n";
-
vpk::vEntry* vtx_entry = pakIndex.find(baseName + ".dx90.vtx");
vpk::vEntry* vvd_entry = pakIndex.find(baseName + ".vvd");
if (vtx_entry == NULL || vvd_entry == NULL) {
std::cout << "Couldn't find vtx/vvd model data\n";
+ this->modelCache.push_back(NULL);
continue;
}
// Read vvd
std::string vvdPakDir = pakDir + "pak01_" + sutil::pad0(std::to_string(vvd_entry->entryInfo.ArchiveIndex), 3) + ".vpk";
std::ifstream vvdPakFile(vvdPakDir, std::ios::in | std::ios::binary);
- vvd_data vvd(&vvdPakFile, vvd_entry->entryInfo.EntryOffset, true);
+ vvd_data vvd(&vvdPakFile, vvd_entry->entryInfo.EntryOffset, false);
vvdPakFile.close();
// GENERATE MESH TING
this->modelCache.push_back(m);
}
else {
- std::cout << "Searching for model in gamedir...\n";
+ std::string vtxFile = pakDir + baseName + ".dx90.vtx";
+ std::string vvdFile = pakDir + baseName + ".vvd";
+
+ // Check that custom model data actually exists
+ if (_access_s(vtxFile.c_str(), 0) != 0 || _access_s(vvdFile.c_str(), 0) != 0) {
+ std::cout << "Couldn't find vtx/vvd model data\n";
+ this->modelCache.push_back(NULL);
+ continue;
+ }
+
+ // Read vtx
+ vtx_mesh vtx(vtxFile);
+
+ // Read vvd
+ vvd_data vvd(vvdFile);
+
+ // GENERATE MESH TING
+ std::vector<float> meshData;
+ for (auto && vert : vtx.vertexSequence) {
+ meshData.push_back(vvd.verticesLOD0[vert].m_vecPosition.x);
+ meshData.push_back(vvd.verticesLOD0[vert].m_vecPosition.y);
+ meshData.push_back(vvd.verticesLOD0[vert].m_vecPosition.z);
+ meshData.push_back(0);
+ meshData.push_back(0);
+ meshData.push_back(1);
+ }
+
+ Mesh* m = new Mesh(meshData, MeshMode::POS_XYZ_NORMAL_XYZ);
+ this->modelCache.push_back(m);
}
}
}
void populatePropList(std::string visgroupfilter = "") {
for (auto && prop : this->findEntitiesByClassName("prop_static")) {
- //if (!this->testIfInVisgroup(prop, visgroupfilter)) continue;
+ if (!this->testIfInVisgroup(prop, visgroupfilter)) continue;
std::string modelName = kv::tryGetStringValue(prop->keyValues, "model", "error.mdl");
reader.seekg(MODEL.lodOffset - sizeof(vtx::ModelHeader), std::ios::cur);
int abs_lod_base_offset = reader.tellg();
- for (int lod = 0; lod < MODEL.numLODs; lod++)
- {
+ for (int lod = 0; lod < MODEL.numLODs; lod++){
+ if (lod > 0) goto IL_EXIT; // Skip all the other lods for now
+
//Move to the current LOD header array item
reader.seekg(abs_lod_base_offset);
reader.seekg(lod * sizeof(vtx::ModelLODHeader), std::ios::cur);
}
}
+ IL_EXIT: __noop;
//Dispose stream
reader.close();
}
}
}
}
-
-
}
IL_EXIT: __noop;
}
VVD::Vertex vert;
reader.read((char*)&vert, sizeof(vert));
+ // THIS HURTS
+ // REAL BAD
+ // forgot to copy this... spent 9 hours trying to learning studiomdl.
+ // note to self: dont dupe your code.
+ // Do the sorce->opengl flipperoo
+ glm::vec3 temp = vert.m_vecPosition;
+ vert.m_vecPosition = glm::vec3(-temp.x, temp.z, temp.y);
+
this->verticesLOD0.push_back(vert);
}