# It's usually sufficient to change just the target name and source file list\r
# and be sure that CXX is set to a valid compiler\r
TARGET = test\r
-SOURCE_FILES = voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp\r
+SOURCE_FILES = mapnode.cpp tile.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp\r
SOURCES = $(addprefix src/, $(SOURCE_FILES))\r
OBJECTS = $(SOURCES:.cpp=.o)\r
FASTTARGET = fasttest\r
return NULL;
}
-Client::Client(IrrlichtDevice *device, video::SMaterial *materials,
- float delete_unused_sectors_timeout,
+Client::Client(IrrlichtDevice *device,
const char *playername):
m_thread(this),
- m_env(new ClientMap(this, materials,
+ m_env(new ClientMap(this,
device->getSceneManager()->getRootSceneNode(),
device->getSceneManager(), 666),
dout_client),
camera_direction(0,0,1),
m_server_ser_ver(SER_FMT_VER_INVALID),
m_step_dtime(0.0),
- m_delete_unused_sectors_timeout(delete_unused_sectors_timeout),
m_inventory_updated(false)
{
//m_fetchblock_mutex.Init();
JMutexAutoLock lock(m_env_mutex);
core::list<v3s16> deleted_blocks;
+
+ float delete_unused_sectors_timeout =
+ g_settings.getFloat("client_delete_unused_sectors_timeout");
// Delete sector blocks
/*u32 num = m_env.getMap().deleteUnusedSectors
- (m_delete_unused_sectors_timeout,
+ (delete_unused_sectors_timeout,
true, &deleted_blocks);*/
// Delete whole sectors
u32 num = m_env.getMap().deleteUnusedSectors
- (m_delete_unused_sectors_timeout,
+ (delete_unused_sectors_timeout,
false, &deleted_blocks);
if(num > 0)
/*
NOTE: Every public method should be thread-safe
*/
- Client(IrrlichtDevice *device, video::SMaterial *materials,
- float delete_unused_sectors_timeout,
- const char *playername);
+ Client(IrrlichtDevice *device, const char *playername);
~Client();
/*
The name of the local player should already be set when
float m_step_dtime;
JMutex m_step_dtime_mutex;
- float m_delete_unused_sectors_timeout;
-
// This is behind m_env_mutex.
bool m_inventory_updated;
}
video::ITexture * getImage()
{
- return g_materials[m_material].getTexture(0);
+ u16 tile = content_tile(m_material, v3s16(1,0,0));
+ return g_tile_materials[tile].getTexture(0);
}
std::string getText()
{
\r
IrrlichtDevice *g_device = NULL;\r
\r
-const char *g_content_filenames[MATERIALS_COUNT] =\r
+/*const char *g_content_filenames[MATERIALS_COUNT] =\r
{\r
"../data/stone.png",\r
"../data/grass.png",\r
};\r
\r
// Material cache\r
-video::SMaterial g_materials[MATERIALS_COUNT];\r
+video::SMaterial g_materials[MATERIALS_COUNT];*/\r
\r
// Texture cache\r
TextureCache g_texturecache;\r
Initialize material array\r
*/\r
\r
- //video::SMaterial g_materials[MATERIALS_COUNT];\r
+ /*//video::SMaterial g_materials[MATERIALS_COUNT];\r
for(u16 i=0; i<MATERIALS_COUNT; i++)\r
{\r
g_materials[i].Lighting = false;\r
g_materials[CONTENT_WATER].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;\r
//g_materials[CONTENT_WATER].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;\r
g_materials[CONTENT_OCEAN].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;\r
+ */\r
\r
/*g_mesh_materials[0].setTexture(0, driver->getTexture("../data/water.png"));\r
g_mesh_materials[1].setTexture(0, driver->getTexture("../data/grass.png"));\r
g_texturecache.set("torch", driver->getTexture("../data/torch.png"));\r
g_texturecache.set("torch_on_floor", driver->getTexture("../data/torch_on_floor.png"));\r
g_texturecache.set("torch_on_ceiling", driver->getTexture("../data/torch_on_ceiling.png"));\r
+ \r
+ /*\r
+ Load tile textures\r
+ */\r
+ for(s32 i=0; i<TILES_COUNT; i++)\r
+ {\r
+ if(g_tile_texture_names[i] == NULL)\r
+ continue;\r
+ std::string name = g_tile_texture_names[i];\r
+ std::string filename;\r
+ filename += "../data/";\r
+ filename += name;\r
+ filename += ".png";\r
+ g_texturecache.set(name, driver->getTexture(filename.c_str()));\r
+ }\r
+\r
+ tile_materials_preload(g_texturecache);\r
\r
/*\r
Make a scope here for the client so that it gets removed\r
Create client\r
*/\r
\r
- // TODO: Get rid of the g_materials parameter or it's globalness\r
- Client client(device, g_materials,\r
- g_settings.getFloat("client_delete_unused_sectors_timeout"),\r
- playername);\r
+ Client client(device, playername);\r
\r
Address connect_address(0,0,0,0, port);\r
try{\r
/*\r
Create skybox\r
*/\r
- scene::ISceneNode* skybox = smgr->addSkyBoxSceneNode(\r
+ scene::ISceneNode* skybox;\r
+ skybox = smgr->addSkyBoxSceneNode(\r
driver->getTexture("../data/skybox2.png"),\r
driver->getTexture("../data/skybox3.png"),\r
driver->getTexture("../data/skybox1.png"),\r
driver->getTexture("../data/skybox1.png"),\r
driver->getTexture("../data/skybox1.png"),\r
driver->getTexture("../data/skybox1.png"));\r
- /* driver->getTexture("../data/irrlicht2_up.jpg"),\r
- driver->getTexture("../data/irrlicht2_dn.jpg"),\r
- driver->getTexture("../data/irrlicht2_lf.jpg"),\r
- driver->getTexture("../data/irrlicht2_rt.jpg"),\r
- driver->getTexture("../data/irrlicht2_ft.jpg"),\r
- driver->getTexture("../data/irrlicht2_bk.jpg"));*/\r
\r
/*\r
Create the camera node\r
// TODO: Move somewhere else? materials.h?
// This header is only for MATERIALS_COUNT
-#include "mapnode.h"
-extern video::SMaterial g_materials[MATERIALS_COUNT];
+//#include "mapnode.h"
+//extern video::SMaterial g_materials[MATERIALS_COUNT];
#include "utility.h"
extern TextureCache g_texturecache;
sector->setHeightmap(p_in_sector, hm);
//TODO: Make these values configurable
- hm->generateContinued(0.0, 0.0, corners);
+ //hm->generateContinued(0.0, 0.0, corners);
+ hm->generateContinued(0.5, 0.2, corners);
//hm->generateContinued(1.0, 0.2, corners);
//hm->generateContinued(2.0, 0.2, corners);
ClientMap::ClientMap(
Client *client,
- video::SMaterial *materials,
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id
Map(dout_client),
scene::ISceneNode(parent, mgr, id),
m_client(client),
- m_materials(materials),
mesh(NULL)
{
/*m_box = core::aabbox3d<f32>(0,0,0,
sector->deSerialize(is);
}
-void ClientMap::renderMap(video::IVideoDriver* driver,
- video::SMaterial *materials, s32 pass)
+void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
{
//m_dout<<DTIME<<"Rendering map..."<<std::endl;
DSTACK(__FUNCTION_NAME);
void ClientMap::updateMesh()
{
-#if 0
- DSTACK(__FUNCTION_NAME);
- //TODO
- /*
- Check what sectors don't draw anything useful at ground level
- and create a mesh of the rough heightmap at those positions.
- */
-
- m_camera_mutex.Lock();
- v3f camera_position = m_camera_position;
- v3f camera_direction = m_camera_direction;
- m_camera_mutex.Unlock();
-
- v3s16 cam_pos_nodes(
- camera_position.X / BS,
- camera_position.Y / BS,
- camera_position.Z / BS);
-
- v3s16 box_nodes_d = HEIGHTMAP_RANGE_NODES * v3s16(1,1,1);
-
- v3s16 p_nodes_min = cam_pos_nodes - box_nodes_d;
- v3s16 p_nodes_max = cam_pos_nodes + box_nodes_d;
-
- // Take a fair amount as we will be dropping more out later
- v3s16 p_blocks_min(
- p_nodes_min.X / MAP_BLOCKSIZE - 1,
- p_nodes_min.Y / MAP_BLOCKSIZE - 1,
- p_nodes_min.Z / MAP_BLOCKSIZE - 1);
- v3s16 p_blocks_max(
- p_nodes_max.X / MAP_BLOCKSIZE + 1,
- p_nodes_max.Y / MAP_BLOCKSIZE + 1,
- p_nodes_max.Z / MAP_BLOCKSIZE + 1);
-
- /*
- Initialize new mesh
- */
-
- scene::SMesh *mesh_new = new scene::SMesh();
- //scene::IMeshBuffer *buf = NULL;
- scene::SMeshBuffer *buf = NULL;
-
- u8 material_in_use = 0;
-
- /*
- Loop through sectors
- */
-
- for(core::map<v2s16, MapSector*>::Iterator
- si = m_sectors.getIterator();
- si.atEnd() == false; si++)
- {
- MapSector *sector = si.getNode()->getValue();
-
- if(sector->getId() != MAPSECTOR_CLIENT)
- {
- dstream<<"WARNING: Client has a non-client sector"
- <<std::endl;
- continue;
- }
-
- ClientMapSector *cs = (ClientMapSector*)sector;
-
- v2s16 sp = sector->getPos();
-
- if(sp.X < p_blocks_min.X
- || sp.X > p_blocks_max.X
- || sp.Y < p_blocks_min.Z
- || sp.Y > p_blocks_max.Z)
- continue;
-
- /*
- Get some ground level info
- */
-
- s16 a = -5;
-
- s16 cn[4] =
- {
- cs->getCorner(0)+a,
- cs->getCorner(1)+a,
- cs->getCorner(2)+a,
- cs->getCorner(3)+a,
- };
- s16 cn_avg = (cn[0]+cn[1]+cn[2]+cn[3])/4;
- s16 cn_min = 32767;
- s16 cn_max = -32768;
- for(s16 i=0; i<4; i++)
- {
- if(cn[i] < cn_min)
- cn_min = cn[i];
- if(cn[i] > cn_max)
- cn_max = cn[i];
- }
- s16 cn_slope = cn_max - cn_min;
-
- /*
- Generate this part of the heightmap mesh
- */
-
- u8 material;
- if(cn_avg + MAP_BLOCKSIZE/4 <= WATER_LEVEL)
- material = 0;
- else if(cn_slope <= MAP_BLOCKSIZE)
- material = 1;
- else
- material = 2;
-
- if(material != material_in_use || buf == NULL)
- {
- // Try to get a meshbuffer associated with the material
- buf = (scene::SMeshBuffer*)mesh_new->getMeshBuffer
- (g_mesh_materials[material]);
- // If not found, create one
- if(buf == NULL)
- {
- // This is a "Standard MeshBuffer",
- // it's a typedeffed CMeshBuffer<video::S3DVertex>
- buf = new scene::SMeshBuffer();
-
- // Set material
- buf->Material = g_mesh_materials[material];
- // Use VBO
- //buf->setHardwareMappingHint(scene::EHM_STATIC);
- // Add to mesh
- mesh_new->addMeshBuffer(buf);
- // Mesh grabbed it
- buf->drop();
- }
- material_in_use = material;
- }
-
- // Sector side width in floating-point units
- f32 sd = BS * MAP_BLOCKSIZE;
- // Sector position in global floating-point units
- v3f spf = v3f((f32)sp.X, 0, (f32)sp.Y) * sd;
-
- //video::SColor c(255,255,255,255);
- u8 cc = 180;
- video::SColor c(255,cc,cc,cc);
-
- video::S3DVertex vertices[4] =
- {
- video::S3DVertex(spf.X, (f32)BS*cn[0],spf.Z, 0,0,0, c, 0,1),
- video::S3DVertex(spf.X+sd,(f32)BS*cn[1],spf.Z, 0,0,0, c, 1,1),
- video::S3DVertex(spf.X+sd,(f32)BS*cn[2],spf.Z+sd,0,0,0, c, 1,0),
- video::S3DVertex(spf.X, (f32)BS*cn[3],spf.Z+sd,0,0,0, c, 0,0),
- };
- u16 indices[] = {0,1,2,2,3,0};
-
- buf->append(vertices, 4, indices, 6);
- }
-
- // Set VBO on
- //mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
-
- /*
- Replace the mesh
- */
-
- mesh_mutex.Lock();
-
- scene::SMesh *mesh_old = mesh;
-
- //DEBUG
- /*mesh = NULL;
- mesh_new->drop();*/
- mesh = mesh_new;
-
- mesh_mutex.Unlock();
-
- if(mesh_old != NULL)
- {
- /*dstream<<"mesh_old refcount="<<mesh_old->getReferenceCount()
- <<std::endl;
- scene::IMeshBuffer *buf = mesh_new->getMeshBuffer
- (g_materials[CONTENT_GRASS]);
- if(buf != NULL)
- dstream<<"grass buf refcount="<<buf->getReferenceCount()
- <<std::endl;*/
-
- mesh_old->drop();
- }
- else
- {
- dstream<<"WARNING: There was no old master heightmap mesh"<<std::endl;
- }
-#endif
+ //TODO: Remove this
}
void ClientMap::PrintInfo(std::ostream &out)
public:
ClientMap(
Client *client,
- video::SMaterial *materials,
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
- renderMap(driver, m_materials, SceneManager->getSceneNodeRenderPass());
+ renderMap(driver, SceneManager->getSceneNodeRenderPass());
}
virtual const core::aabbox3d<f32>& getBoundingBox() const
return m_box;
}
- void renderMap(video::IVideoDriver* driver,
- video::SMaterial *materials, s32 pass);
+ void renderMap(video::IVideoDriver* driver, s32 pass);
// Update master heightmap mesh
void updateMesh();
private:
Client *m_client;
- video::SMaterial *m_materials;
-
core::aabbox3d<f32> m_box;
// This is the master heightmap mesh
core::vector2d<f32>(0,0));
f->tile = tile;
+ //DEBUG
+ //f->tile = TILE_GRASS;
return f;
}
}
/*
- Gets node material from any place relative to block.
+ Gets node tile from any place relative to block.
Returns CONTENT_IGNORE if doesn't exist or should not be drawn.
*/
-u8 MapBlock::getNodeTile(v3s16 p)
+u16 MapBlock::getNodeTile(v3s16 p, v3s16 face_dir)
{
try{
MapNode n = getNodeParent(p);
- return content_tile(n.d);
+ //return content_tile(n.d);
+ return n.getTile(face_dir);
+ }
+ catch(InvalidPositionException &e)
+ {
+ //return CONTENT_IGNORE;
+ return TILE_NONE;
+ }
+}
+
+u8 MapBlock::getNodeContent(v3s16 p)
+{
+ try{
+ MapNode n = getNodeParent(p);
+
+ return n.d;
}
catch(InvalidPositionException &e)
{
v3s16 p = startpos;
/*
- The light in the air lights the surface is taken from
- the node that is air.
+ Get face light at starting position
*/
u8 light = getFaceLight(p, face_dir);
u16 continuous_tiles_count = 0;
- u8 tile0 = getNodeTile(p);
- u8 tile1 = getNodeTile(p + face_dir);
+ u8 tile0 = getNodeTile(p, face_dir);
+ u8 tile1 = getNodeTile(p + face_dir, -face_dir);
for(u16 j=0; j<length; j++)
{
if(j != length - 1){
p_next = p + translate_dir;
- tile0_next = getNodeTile(p_next);
- tile1_next = getNodeTile(p_next + face_dir);
+ tile0_next = getNodeTile(p_next, face_dir);
+ tile1_next = getNodeTile(p_next + face_dir, -face_dir);
light_next = getFaceLight(p_next, face_dir);
if(tile0_next == tile0
/*
Create a face if there should be one
*/
- u8 mf = face_contents(tile0, tile1);
+ //u8 mf = face_contents(tile0, tile1);
+ // This is hackish
+ u8 content0 = getNodeContent(p);
+ u8 content1 = getNodeContent(p + face_dir);
+ u8 mf = face_contents(content0, content1);
if(mf != 0)
{
/*collector.append(g_materials[f->material], f->vertices, 4,
indices, 6);*/
- collector.append(g_materials[f->tile], f->vertices, 4,
+ /*collector.append(g_materials[f->tile], f->vertices, 4,
+ indices, 6);*/
+ collector.append(g_tile_materials[f->tile], f->vertices, 4,
indices, 6);
}
u8 getFaceLight(v3s16 p, v3s16 face_dir);
- u8 getNodeTile(v3s16 p);
+ u16 getNodeTile(v3s16 p, v3s16 face_dir);
+ u8 getNodeContent(v3s16 p);
/*
startpos:
#include "utility.h"
#include "exceptions.h"
#include "serialization.h"
+#include "tile.h"
// Size of node in rendering units
#define BS 10
enum Content
{
- CONTENT_STONE=0,
-
- CONTENT_GRASS=1,
-
- CONTENT_WATER=2,
-
- CONTENT_LIGHT=3,
-
- CONTENT_TREE=4,
-
- CONTENT_LEAVES=5,
-
- CONTENT_GRASS_FOOTSTEPS=6,
-
- CONTENT_MESE=7,
-
- CONTENT_MUD=8,
-
- CONTENT_OCEAN=9,
+ CONTENT_STONE,
+ CONTENT_GRASS,
+ CONTENT_WATER,
+ CONTENT_LIGHT,
+ CONTENT_TREE,
+ CONTENT_LEAVES,
+ CONTENT_GRASS_FOOTSTEPS,
+ CONTENT_MESE,
+ CONTENT_MUD,
+ CONTENT_OCEAN,
// This is set to the number of the actual values in this enum
USEFUL_CONTENT_COUNT
};
+extern u16 g_content_tiles[USEFUL_CONTENT_COUNT][6];
+
/*
If true, the material allows light propagation and brightness is stored
in param.
return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_OCEAN);
}
-/*
- TODO: Make a mapper class for mapping every side of a content
- to some tile.
- This dumbily maps all sides of content to the tile of the same id.
-*/
-inline u8 content_tile(u8 c)
-{
- if(c == CONTENT_IGNORE || c == CONTENT_LIGHT)
- return CONTENT_AIR;
- return c;
-}
-
/*
Returns true for contents that form the base ground that
follows the main heightmap
return d;
}
+inline u16 content_tile(u8 c, v3s16 dir)
+{
+ if(c == CONTENT_IGNORE || c == CONTENT_AIR
+ || c >= USEFUL_CONTENT_COUNT)
+ return TILE_NONE;
+
+ s32 dir_i = -1;
+
+ if(dir == v3s16(0,1,0))
+ dir_i = 0;
+ else if(dir == v3s16(0,-1,0))
+ dir_i = 1;
+ else if(dir == v3s16(1,0,0))
+ dir_i = 2;
+ else if(dir == v3s16(-1,0,0))
+ dir_i = 3;
+ else if(dir == v3s16(0,0,1))
+ dir_i = 4;
+ else if(dir == v3s16(0,0,-1))
+ dir_i = 5;
+
+ /*if(dir_i == -1)
+ return TILE_NONE;*/
+ assert(dir_i != -1);
+
+ return g_content_tiles[c][dir_i];
+}
+
struct MapNode
{
// Content
param = a_light;
}
+ u16 getTile(v3s16 dir)
+ {
+ return content_tile(d, dir);
+ }
+
/*
These serialization functions are used when informing client
of a single node add
v.print(dstream, VOXELPRINT_WATERPRESSURE);
- s16 highest_y = -32768;
+ //s16 highest_y = -32768;
/*
NOTE: These are commented out because this behaviour is changed
all the time
n.d = 4;
b.setNode(p, n);
assert(b.getNode(p).d == 4);
- assert(b.getNodeTile(p) == 4);
- assert(b.getNodeTile(v3s16(-1,-1,0)) == 5);
+ //TODO: Update to new system
+ /*assert(b.getNodeTile(p) == 4);
+ assert(b.getNodeTile(v3s16(-1,-1,0)) == 5);*/
/*
propagateSunlight()
#ifndef UTILITY_HEADER
#define UTILITY_HEADER
-#include "common_irrlicht.h"
-#include "debug.h"
-#include "strfnd.h"
-#include "exceptions.h"
#include <iostream>
#include <fstream>
#include <string>
#include <jmutex.h>
#include <jmutexautolock.h>
+#include "common_irrlicht.h"
+#include "debug.h"
+#include "strfnd.h"
+#include "exceptions.h"
+
extern const v3s16 g_26dirs[26];
inline void writeU32(u8 *data, u32 i)