Merge pull request #18 from devZoGok/imp-12-map-cells

Imp 12 map cells
This commit is contained in:
devZoGok
2023-09-03 06:46:00 +00:00
committed by GitHub
10 changed files with 264 additions and 433 deletions
+2
View File
@@ -276,6 +276,7 @@ namespace battleship{
Map *map = Map::getSingleton();
/*
for(Unit *u : mainPlayer->getSelectedUnits())
if(u->getType() == UnitType::UNDERWATER){
for(int i = 1; i < map->getNumTerrainObjects(); i++){
@@ -289,6 +290,7 @@ namespace battleship{
}
}
}
*/
targets.push_back(Order::Target((it != unitData.end() ? unitData[node] : unit), results[0].pos));
}
+1
View File
@@ -217,6 +217,7 @@ namespace battleship{
listbox = new Listbox(pos, size, lines, maxDisplay, fontPath, closable);
break;
case UNITS:{
string path = GameManager::getSingleton()->getPath();
bool vehicles = guiTable["vehicles"];
int numUnits = SOL_LUA_STATE["numUnits"];
+1 -1
View File
@@ -22,7 +22,7 @@ namespace battleship{
MapEditorAppState::MapEditor *mapEditor = ((MapEditorAppState*)sm->getAppStateByType((int)AppStateType::MAP_EDITOR))->getMapEditor();
Map *map = Map::getSingleton();
Material *mat = map->getTerrainObject(0).node->getMesh(0)->getMaterial();
Material *mat = map->getNodeParent()->getChild(0)->getMesh(0)->getMaterial();
Material::BoolUniform *texturingUniform = (Material::BoolUniform*)mat->getUniform("texturingEnabled");
Texture *landTex = mapEditor->getLandmassTexture(selectedOption);
string texUni = "textures[0]";
+69 -134
View File
@@ -56,104 +56,16 @@ namespace battleship{
}
void Map::loadTerrainObject(int id){
/*
LuaManager *luaManager = LuaManager::getSingleton();
string terrainTable = (id == -1 ? "terrain" : "waterBodies");
vector<Index> baseIndices = (id == -1 ? vector<Index>{Index(terrainTable)} : vector<Index>{Index(terrainTable), Index(id + 1)});
Vector3 pos = Vector3::VEC_ZERO, size = Vector3::VEC_ZERO;
Index terrInd = Index("terrain"),
waterInd = Index("waterBodies"),
idIndex = Index(id + 1),
posInd = Index("pos"),
sizeInd = Index("size"),
xInd = Index("x"),
yInd = Index("y"),
zInd = Index("z"),
nodeInd = Index("nodes");
vector<Index> sizeBaseInd;
if(id == -1){
sizeBaseInd.push_back(terrInd);
}
else{
float x = luaManager->getFloatFromTable(mapTable, vector<Index>{waterInd, idIndex, posInd, xInd});
float y = luaManager->getFloatFromTable(mapTable, vector<Index>{waterInd, idIndex, posInd, yInd});
float z = luaManager->getFloatFromTable(mapTable, vector<Index>{waterInd, idIndex, posInd, zInd});
pos = Vector3(x, y, z);
sizeBaseInd = vector<Index>{waterInd, idIndex};
}
sizeBaseInd.push_back(sizeInd);
vector<Index> indVecX = sizeBaseInd;
vector<Index> indVecY = sizeBaseInd;
vector<Index> indVecZ = sizeBaseInd;
indVecX.push_back(xInd);
indVecY.push_back(yInd);
indVecZ.push_back(zInd);
float x = luaManager->getFloatFromTable(mapTable, indVecX);
float y = luaManager->getFloatFromTable(mapTable, indVecY);
float z = luaManager->getFloatFromTable(mapTable, indVecZ);
size = Vector3(x, y, z);
vector<Index> baseNodeInd = baseIndices;
baseNodeInd.push_back(nodeInd);
vector<Index> ind = baseNodeInd;
ind.push_back(Index("numCells"));
int numCells = luaManager->getIntFromTable(mapTable, ind);
u32 **weights = new u32*[numCells];
Cell *cells = new Cell[numCells];
for(int i = 0; i < numCells; i++){
weights[i] = new u32[numCells];
for(int j = 0; j < numCells; j++){
int wid = i * numCells + j;
ind = baseNodeInd;
ind.push_back(Index("weights"));
ind.push_back(Index(wid + 1));
u32 w = luaManager->getIntFromTable(mapTable, ind);
weights[i][j] = w;
}
ind = baseNodeInd;
ind.push_back(Index("impassible"));
ind.push_back(Index(i + 1));
bool impassible = luaManager->getFloatFromTable(mapTable, ind);
vector<Index> posBaseInd = baseNodeInd;
posBaseInd.push_back(posInd);
posBaseInd.push_back(Index(i + 1));
vector<Index> indVecX = posBaseInd;
vector<Index> indVecY = posBaseInd;
vector<Index> indVecZ = posBaseInd;
indVecX.push_back(xInd);
indVecY.push_back(yInd);
indVecZ.push_back(zInd);
float x = luaManager->getFloatFromTable(mapTable, indVecX);
float y = luaManager->getFloatFromTable(mapTable, indVecY);
float z = luaManager->getFloatFromTable(mapTable, indVecZ);
cells[i] = Cell(Vector3(x, y, z), (id == -1), impassible);
}
Node *node = nullptr;
string texPath = "";
Quad *quad = nullptr;
TerrainObject::Type type;
string basePath = GameManager::getSingleton()->getPath();
string texPath = basePath;
Node *node = nullptr;
sol::state_view SOL_LUA_STATE = generateView();
//TODO remove this quick fix for landmass model loading
if(id == -1){
type = TerrainObject::LANDMASS;
string mapPathSuffix = "Models/Maps/" + mapName + "/";
texPath += mapPathSuffix;
string terrainFile = basePath + mapPathSuffix + luaManager->getStringFromTable(mapTable, vector<Index>{terrInd, Index("model")});
string basePath = GameManager::getSingleton()->getPath() + "Models/Maps/" + mapName + "/";
texPath = basePath + (string)SOL_LUA_STATE[mapTable]["terrain"]["albedo"];
string terrainFile = basePath + (string)SOL_LUA_STATE[mapTable]["terrain"]["model"];
AssetManager::getSingleton()->load(terrainFile);
node = (Model*)((new Model(terrainFile))->getChild(0));
@@ -162,25 +74,21 @@ namespace battleship{
delete par;
}
else{
type = TerrainObject::RECT_WATERBODY;
node = new Node();
quad = new Quad(Vector3(size.x, size.z, 1), true);
node->attachMesh(quad);
sol::table waterBodyTable = SOL_LUA_STATE[mapTable]["waterbodies"][id + 1], posTable = waterBodyTable["pos"];
texPath = GameManager::getSingleton()->getPath() + "Textures/Water/" + (string)waterBodyTable["albedo"];
texPath += "Textures/Water/";
quad = new Quad(Vector3(waterBodyTable["size"]["x"], waterBodyTable["size"]["y"], 1), true);
Vector3 pos = Vector3(posTable["x"], posTable["y"], posTable["z"]);
node = new Node(pos);
node->attachMesh(quad);
}
nodeParent->attachChild(node);
node->setPosition(pos);
terrainNode->attachChild(node);
Material *mat = new Material(Root::getSingleton()->getLibPath() + "texture");
mat->addBoolUniform("texturingEnabled", true);
mat->addBoolUniform("lightingEnabled", false);
ind = baseIndices;
ind.push_back(Index("albedoMap"));
texPath += luaManager->getStringFromTable(mapTable, ind);
string fr[]{texPath};
AssetManager::getSingleton()->load(fr[0]);
Texture *t = new Texture(fr, 1, false);
@@ -191,9 +99,6 @@ namespace battleship{
((Model*)node)->setMaterial(mat);
else
quad->setMaterial(mat);
terrainObjects.push_back(TerrainObject(pos, size, Vector3(cellSize.x, (id == -1 ? 0 : cellSize.y), cellSize.z), type, node, numCells, cells, weights));
*/
}
void Map::loadSpawnPoints(){
@@ -201,12 +106,11 @@ namespace battleship{
int numSpawnPoints = SOL_LUA_STATE[mapTable]["numSpawnPoints"];
for(int i = 0; i < numSpawnPoints; i++){
sol::table posTable = SOL_LUA_STATE[mapTable]["spawnPointInd"][i + 1];
sol::table posTable = SOL_LUA_STATE[mapTable]["spawnPoints"][i + 1];
spawnPoints.push_back(Vector3(posTable["x"], posTable["y"], posTable["z"]));
}
}
//TODO simplify the dubplicatory field extraction statements
void Map::loadPlayers(){
AssetManager *assetManager = AssetManager::getSingleton();
string path = GameManager::getSingleton()->getPath();
@@ -218,7 +122,7 @@ namespace battleship{
string playerInd = "players";
for(int i = 0; i < numPlayers; i++){
int spawnPointId = SOL_LUA_STATE[mapTable]["spawnPointInd"][i + 1][spawnPointId];
//int spawnPointId = SOL_LUA_STATE[mapTable]["spawnPointInd"][i + 1][spawnPointId];
int numUnits = SOL_LUA_STATE[mapTable][playerInd][i + 1]["numUnits"];
players.push_back(new Player(0, 0, 0, spawnPoints[i]));
@@ -240,30 +144,77 @@ namespace battleship{
}
void Map::preprareScene(){
nodeParent = new Node();
Root *root = Root::getSingleton();
root->getRootNode()->attachChild(nodeParent);
Node *rootNode = root->getRootNode();
string libPath = root->getLibPath();
terrainNode = new Node();
rootNode->attachChild(terrainNode);
cellNode = new Node();
cellNode->setVisible(false);
rootNode->attachChild(cellNode);
landCellMat = new Material(libPath + "texture");
landCellMat->addBoolUniform("lightingEnabled", false);
landCellMat->addBoolUniform("texturingEnabled", false);
landCellMat->addVec4Uniform("diffuseColor", Vector4(0, 1, 0, 1));
waterCellMat = new Material(libPath + "texture");
waterCellMat->addBoolUniform("lightingEnabled", false);
waterCellMat->addBoolUniform("texturingEnabled", false);
waterCellMat->addVec4Uniform("diffuseColor", Vector4(0, 0, 1, 1));
Camera *cam = root->getCamera();
cam->setPosition(Vector3(1, 1, 1) * 40);
cam->lookAt(Vector3(-1, -1, -1).norm(), Vector3(-1, 1, -1).norm());
}
void Map::loadCells(){
sol::state_view SOL_LUA_STATE = generateView();
int numCells = SOL_LUA_STATE[mapTable]["numCells"];
sol::table cellsTable = SOL_LUA_STATE[mapTable]["cells"];
for(int i = 0; i < numCells; i++){
sol::table cellTable = cellsTable[i + 1], posTable = cellTable["pos"];
int numEdges = cellTable["numEdges"];
vector<Edge> edges;
for(int j = 0; j < numEdges; j++){
sol::table edgeTable = cellTable["edges"][j + 1];
edges.push_back(Edge(edgeTable["weight"], edgeTable["srcCellId"], edgeTable["destCellId"]));
}
Vector3 cellPos = Vector3(posTable["x"], posTable["y"], posTable["z"]);
Cell::Type cellType = (Cell::Type)cellTable["type"];
Quad *quad = new Quad(Vector3(CELL_SIZE.x, CELL_SIZE.z, 0));
quad->setWireframe(true);
quad->setMaterial(cellType == Cell::Type::LAND ? landCellMat : waterCellMat);
Node *node = new Node(cellPos + Vector3::VEC_J * .1);
node->attachMesh(quad);
cellNode->attachChild(node);
cells.push_back(Cell(cellPos, cellType, edges));
}
}
void Map::load(string mapName, bool empty) {
this->mapName = mapName;
cellSize = Vector3(7, 6, 7);
Pathfinder::getSingleton()->setImpassibleNodeVal(u16(0 - 1));
string path = GameManager::getSingleton()->getPath();
sol::state_view SOL_LUA_STATE = generateView();
preprareScene();
if(!empty){
sol::state_view SOL_LUA_STATE = generateView();
sol::state_view SOL_LUA_STATE = generateView();
SOL_LUA_STATE.script_file(GameManager::getSingleton()->getPath() + "Models/Maps/" + mapName + "/" + mapName + ".lua");
int numWaterbodies = SOL_LUA_STATE[mapTable]["numWaterBodies"];
loadSpawnPoints();
loadPlayers();
loadSkybox();
loadCells();
loadTerrainObject(-1);
for(int i = 0; i < numWaterbodies; i++)
@@ -274,6 +225,7 @@ namespace battleship{
void Map::unload() {}
int Map::getCellId(Vector3 pos, int id){
/*
Vector3 regionSize = terrainObjects[id].size;
Vector3 regionPos = terrainObjects[id].pos;
Vector3 cellSize = terrainObjects[id].cellSize;
@@ -287,24 +239,7 @@ namespace battleship{
int z = fabs(pos.z - initPos.z) / cellSize.z;
return (numCellsX * numCellsZ * y + (numCellsX * z + x));
}
bool Map::isPointWithinTerrainObject(Vector3 p, int id){
bool within;
Vector3 pos = terrainObjects[id].pos, size = terrainObjects[id].size;
if(terrainObjects[id].type == TerrainObject::RECT_WATERBODY)
within = (fabs(pos.x - p.x) < 0.5 * size.x && fabs(pos.z - p.z) < 0.5 * size.z);
else if(terrainObjects[id].type == TerrainObject::ROUND_WATERBODY)
within = Vector2(pos.x, pos.z).getDistanceFrom(Vector2(p.x, p.z)) < size.x;
else
within = true;
return within;
}
void Map::addTerrainObject(TerrainObject obj){
nodeParent->attachChild(obj.node);
terrainObjects.push_back(obj);
*/
return 0;
}
}
+26 -43
View File
@@ -8,50 +8,35 @@
#include <vector.h>
#include <util.h>
namespace gameBase{
class LuaManager;
}
namespace vb01{
class Model;
class Material;
class Node;
}
namespace battleship{
class Player;
struct Cell{
bool land, impassible;
vb01::Vector3 pos;
Cell(){}
Cell(vb01::Vector3 p, bool l, bool i): pos(p), land(l), impassible(i){}
};
struct TerrainObject{
enum Type{LANDMASS, RECT_WATERBODY, ROUND_WATERBODY};
vb01::Vector3 pos, size, cellSize;
Type type;
vb01::Node *node = nullptr;
std::vector<vb01::Node*> cellMarkers;
int numCells;
Cell *cells = nullptr;
vb01::u32 **weights = nullptr;
TerrainObject(){}
TerrainObject(vb01::Vector3 p, vb01::Vector3 s, vb01::Vector3 cs, Type t, vb01::Node *n, int num, Cell *c, vb01::u32 **w) :
pos(p),
size(s),
cellSize(cs),
type(t),
node(n),
numCells(num),
cells(c),
weights(w){}
};
class Map {
public:
struct Cell;
struct Edge{
Edge(vb01::s64 w, vb01::s64 src, vb01::s64 dest) : weight(w), srcCellId(src), destCellId(dest){}
vb01::s64 weight, srcCellId, destCellId;
};
struct Cell{
enum Type{LAND, WATER};
Type type;
vb01::Vector3 pos;
std::vector<Edge> edges;
Cell(){}
Cell(vb01::Vector3 p, Type t, std::vector<Edge> e = std::vector<Edge>{}): pos(p), type(t), edges(e){}
};
static Map* getSingleton();
~Map(){}
void update();
@@ -59,13 +44,9 @@ namespace battleship{
void unload();
int getCellId(vb01::Vector3, int);
bool isPointWithinTerrainObject(vb01::Vector3, int);
void addTerrainObject(TerrainObject);
inline std::string getMapName(){return mapName;}
inline TerrainObject& getTerrainObject(int i){return terrainObjects[i];}
inline int getNumTerrainObjects(){return terrainObjects.size();}
inline vb01::Node* getNodeParent(){return nodeParent;}
inline vb01::Vector3 getCellSize(){return cellSize;}
inline std::vector<TerrainObject>& getTerrainObjects(){return terrainObjects;}
inline vb01::Node* getNodeParent(){return terrainNode;}
inline vb01::Vector3 getCellSize(){return CELL_SIZE;}
inline std::vector<Player*> getPlayers() {return players;}
inline Player* getPlayer(int i){return players[i];}
inline void addPlayer(Player *p){players.push_back(p);}
@@ -75,18 +56,20 @@ namespace battleship{
inline void addSpawnPoint(vb01::Vector3 sp){spawnPoints.push_back(sp);}
private:
std::string mapTable = "map";
vb01::Node *nodeParent = nullptr;
vb01::Node *terrainNode = nullptr, *cellNode = nullptr;
vb01::Material *landCellMat = nullptr, *waterCellMat = nullptr;
std::string mapName;
std::vector<TerrainObject> terrainObjects;
vb01::Vector3 cellSize;
vb01::Vector3 CELL_SIZE = vb01::Vector3(7, 7, 7);
std::vector<vb01::Vector3> spawnPoints;
std::vector<Player*> players;
std::vector<Cell> cells;
Map(){}
void preprareScene();
void loadSpawnPoints();
void loadPlayers();
void loadSkybox();
void loadCells();
void loadTerrainObject(int);
};
}
+146 -236
View File
@@ -21,7 +21,8 @@
#include <listbox.h>
#include <fstream>
#include <map>
#include <filesystem>
#include <filesystem>
#include <tinyxml2.h>
@@ -67,9 +68,9 @@ namespace battleship{
circleRadius = MIN_RADIUS;
}
void MapEditorAppState::MapEditor::toggleSelection(TerrainObject *obj, bool select){
obj->node->getMesh(0)->setWireframe(select);
selectedTerrainObject = (select ? obj : nullptr);
void MapEditorAppState::MapEditor::toggleSelection(Node *terrNode, bool select){
terrNode->getMesh(0)->setWireframe(select);
selectedTerrainNode = (select ? terrNode : nullptr);
}
void MapEditorAppState::MapEditor::castSelectionRay(){
@@ -82,13 +83,13 @@ namespace battleship{
Ray::retrieveCollisions(startPos, (endPos - startPos).norm(), map->getNodeParent(), results);
Ray::sortResults(results);
if(selectedTerrainObject)
toggleSelection(selectedTerrainObject, false);
if(selectedTerrainNode)
toggleSelection(selectedTerrainNode, false);
if(!results.empty()){
for(int i = 0; i < map->getNumTerrainObjects(); i++)
if(map->getTerrainObject(i).node == results[i].mesh->getNode()){
toggleSelection(&map->getTerrainObject(i), true);
for(int i = 0; i < map->getNodeParent()->getNumChildren(); i++)
if(map->getNodeParent()->getChild(i) == results[i].mesh->getNode()){
toggleSelection(map->getNodeParent()->getChild(i), true);
break;
}
}
@@ -109,19 +110,13 @@ namespace battleship{
node->attachMesh(quad);
Map *map = Map::getSingleton();
TerrainObject::Type type = TerrainObject::RECT_WATERBODY;
map->addTerrainObject(TerrainObject(pos, size, Vector3(14, 7, 14), type, node, 0, nullptr, nullptr));
int objId = map->getNumTerrainObjects() - 1;
TerrainObject &obj = map->getTerrainObject(objId);
toggleSelection(&obj, true);
prepareTerrainObjects(objId - 1, 1);
prepareCellMarkers(obj);
Node *terrNodeParent = map->getNodeParent();
terrNodeParent->attachChild(node);
toggleSelection(node, true);
}
void MapEditorAppState::MapEditor::moveTerrainObject(float strength){
Vector3 pos = selectedTerrainObject->node->getPosition();
Vector3 pos = selectedTerrainNode->getPosition();
switch(movementAxis){
case MovementAxis::X_AXIS:
@@ -135,12 +130,11 @@ namespace battleship{
break;
}
selectedTerrainObject->node->setPosition(pos);
selectedTerrainObject->pos = pos;
selectedTerrainNode->setPosition(pos);
}
void MapEditorAppState::MapEditor::pushLandmassVerts(float strength){
Mesh *mesh = map->getTerrainObject(0).node->getMesh(0);
Mesh *mesh = map->getNodeParent()->getChild(0)->getMesh(0);
MeshData meshData = mesh->getMeshBase();
MeshData::Vertex *verts = meshData.vertices;
int numVerts = meshData.numTris * 3;
@@ -169,13 +163,7 @@ namespace battleship{
Node *node = new Node();
node->attachMesh(mesh);
TerrainObject::Type type = TerrainObject::LANDMASS;
Vector3 pos = Vector3::VEC_ZERO, s = Vector3(size.x, 0, size.y);
map->addTerrainObject(TerrainObject(pos, s, Vector3(14, 6, 14), type, node, 0, nullptr, nullptr));
prepareTerrainObjects(0, 1);
prepareCellMarkers(map->getTerrainObject(0));
map->getNodeParent()->attachChild(node);
}
void MapEditorAppState::MapEditor::prepareTextures(string basePath, bool skybox, vector<Texture*> &textures){
@@ -214,7 +202,7 @@ namespace battleship{
}
}
void MapEditorAppState::MapEditor::parseLandmass(){
void MapEditorAppState::MapEditor::generateLandmassXml(){
XMLDocument *doc = new XMLDocument();
char *nodeTagName = "node";
@@ -227,7 +215,7 @@ namespace battleship{
XMLNode *nodeTag = rootTag->InsertEndChild(nodeEl);
XMLElement *meshEl = doc->NewElement("mesh");
MeshData meshData = map->getTerrainObject(0).node->getMesh(0)->getMeshBase();
MeshData meshData = map->getNodeParent()->getChild(0)->getMesh(0)->getMeshBase();
meshEl->SetAttribute("name", "mesh");
meshEl->SetAttribute("num_faces", meshData.numTris);
meshEl->SetAttribute("num_vertex_groups", 0);
@@ -270,175 +258,112 @@ namespace battleship{
doc->SaveFile(name.c_str());
}
void MapEditorAppState::MapEditor::deleteWeights(){
weightsGenerated = false;
}
vector<Map::Cell> MapEditorAppState::MapEditor::generateMapCells(){
Vector3 startPos = -.49 * Vector3(mapSize.x, 0, mapSize.y), cellSize = map->getCellSize();
int numHorCells = int(mapSize.x / cellSize.x);
int numVertCells = int(mapSize.y / cellSize.z);
vector<Map::Cell> cells;
vector<pair<int, float>> waterBodyBedPoints;
Node *terrainNode = map->getNodeParent();
void MapEditorAppState::MapEditor::prepareTerrainObject(u32 **weights, Cell *cells, int cellsByDim[3], float height, bool land){
const int numCells = cellsByDim[0] * cellsByDim[1] * cellsByDim[2];
Vector3 initPos = -.5 * Vector3(mapSize.x, -height, mapSize.y);
Node *landmass = map->getTerrainObject(0).node;
for(int i = 0; i < numCells; i++){
int xId = i % cellsByDim[0];
int yId = int(i / (cellsByDim[0] * cellsByDim[2]));
int zId = (int(i / cellsByDim[0])) % cellsByDim[2];
cells[i].pos = initPos + Vector3(xId * cellLength, -yId * cellDepth, zId * cellWidth);
if(land){
for(int i = 0; i < numVertCells; i++)
for(int j = 0; j < numHorCells; j++){
vector<Ray::CollisionResult> res;
Ray::retrieveCollisions(Vector3(cells[i].pos.x, 100, cells[i].pos.z), -Vector3::VEC_J, landmass, res);
Vector3 rayPos = startPos + Vector3(cellSize.x * j, 100, cellSize.z * i);
Ray::retrieveCollisions(rayPos, -Vector3::VEC_J, terrainNode->getChild(0), res);
Ray::sortResults(res);
if(!res.empty())
cells[i].pos.y = res[0].pos.y;
}
}
if(res.empty()){
Ray::CollisionResult r;
r.pos = Vector3(rayPos.x, 0, rayPos.z);
res.push_back(r);
}
Map::Cell::Type type = Map::Cell::Type::LAND;
Vector3 pos = res[0].pos;
MeshData meshData = landmass->getMesh(0)->getMeshBase();
for(int i = 0; i < numCells; i++){
int waterbodyId = -1;
bool impassible = false;
TerrainObject waterbody;
for(int j = 0; j < 3 * meshData.numTris; j++){
Vector3 point = Vector3(float(meshData.vertices[j].pos.x), float(meshData.vertices[j].pos.y), float(meshData.vertices[j].pos.z));
for(int k = 1; k < map->getNumTerrainObjects(); k++){
TerrainObject wb = map->getTerrainObject(k);
bool diffX = (abs(point.x - wb.pos.x) < .5 * wb.size.x);
bool diffY = (abs(point.y - wb.pos.z) < .5 * wb.size.z);
bool diffZ = (abs(point.z + wb.pos.y) < .5 * wb.size.y);
if(diffX && diffZ){
waterbodyId = k;
break;
for(int k = 1; k < terrainNode->getNumChildren(); k++){
Vector3 waterPos = terrainNode->getChild(k)->getPosition();
Vector3 waterSize = ((Quad*)terrainNode->getChild(k)->getMesh(0))->getSize();
if(fabs(res[0].pos.x - waterPos.x) < .5 * waterSize.x && fabs(res[0].pos.z - waterPos.z) < .5 * waterSize.y){
type = Map::Cell::Type::WATER;
pos.y = waterPos.y;
waterBodyBedPoints.push_back(pair(numVertCells * i + j, res[0].pos.y));
break;
}
}
if(waterbodyId != -1)
waterbody = map->getTerrainObject(waterbodyId);
bool withinX = (abs(point.x - cells[i].pos.x) < 0.5 * cellLength);
bool withinY = (!land ? (abs(point.y - cells[i].pos.y) < 0.5 * cellDepth) : true);
bool withinZ = (abs(point.z - cells[i].pos.z) < 0.5 * cellWidth);
bool pointWithin = (withinX && withinY && withinZ);
if(land && pointWithin && (waterbodyId != -1 && point.y < waterbody.pos.z))
impassible = true;
else if(!land && pointWithin && waterbodyId != -1)
impassible = true;
}
}
for(int i = 0; i < numCells; i++){
int xId = i % cellsByDim[0];
int yId = i / (cellsByDim[0] * cellsByDim[2]);
int zId = (i / cellsByDim[0]) % cellsByDim[2];
for(int j = 0; j < numCells; j++){
bool adjacent = false;
if(xId == 0 && j - i == 1)
adjacent = true;
else if(xId == cellsByDim[0] - 1 && j - i == -1)
adjacent = true;
else if(0 < xId && xId < cellsByDim[0] - 1 && abs(j - i) == 1)
adjacent = true;
if(yId == 0 && j - i == cellsByDim[0] * cellsByDim[2])
adjacent = true;
else if(0 < yId && yId < cellsByDim[1] - 1 && abs(j - i) == cellsByDim[0] * cellsByDim[2])
adjacent = true;
else if(yId == cellsByDim[1] - 1 && j - i == -(cellsByDim[0] * cellsByDim[2]))
adjacent = true;
if(zId == 0 && j - i == cellsByDim[0])
adjacent = true;
else if(zId == cellsByDim[2] - 1 && j - i == -cellsByDim[0])
adjacent = true;
else if(0 < zId && zId < cellsByDim[2] - 1 && abs(j - i) == cellsByDim[0])
adjacent = true;
weights[i][j] = IMPASS_NODE_VAL;
if(i == j)
weights[i][j] = 0;
else if(adjacent)
weights[i][j] = 1;
vector<Map::Edge> edges;
int weight = 1;
bool up = (i > 0), right = (j < numHorCells - 1), down = (i < numVertCells - 1), left = (j > 0);
if(left)
edges.push_back(Map::Edge(weight, numVertCells * i + j, numVertCells * i + j - 1));
if(right)
edges.push_back(Map::Edge(weight, numVertCells * i + j, numVertCells * i + j + 1));
if(up)
edges.push_back(Map::Edge(weight, numVertCells * i + j, numVertCells * (i - 1) + j));
if(down)
edges.push_back(Map::Edge(weight, numVertCells * i + j, numVertCells * (i + 1) + j));
if(up && left)
edges.push_back(Map::Edge(weight, numVertCells * i + j, numVertCells * (i - 1) + j - 1));
if(up && right)
edges.push_back(Map::Edge(weight, numVertCells * i + j, numVertCells * (i - 1) + j + 1));
if(down && left)
edges.push_back(Map::Edge(weight, numVertCells * i + j, numVertCells * (i + 1) + j - 1));
if(down && right)
edges.push_back(Map::Edge(weight, numVertCells * i + j, numVertCells * (i + 1) + j + 1));
cells.push_back(Map::Cell(pos, type, edges));
}
std::map<int, vector<int>> waterCellMap;
int currUnderWaterCellId = cells.size();
int weight = 2;
for(pair<int, float> p : waterBodyBedPoints){
int numUnderWaterCells = (int)((cells[p.first].pos.y - p.second) / cellSize.y);
vector<int> underWaterCellIds;
if(numUnderWaterCells)
cells[p.first].edges.push_back(Map::Edge(weight, p.first, currUnderWaterCellId));
for(int i = 0; i < numUnderWaterCells; i++, currUnderWaterCellId++)
underWaterCellIds.push_back(currUnderWaterCellId);
waterCellMap[p.first] = underWaterCellIds;
}
for(std::map<int, vector<int>>::iterator it = waterCellMap.begin(); it != waterCellMap.end(); ++it){
for(int i = 0; i < waterCellMap[it->first].size(); i++){
vector<Map::Edge> edges = vector<Map::Edge>{Map::Edge(weight, waterCellMap[it->first][i], it->first)};
for(Map::Edge edge : cells[it->first].edges){
if(cells[edge.destCellId].type == Map::Cell::Type::WATER && waterCellMap[edge.destCellId].size() >= i){
edges.push_back(Map::Edge(weight, waterCellMap[it->first][i], waterCellMap[edge.destCellId][i]));
}
}
Vector3 cellPos = cells[it->first].pos - Vector3::VEC_J * cellSize.y * (i + 1);
cells.push_back(Map::Cell(cellPos, Map::Cell::Type::WATER, edges));
}
}
return cells;
}
void MapEditorAppState::MapEditor::prepareTerrainObjects(int startId, int numObjs){
if(numObjs == -1)
numObjs = map->getNumTerrainObjects();
for(int i = startId; i < numObjs; i++){
TerrainObject &obj = map->getTerrainObject(i);
Vector3 size = obj.size;
int cellsByDim[]{
int(size.x / cellLength),
i == 0 ? 1 : int(size.y / cellDepth),
int(size.z / cellWidth)
};
const int numCells = cellsByDim[0] * cellsByDim[1] * cellsByDim[2];
Cell *cells = new Cell[numCells];
u32 **weights = new u32*[numCells];
for(int i = 0; i < numCells; i++)
weights[i] = new u32[numCells];
obj.cells = cells;
obj.numCells = numCells;
obj.weights = weights;
prepareTerrainObject(weights, cells, cellsByDim, (i > 0 ? obj.pos.y : 0), i == 0);
}
}
string MapEditorAppState::MapEditor::parseTerrainObject(TerrainObject &terrObj){
string terrObjStr = "{\n";
if(terrObj.type = TerrainObject::LANDMASS)
terrObjStr += "model = \"" + map->getMapName() + ".xml\",\n";
terrObjStr += "albedoMap = \"" + map->getMapName() + ".jpg\",\n";
terrObjStr += "size = {x = " + to_string(terrObj.pos.x) + ", y = " + to_string(terrObj.pos.y) + ", z = " + to_string(terrObj.pos.z) + "},\n";
terrObjStr += "nodes = {\n";
terrObjStr += "numCells = " + to_string(terrObj.numCells) + ",\n";
terrObjStr += "size = {x = " + to_string(cellLength) + ", y = " + to_string(cellDepth) + ", z = " + to_string(cellWidth) + "},\n";
terrObjStr += "pos = {\n";
for(int i = 0; i < terrObj.numCells; i++)
terrObjStr += "{x = " + to_string(terrObj.cells[i].pos.x) + ", y = " + to_string(terrObj.cells[i].pos.y) + ", z = " + to_string(terrObj.cells[i].pos.z) + "},\n";
terrObjStr += "},\nimpassible = {\n";
for(int i = 0; i < terrObj.numCells; i++){
terrObjStr += (terrObj.cells[i].impassible ? "true" : "false");
terrObjStr += ",\n";
}
terrObjStr += "},\nweights = {\n";
for(int i = 0; i < terrObj.numCells; i++)
for(int j = 0; j < terrObj.numCells; j++)
terrObjStr += to_string(terrObj.weights[i][j]) + ", ";
terrObjStr += "}\n}\n},\n";
return terrObjStr;
}
void MapEditorAppState::MapEditor::parseMapScript(){
int numTerrObjs = map->getNumTerrainObjects();
string mapScript = "map = {\nnumWaterBodies = " + to_string(numTerrObjs) + ",\n";
void MapEditorAppState::MapEditor::generateMapScript(){
int numWaterBodies = map->getNodeParent()->getNumChildren() - 1;
string mapScript = "map = {\nnumWaterBodies = " + to_string(numWaterBodies) + ",\n";
mapScript += "impassibleNodeValue = " + to_string(IMPASS_NODE_VAL) + ",\n";
mapScript += "numPlayers = " + to_string(map->getNumPlayers()) + ",\n";
@@ -454,7 +379,7 @@ namespace battleship{
mapScript += "},\nplayers = {\n";
for(int i = 0; i < map->getNumPlayers(); i++){
mapScript += "spawnPoint = 0,\n";
mapScript += "{\nspawnPoint = 0,\n";
int numUnits = map->getPlayer(i)->getNumberOfUnits();
mapScript += "numUnits = " + to_string(numUnits) + ",\n";
@@ -477,8 +402,23 @@ namespace battleship{
}
mapScript += "}\n,";
mapScript += "}";
}
mapScript += "}\n";
}
vector<Map::Cell> cells = generateMapCells();
mapScript += "},\nnumCells = " + to_string(cells.size()) + ",\n";
mapScript += "cells = {\n";
for(Map::Cell cell : cells){
Vector3 p = cell.pos;
mapScript += "{type = " + to_string((int)cell.type) + ", pos = {x = " + to_string(p.x) + ", y = " + to_string(p.y) + ", z = " + to_string(p.z) + "}, numEdges = " + to_string(cell.edges.size()) + ", edges = {";
for(Map::Edge edge : cell.edges)
mapScript += "{srcCellId = " + to_string(edge.srcCellId) + ", destCellId = " + to_string(edge.destCellId) + ", weight = " + to_string(edge.weight) + "}, ";
mapScript += "}\n},\n";
}
mapScript += "},\n";
@@ -497,11 +437,17 @@ namespace battleship{
}
mapScript += "skybox = \"" + skyboxPath + "\",\n";
mapScript += "terrain = " + parseTerrainObject(map->getTerrainObject(0));
mapScript += "waterbodies = {";
mapScript += "terrain = {model = \"" + map->getMapName() + ".xml\", albedo = \"" + map->getMapName() + ".jpg\"},\n";
mapScript += "waterbodies = {\n";
for(int i = 1; i < numTerrObjs; i++)
mapScript += parseTerrainObject(map->getTerrainObject(i));
for(int i = 0; i < numWaterBodies; i++){
Node *waterNode = map->getNodeParent()->getChild(i + 1);
Vector3 pos = waterNode->getPosition();
Vector3 size = ((Quad*)waterNode->getMesh(0))->getSize();
mapScript +=
"{pos = {x = " + to_string(pos.x) + ", y = " + to_string(pos.y) + ", z = " + to_string(pos.z) + "},\
size = {x = " + to_string(size.x) + ", y = " + to_string(size.y) + "}, albedo = \"water.jpg\"},";
}
mapScript += "}\n}";
@@ -512,44 +458,14 @@ namespace battleship{
outFile.close();
}
void MapEditorAppState::MapEditor::toggleCellMarkers(){
cellMarkersVisible = !cellMarkersVisible;
for(TerrainObject &obj : map->getTerrainObjects())
for(Node *cellMarker : obj.cellMarkers)
cellMarker->setVisible(cellMarkersVisible);
}
void MapEditorAppState::MapEditor::prepareCellMarkers(TerrainObject &obj){
Root *root = Root::getSingleton();
Node *rootNode = root->getRootNode();
for(int i = 0; i < obj.numCells; i++){
Material *mat = new Material(root->getLibPath() + "texture");
mat->addBoolUniform("lightingEnabled", false);
mat->addBoolUniform("texturingEnabled", false);
mat->addVec4Uniform("diffuseColor", Vector4(0, 0, 1, 1));
Box *box = new Box(Vector3(1, 3, 1));
box->setMaterial(mat);
Node *cellMarker = new Node(obj.cells[i].pos);
cellMarker->attachMesh(box);
cellMarker->setVisible(cellMarkersVisible);
rootNode->attachChild(cellMarker);
obj.cellMarkers.push_back(cellMarker);
}
}
void MapEditorAppState::MapEditor::exportMap(){
string assetsPath = GameManager::getSingleton()->getPath();
string mapFolder = assetsPath + "Models/Maps/" + map->getMapName() + "/";
create_directory(mapFolder);
copy_file(DEFAULT_TEXTURE, mapFolder + map->getMapName() + ".jpg");
copy_file(assetsPath + DEFAULT_TEXTURE, mapFolder + map->getMapName() + ".jpg");
prepareTerrainObjects();
parseLandmass();
parseMapScript();
generateLandmassXml();
generateMapScript();
}
MapEditorAppState::MapEditorAppState(string name, Vector2 size, bool newMap) : AbstractAppState(
@@ -635,7 +551,7 @@ namespace battleship{
Vector3 endPos = screenToSpace(cursorPos);
vector<Ray::CollisionResult> results;
Ray::retrieveCollisions(startPos, (endPos - startPos).norm(), Map::getSingleton()->getTerrainObject(0).node, results);
Ray::retrieveCollisions(startPos, (endPos - startPos).norm(), Root::getSingleton()->getRootNode(), results);
Ray::sortResults(results);
@@ -672,12 +588,6 @@ namespace battleship{
mapEditor->setMovementAxis(axis);
}
break;
case Bind::GENERATE_WEIGHTS:
mapEditor->prepareTerrainObjects();
break;
case Bind::TOGGLE_CELL_MARKERS:
if(isPressed) mapEditor->toggleCellMarkers();
break;
}
}
@@ -704,7 +614,7 @@ namespace battleship{
case Bind::PUSH_VERTS_UP:
case Bind::PUSH_VERTS_DOWN:
if(mapEditor->isPushing()) mapEditor->pushLandmassVerts(strength);
else if(mapEditor->isMovingTerrainObject() && mapEditor->getSelectedTerrainObject() != &Map::getSingleton()->getTerrainObject(0))
else if(mapEditor->isMovingTerrainObject() && mapEditor->getSelectedNode() != Map::getSingleton()->getNodeParent()->getChild(0))
mapEditor->moveTerrainObject(strength);
break;
+7 -11
View File
@@ -18,7 +18,6 @@ namespace vb01{
namespace battleship{
class MapEditor;
class TerrainObject;
class MapEditorAppState : public gameBase::AbstractAppState{
public:
@@ -38,8 +37,7 @@ namespace battleship{
void moveTerrainObject(float);
void exportMap();
void prepareTerrainObjects(int = 0, int = -1);
void toggleCellMarkers();
inline TerrainObject* getSelectedTerrainObject(){return selectedTerrainObject;}
inline vb01::Node* getSelectedNode(){return selectedTerrainNode;}
inline float getGuiThreshold(){return guiThreshold;}
inline float getCircleRadius(){return circleRadius;}
inline bool isPushing(){return pushing;}
@@ -55,16 +53,14 @@ namespace battleship{
private:
void generatePlane(vb01::Vector2);
void prepareTextures(std::string, bool, std::vector<vb01::Texture*>&);
void toggleSelection(TerrainObject*, bool);
void parseLandmass();
std::string parseTerrainObject(TerrainObject&);
void parseMapScript();
void deleteWeights();
void prepareTerrainObject(vb01::u32**, Cell*, int[3], float, bool);
void prepareCellMarkers(TerrainObject&);
void toggleSelection(vb01::Node*, bool);
std::vector<Map::Cell> generateMapCells();
void generateLandmassXml();
void generateMapScript();
void prepareTerrainObject(vb01::u32**, Map::Cell*, int[3], float, bool);
Map *map;
TerrainObject *selectedTerrainObject = nullptr;
vb01::Node *selectedTerrainNode = nullptr;
MovementAxis movementAxis = X_AXIS;
vb01Gui::Listbox *skyListbox = nullptr;
bool pushing = false, movingTerrainObject = false, weightsGenerated = false, newMap, cellMarkersVisible = false;
+2 -4
View File
@@ -13,16 +13,14 @@ namespace battleship{
this->spawnPoint = spawnPoint;
this->id = id;
sol::state_view SOL_LUA_STATE = generateView();
SOL_LUA_STATE.script("players[" + to_string(id + 1) + "] = Player:new({id = " + to_string(id + 1) + "})");
//SOL_LUA_STATE.script("players[" + to_string(id + 1) + "] = Player:new({id = " + to_string(id + 1) + "})");
}
Player::~Player() {
}
void Player::update() {
sol::state_view SOL_LUA_STATE = generateView();
SOL_LUA_STATE.script("players[" + to_string(id + 1) + "]:update()");
//SOL_LUA_STATE.script("players[" + to_string(id + 1) + "]:update()");
for(Unit *u : units)
u->update();
+4 -4
View File
@@ -43,7 +43,7 @@ namespace battleship{
//TODO implement terrain evenness check
void UnitFrameController::update(){
Map *map = Map::getSingleton();
MeshData meshData = map->getTerrainObject(0).node->getMesh(0)->getMeshBase();
MeshData meshData = map->getNodeParent()->getChild(0)->getMesh(0)->getMeshBase();
MeshData::Vertex *verts = meshData.vertices;
int numVerts = 3 * meshData.numTris;
@@ -56,7 +56,7 @@ namespace battleship{
for(UnitFrame &s : unitFrames){
vector<Ray::CollisionResult> results;
Ray::retrieveCollisions(startPos, (endPos - startPos).norm(), map->getTerrainObject(0).node, results);
Ray::retrieveCollisions(startPos, (endPos - startPos).norm(), map->getNodeParent()->getChild(0), results);
Ray::sortResults(results);
if(!results.empty()){
@@ -64,8 +64,8 @@ namespace battleship{
s.model->setPosition(results[0].pos);
sol::table unitTable = SOL_LUA_STATE["unitCornerPoints"][s.id + 1];
float width = (int)unitTable[1]["x"] - (int)unitTable[2]["x"];
float length = (int)unitTable[4]["z"] - (int)unitTable[1]["z"];
float width = (float)unitTable[1]["x"] - (float)unitTable[2]["x"];
float length = (float)unitTable[4]["z"] - (float)unitTable[1]["z"];
float unevenness = 0;
+6
View File
@@ -108,6 +108,7 @@ namespace battleship{
}
void Vehicle::alignToSurface(){
/*
Map *map = Map::getSingleton();
TerrainObject terr = map->getTerrainObject(0);
vector<Ray::CollisionResult> res;
@@ -122,6 +123,7 @@ namespace battleship{
Quaternion rotQuat = Quaternion(angle, axis);
orientUnit(rotQuat * rot);
}
*/
}
void Vehicle::move(Order order) {
@@ -138,6 +140,7 @@ namespace battleship{
int srcObjId = 0, destObjId = 0;
Map *map = Map::getSingleton();
/*
for(int i = 1; i < map->getNumTerrainObjects(); i++){
if(map->isPointWithinTerrainObject(pos, i))
srcObjId = i;
@@ -145,6 +148,7 @@ namespace battleship{
if(map->isPointWithinTerrainObject(order.targets[0].pos, i))
destObjId = i;
}
*/
if(srcObjId != destObjId)
return;
@@ -152,6 +156,7 @@ namespace battleship{
int source = map->getCellId(pos, srcObjId);
int dest = map->getCellId(order.targets[0].pos, destObjId);
/*
Pathfinder *pathfinder = Pathfinder::getSingleton();
u32 **weights = map->getTerrainObject(srcObjId).weights;
vector<int> path = pathfinder->findPath(weights, map->getTerrainObject(srcObjId).numCells, source, dest);
@@ -166,5 +171,6 @@ namespace battleship{
if(!(impassibleNodePresent || path.empty()))
for(int p : path)
pathPoints.push_back(map->getTerrainObject(srcObjId).cells[p].pos);
*/
}
}