forked from Mirrorlandia_minetest/minetest
Fix rendering glitches when far from the center of the map
This commit is contained in:
parent
8e15179e7d
commit
062de11b4c
@ -36,6 +36,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "profiler.h"
|
#include "profiler.h"
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include "util/mathconstants.h"
|
#include "util/mathconstants.h"
|
||||||
|
#include "constants.h"
|
||||||
|
|
||||||
|
#define CAMERA_OFFSET_STEP 200
|
||||||
|
|
||||||
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
|
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
|
||||||
IGameDef *gamedef):
|
IGameDef *gamedef):
|
||||||
@ -53,6 +56,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
|
|||||||
|
|
||||||
m_camera_position(0,0,0),
|
m_camera_position(0,0,0),
|
||||||
m_camera_direction(0,0,0),
|
m_camera_direction(0,0,0),
|
||||||
|
m_camera_offset(0,0,0),
|
||||||
|
|
||||||
m_aspect(1.0),
|
m_aspect(1.0),
|
||||||
m_fov_x(1.0),
|
m_fov_x(1.0),
|
||||||
@ -348,11 +352,19 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
|
|||||||
v3f abs_cam_up;
|
v3f abs_cam_up;
|
||||||
m_headnode->getAbsoluteTransformation().rotateVect(abs_cam_up, rel_cam_up);
|
m_headnode->getAbsoluteTransformation().rotateVect(abs_cam_up, rel_cam_up);
|
||||||
|
|
||||||
|
// Update offset if too far away from the center of the map
|
||||||
|
m_camera_offset.X += CAMERA_OFFSET_STEP*
|
||||||
|
(((s16)(m_camera_position.X/BS) - m_camera_offset.X)/CAMERA_OFFSET_STEP);
|
||||||
|
m_camera_offset.Y += CAMERA_OFFSET_STEP*
|
||||||
|
(((s16)(m_camera_position.Y/BS) - m_camera_offset.Y)/CAMERA_OFFSET_STEP);
|
||||||
|
m_camera_offset.Z += CAMERA_OFFSET_STEP*
|
||||||
|
(((s16)(m_camera_position.Z/BS) - m_camera_offset.Z)/CAMERA_OFFSET_STEP);
|
||||||
|
|
||||||
// Set camera node transformation
|
// Set camera node transformation
|
||||||
m_cameranode->setPosition(m_camera_position);
|
m_cameranode->setPosition(m_camera_position-intToFloat(m_camera_offset, BS));
|
||||||
m_cameranode->setUpVector(abs_cam_up);
|
m_cameranode->setUpVector(abs_cam_up);
|
||||||
// *100.0 helps in large map coordinates
|
// *100.0 helps in large map coordinates
|
||||||
m_cameranode->setTarget(m_camera_position + 100 * m_camera_direction);
|
m_cameranode->setTarget(m_camera_position-intToFloat(m_camera_offset, BS) + 100 * m_camera_direction);
|
||||||
|
|
||||||
// Get FOV setting
|
// Get FOV setting
|
||||||
f32 fov_degrees = g_settings->getFloat("fov");
|
f32 fov_degrees = g_settings->getFloat("fov");
|
||||||
|
@ -79,6 +79,12 @@ public:
|
|||||||
{
|
{
|
||||||
return m_camera_direction;
|
return m_camera_direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the camera offset
|
||||||
|
inline v3s16 getOffset() const
|
||||||
|
{
|
||||||
|
return m_camera_offset;
|
||||||
|
}
|
||||||
|
|
||||||
// Horizontal field of view
|
// Horizontal field of view
|
||||||
inline f32 getFovX() const
|
inline f32 getFovX() const
|
||||||
@ -144,6 +150,8 @@ private:
|
|||||||
v3f m_camera_position;
|
v3f m_camera_position;
|
||||||
// Absolute camera direction
|
// Absolute camera direction
|
||||||
v3f m_camera_direction;
|
v3f m_camera_direction;
|
||||||
|
// Camera offset
|
||||||
|
v3s16 m_camera_offset;
|
||||||
|
|
||||||
// Field of view and aspect ratio stuff
|
// Field of view and aspect ratio stuff
|
||||||
f32 m_aspect;
|
f32 m_aspect;
|
||||||
|
@ -179,7 +179,7 @@ void * MeshUpdateThread::Thread()
|
|||||||
|
|
||||||
ScopeProfiler sp(g_profiler, "Client: Mesh making");
|
ScopeProfiler sp(g_profiler, "Client: Mesh making");
|
||||||
|
|
||||||
MapBlockMesh *mesh_new = new MapBlockMesh(q->data);
|
MapBlockMesh *mesh_new = new MapBlockMesh(q->data, m_camera_offset);
|
||||||
if(mesh_new->getMesh()->getMeshBufferCount() == 0)
|
if(mesh_new->getMesh()->getMeshBufferCount() == 0)
|
||||||
{
|
{
|
||||||
delete mesh_new;
|
delete mesh_new;
|
||||||
|
@ -119,6 +119,8 @@ public:
|
|||||||
MutexedQueue<MeshUpdateResult> m_queue_out;
|
MutexedQueue<MeshUpdateResult> m_queue_out;
|
||||||
|
|
||||||
IGameDef *m_gamedef;
|
IGameDef *m_gamedef;
|
||||||
|
|
||||||
|
v3s16 m_camera_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ClientEventType
|
enum ClientEventType
|
||||||
@ -406,6 +408,8 @@ public:
|
|||||||
// Including blocks at appropriate edges
|
// Including blocks at appropriate edges
|
||||||
void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
|
void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
|
||||||
void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
|
void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
|
||||||
|
|
||||||
|
void updateCameraOffset(v3s16 camera_offset){ m_mesh_update_thread.m_camera_offset = camera_offset; }
|
||||||
|
|
||||||
// Get event from queue. CE_NONE is returned if queue is empty.
|
// Get event from queue. CE_NONE is returned if queue is empty.
|
||||||
ClientEvent getClientEvent();
|
ClientEvent getClientEvent();
|
||||||
|
@ -175,6 +175,7 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
|
|||||||
v3f camera_position = m_camera_position;
|
v3f camera_position = m_camera_position;
|
||||||
v3f camera_direction = m_camera_direction;
|
v3f camera_direction = m_camera_direction;
|
||||||
f32 camera_fov = m_camera_fov;
|
f32 camera_fov = m_camera_fov;
|
||||||
|
v3s16 camera_offset = m_camera_offset;
|
||||||
m_camera_mutex.Unlock();
|
m_camera_mutex.Unlock();
|
||||||
|
|
||||||
// Use a higher fov to accomodate faster camera movements.
|
// Use a higher fov to accomodate faster camera movements.
|
||||||
@ -250,6 +251,9 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
|
|||||||
if not seen on display
|
if not seen on display
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (block->mesh != NULL)
|
||||||
|
block->mesh->updateCameraOffset(m_camera_offset);
|
||||||
|
|
||||||
float range = 100000 * BS;
|
float range = 100000 * BS;
|
||||||
if(m_control.range_all == false)
|
if(m_control.range_all == false)
|
||||||
range = m_control.wanted_range * BS;
|
range = m_control.wanted_range * BS;
|
||||||
|
@ -86,12 +86,13 @@ public:
|
|||||||
ISceneNode::drop();
|
ISceneNode::drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateCamera(v3f pos, v3f dir, f32 fov)
|
void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset)
|
||||||
{
|
{
|
||||||
JMutexAutoLock lock(m_camera_mutex);
|
JMutexAutoLock lock(m_camera_mutex);
|
||||||
m_camera_position = pos;
|
m_camera_position = pos;
|
||||||
m_camera_direction = dir;
|
m_camera_direction = dir;
|
||||||
m_camera_fov = fov;
|
m_camera_fov = fov;
|
||||||
|
m_camera_offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -146,6 +147,7 @@ private:
|
|||||||
v3f m_camera_position;
|
v3f m_camera_position;
|
||||||
v3f m_camera_direction;
|
v3f m_camera_direction;
|
||||||
f32 m_camera_fov;
|
f32 m_camera_fov;
|
||||||
|
v3s16 m_camera_offset;
|
||||||
JMutex m_camera_mutex;
|
JMutex m_camera_mutex;
|
||||||
|
|
||||||
std::map<v3s16, MapBlock*> m_drawlist;
|
std::map<v3s16, MapBlock*> m_drawlist;
|
||||||
|
@ -65,6 +65,7 @@ public:
|
|||||||
virtual bool isLocalPlayer(){return false;}
|
virtual bool isLocalPlayer(){return false;}
|
||||||
virtual void setAttachments(){}
|
virtual void setAttachments(){}
|
||||||
virtual bool doShowSelectionBox(){return true;}
|
virtual bool doShowSelectionBox(){return true;}
|
||||||
|
virtual void updateCameraOffset(v3s16 camera_offset){};
|
||||||
|
|
||||||
// Step object in time
|
// Step object in time
|
||||||
virtual void step(float dtime, ClientEnvironment *env){}
|
virtual void step(float dtime, ClientEnvironment *env){}
|
||||||
|
@ -35,7 +35,8 @@ Clouds::Clouds(
|
|||||||
scene::ISceneNode(parent, mgr, id),
|
scene::ISceneNode(parent, mgr, id),
|
||||||
m_seed(seed),
|
m_seed(seed),
|
||||||
m_camera_pos(0,0),
|
m_camera_pos(0,0),
|
||||||
m_time(0)
|
m_time(0),
|
||||||
|
m_camera_offset(0,0,0)
|
||||||
{
|
{
|
||||||
m_material.setFlag(video::EMF_LIGHTING, false);
|
m_material.setFlag(video::EMF_LIGHTING, false);
|
||||||
//m_material.setFlag(video::EMF_BACK_FACE_CULLING, false);
|
//m_material.setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||||
@ -318,6 +319,7 @@ void Clouds::render()
|
|||||||
}
|
}
|
||||||
|
|
||||||
v3f pos(p0.X, m_cloud_y, p0.Y);
|
v3f pos(p0.X, m_cloud_y, p0.Y);
|
||||||
|
pos -= intToFloat(m_camera_offset, BS);
|
||||||
|
|
||||||
for(u16 i=0; i<4; i++)
|
for(u16 i=0; i<4; i++)
|
||||||
v[i].Pos += pos;
|
v[i].Pos += pos;
|
||||||
|
@ -66,6 +66,11 @@ public:
|
|||||||
void step(float dtime);
|
void step(float dtime);
|
||||||
|
|
||||||
void update(v2f camera_p, video::SColorf color);
|
void update(v2f camera_p, video::SColorf color);
|
||||||
|
|
||||||
|
void updateCameraOffset(v3s16 camera_offset)
|
||||||
|
{
|
||||||
|
m_camera_offset = camera_offset;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
video::SMaterial m_material;
|
video::SMaterial m_material;
|
||||||
@ -76,6 +81,7 @@ private:
|
|||||||
u32 m_seed;
|
u32 m_seed;
|
||||||
v2f m_camera_pos;
|
v2f m_camera_pos;
|
||||||
float m_time;
|
float m_time;
|
||||||
|
v3s16 m_camera_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1058,23 +1058,24 @@ public:
|
|||||||
if(getParent() != NULL)
|
if(getParent() != NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
v3s16 camera_offset = m_env->getCameraOffset();
|
||||||
if(m_meshnode){
|
if(m_meshnode){
|
||||||
m_meshnode->setPosition(pos_translator.vect_show);
|
m_meshnode->setPosition(pos_translator.vect_show-intToFloat(camera_offset, BS));
|
||||||
v3f rot = m_meshnode->getRotation();
|
v3f rot = m_meshnode->getRotation();
|
||||||
rot.Y = -m_yaw;
|
rot.Y = -m_yaw;
|
||||||
m_meshnode->setRotation(rot);
|
m_meshnode->setRotation(rot);
|
||||||
}
|
}
|
||||||
if(m_animated_meshnode){
|
if(m_animated_meshnode){
|
||||||
m_animated_meshnode->setPosition(pos_translator.vect_show);
|
m_animated_meshnode->setPosition(pos_translator.vect_show-intToFloat(camera_offset, BS));
|
||||||
v3f rot = m_animated_meshnode->getRotation();
|
v3f rot = m_animated_meshnode->getRotation();
|
||||||
rot.Y = -m_yaw;
|
rot.Y = -m_yaw;
|
||||||
m_animated_meshnode->setRotation(rot);
|
m_animated_meshnode->setRotation(rot);
|
||||||
}
|
}
|
||||||
if(m_spritenode){
|
if(m_spritenode){
|
||||||
m_spritenode->setPosition(pos_translator.vect_show);
|
m_spritenode->setPosition(pos_translator.vect_show-intToFloat(camera_offset, BS));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void step(float dtime, ClientEnvironment *env)
|
void step(float dtime, ClientEnvironment *env)
|
||||||
{
|
{
|
||||||
if(m_visuals_expired && m_smgr && m_irr){
|
if(m_visuals_expired && m_smgr && m_irr){
|
||||||
|
@ -500,6 +500,10 @@ public:
|
|||||||
{ m_player_names.push_back(name); }
|
{ m_player_names.push_back(name); }
|
||||||
void removePlayerName(std::string name)
|
void removePlayerName(std::string name)
|
||||||
{ m_player_names.remove(name); }
|
{ m_player_names.remove(name); }
|
||||||
|
void updateCameraOffset(v3s16 camera_offset)
|
||||||
|
{ m_camera_offset = camera_offset; }
|
||||||
|
v3s16 getCameraOffset()
|
||||||
|
{ return m_camera_offset; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClientMap *m_map;
|
ClientMap *m_map;
|
||||||
@ -515,6 +519,7 @@ private:
|
|||||||
IntervalLimiter m_drowning_interval;
|
IntervalLimiter m_drowning_interval;
|
||||||
IntervalLimiter m_breathing_interval;
|
IntervalLimiter m_breathing_interval;
|
||||||
std::list<std::string> m_player_names;
|
std::list<std::string> m_player_names;
|
||||||
|
v3s16 m_camera_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
28
src/game.cpp
28
src/game.cpp
@ -228,6 +228,7 @@ PointedThing getPointedThing(Client *client, v3f player_position,
|
|||||||
core::line3d<f32> shootline, f32 d,
|
core::line3d<f32> shootline, f32 d,
|
||||||
bool liquids_pointable,
|
bool liquids_pointable,
|
||||||
bool look_for_object,
|
bool look_for_object,
|
||||||
|
v3s16 camera_offset,
|
||||||
std::vector<aabb3f> &hilightboxes,
|
std::vector<aabb3f> &hilightboxes,
|
||||||
ClientActiveObject *&selected_object)
|
ClientActiveObject *&selected_object)
|
||||||
{
|
{
|
||||||
@ -258,8 +259,8 @@ PointedThing getPointedThing(Client *client, v3f player_position,
|
|||||||
|
|
||||||
v3f pos = selected_object->getPosition();
|
v3f pos = selected_object->getPosition();
|
||||||
hilightboxes.push_back(aabb3f(
|
hilightboxes.push_back(aabb3f(
|
||||||
selection_box->MinEdge + pos,
|
selection_box->MinEdge + pos - intToFloat(camera_offset, BS),
|
||||||
selection_box->MaxEdge + pos));
|
selection_box->MaxEdge + pos - intToFloat(camera_offset, BS)));
|
||||||
}
|
}
|
||||||
|
|
||||||
mindistance = (selected_object->getPosition() - camera_position).getLength();
|
mindistance = (selected_object->getPosition() - camera_position).getLength();
|
||||||
@ -361,8 +362,8 @@ PointedThing getPointedThing(Client *client, v3f player_position,
|
|||||||
i2 != boxes.end(); i2++)
|
i2 != boxes.end(); i2++)
|
||||||
{
|
{
|
||||||
aabb3f box = *i2;
|
aabb3f box = *i2;
|
||||||
box.MinEdge += npf + v3f(-d,-d,-d);
|
box.MinEdge += npf + v3f(-d,-d,-d) - intToFloat(camera_offset, BS);
|
||||||
box.MaxEdge += npf + v3f(d,d,d);
|
box.MaxEdge += npf + v3f(d,d,d) - intToFloat(camera_offset, BS);
|
||||||
hilightboxes.push_back(box);
|
hilightboxes.push_back(box);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2541,6 +2542,8 @@ void the_game(
|
|||||||
Update camera
|
Update camera
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
v3s16 old_camera_offset = camera.getOffset();
|
||||||
|
|
||||||
LocalPlayer* player = client.getEnv().getLocalPlayer();
|
LocalPlayer* player = client.getEnv().getLocalPlayer();
|
||||||
float full_punch_interval = playeritem_toolcap.full_punch_interval;
|
float full_punch_interval = playeritem_toolcap.full_punch_interval;
|
||||||
float tool_reload_ratio = time_from_last_punch / full_punch_interval;
|
float tool_reload_ratio = time_from_last_punch / full_punch_interval;
|
||||||
@ -2554,10 +2557,19 @@ void the_game(
|
|||||||
v3f camera_position = camera.getPosition();
|
v3f camera_position = camera.getPosition();
|
||||||
v3f camera_direction = camera.getDirection();
|
v3f camera_direction = camera.getDirection();
|
||||||
f32 camera_fov = camera.getFovMax();
|
f32 camera_fov = camera.getFovMax();
|
||||||
|
v3s16 camera_offset = camera.getOffset();
|
||||||
|
|
||||||
|
bool camera_offset_changed = (camera_offset != old_camera_offset);
|
||||||
|
|
||||||
if(!disable_camera_update){
|
if(!disable_camera_update){
|
||||||
client.getEnv().getClientMap().updateCamera(camera_position,
|
client.getEnv().getClientMap().updateCamera(camera_position,
|
||||||
camera_direction, camera_fov);
|
camera_direction, camera_fov, camera_offset);
|
||||||
|
if (camera_offset_changed){
|
||||||
|
client.updateCameraOffset(camera_offset);
|
||||||
|
client.getEnv().updateCameraOffset(camera_offset);
|
||||||
|
if (clouds)
|
||||||
|
clouds->updateCameraOffset(camera_offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update sound listener
|
// Update sound listener
|
||||||
@ -2600,6 +2612,7 @@ void the_game(
|
|||||||
&client, player_position, camera_direction,
|
&client, player_position, camera_direction,
|
||||||
camera_position, shootline, d,
|
camera_position, shootline, d,
|
||||||
playeritem_def.liquids_pointable, !ldown_for_dig,
|
playeritem_def.liquids_pointable, !ldown_for_dig,
|
||||||
|
camera_offset,
|
||||||
// output
|
// output
|
||||||
hilightboxes,
|
hilightboxes,
|
||||||
selected_object);
|
selected_object);
|
||||||
@ -3030,7 +3043,7 @@ void the_game(
|
|||||||
Update particles
|
Update particles
|
||||||
*/
|
*/
|
||||||
|
|
||||||
allparticles_step(dtime, client.getEnv());
|
allparticles_step(dtime);
|
||||||
allparticlespawners_step(dtime, client.getEnv());
|
allparticlespawners_step(dtime, client.getEnv());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3249,7 +3262,8 @@ void the_game(
|
|||||||
*/
|
*/
|
||||||
update_draw_list_timer += dtime;
|
update_draw_list_timer += dtime;
|
||||||
if(update_draw_list_timer >= 0.2 ||
|
if(update_draw_list_timer >= 0.2 ||
|
||||||
update_draw_list_last_cam_dir.getDistanceFrom(camera_direction) > 0.2){
|
update_draw_list_last_cam_dir.getDistanceFrom(camera_direction) > 0.2 ||
|
||||||
|
camera_offset_changed){
|
||||||
update_draw_list_timer = 0;
|
update_draw_list_timer = 0;
|
||||||
client.getEnv().getClientMap().updateDrawList(driver);
|
client.getEnv().getClientMap().updateDrawList(driver);
|
||||||
update_draw_list_last_cam_dir = camera_direction;
|
update_draw_list_last_cam_dir = camera_direction;
|
||||||
|
@ -398,7 +398,7 @@ public:
|
|||||||
MeshMakeData mesh_make_data(gamedef);
|
MeshMakeData mesh_make_data(gamedef);
|
||||||
MapNode mesh_make_node(id, param1, 0);
|
MapNode mesh_make_node(id, param1, 0);
|
||||||
mesh_make_data.fillSingleNode(&mesh_make_node);
|
mesh_make_data.fillSingleNode(&mesh_make_node);
|
||||||
MapBlockMesh mapblock_mesh(&mesh_make_data);
|
MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0));
|
||||||
scene::IMesh *node_mesh = mapblock_mesh.getMesh();
|
scene::IMesh *node_mesh = mapblock_mesh.getMesh();
|
||||||
assert(node_mesh);
|
assert(node_mesh);
|
||||||
video::SColor c(255, 255, 255, 255);
|
video::SColor c(255, 255, 255, 255);
|
||||||
|
@ -1030,7 +1030,7 @@ static void updateAllFastFaceRows(MeshMakeData *data,
|
|||||||
MapBlockMesh
|
MapBlockMesh
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MapBlockMesh::MapBlockMesh(MeshMakeData *data):
|
MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
|
||||||
m_mesh(new scene::SMesh()),
|
m_mesh(new scene::SMesh()),
|
||||||
m_gamedef(data->m_gamedef),
|
m_gamedef(data->m_gamedef),
|
||||||
m_animation_force_timer(0), // force initial animation
|
m_animation_force_timer(0), // force initial animation
|
||||||
@ -1248,11 +1248,13 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data):
|
|||||||
&p.indices[0], p.indices.size());
|
&p.indices[0], p.indices.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_camera_offset = camera_offset;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Do some stuff to the mesh
|
Do some stuff to the mesh
|
||||||
*/
|
*/
|
||||||
|
|
||||||
translateMesh(m_mesh, intToFloat(data->m_blockpos * MAP_BLOCKSIZE, BS));
|
translateMesh(m_mesh, intToFloat(data->m_blockpos * MAP_BLOCKSIZE - camera_offset, BS));
|
||||||
|
|
||||||
if(m_mesh)
|
if(m_mesh)
|
||||||
{
|
{
|
||||||
@ -1415,6 +1417,14 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapBlockMesh::updateCameraOffset(v3s16 camera_offset)
|
||||||
|
{
|
||||||
|
if (camera_offset != m_camera_offset) {
|
||||||
|
translateMesh(m_mesh, intToFloat(m_camera_offset-camera_offset, BS));
|
||||||
|
m_camera_offset = camera_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MeshCollector
|
MeshCollector
|
||||||
*/
|
*/
|
||||||
|
@ -81,7 +81,7 @@ class MapBlockMesh
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Builds the mesh given
|
// Builds the mesh given
|
||||||
MapBlockMesh(MeshMakeData *data);
|
MapBlockMesh(MeshMakeData *data, v3s16 camera_offset);
|
||||||
~MapBlockMesh();
|
~MapBlockMesh();
|
||||||
|
|
||||||
// Main animation function, parameters:
|
// Main animation function, parameters:
|
||||||
@ -107,6 +107,8 @@ public:
|
|||||||
if(m_animation_force_timer > 0)
|
if(m_animation_force_timer > 0)
|
||||||
m_animation_force_timer--;
|
m_animation_force_timer--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateCameraOffset(v3s16 camera_offset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
scene::SMesh *m_mesh;
|
scene::SMesh *m_mesh;
|
||||||
@ -133,6 +135,9 @@ private:
|
|||||||
u32 m_last_daynight_ratio;
|
u32 m_last_daynight_ratio;
|
||||||
// For each meshbuffer, maps vertex indices to (day,night) pairs
|
// For each meshbuffer, maps vertex indices to (day,night) pairs
|
||||||
std::map<u32, std::map<u32, std::pair<u8, u8> > > m_daynight_diffs;
|
std::map<u32, std::map<u32, std::pair<u8, u8> > > m_daynight_diffs;
|
||||||
|
|
||||||
|
// Camera offset info -> do we have to translate the mesh?
|
||||||
|
v3s16 m_camera_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ Particle::Particle(
|
|||||||
{
|
{
|
||||||
// Misc
|
// Misc
|
||||||
m_gamedef = gamedef;
|
m_gamedef = gamedef;
|
||||||
|
m_env = &env;
|
||||||
|
|
||||||
// Texture
|
// Texture
|
||||||
m_material.setFlag(video::EMF_LIGHTING, false);
|
m_material.setFlag(video::EMF_LIGHTING, false);
|
||||||
@ -95,7 +96,7 @@ Particle::Particle(
|
|||||||
this->setAutomaticCulling(scene::EAC_OFF);
|
this->setAutomaticCulling(scene::EAC_OFF);
|
||||||
|
|
||||||
// Init lighting
|
// Init lighting
|
||||||
updateLight(env);
|
updateLight();
|
||||||
|
|
||||||
// Init model
|
// Init model
|
||||||
updateVertices();
|
updateVertices();
|
||||||
@ -134,7 +135,7 @@ void Particle::render()
|
|||||||
scene::EPT_TRIANGLES, video::EIT_16BIT);
|
scene::EPT_TRIANGLES, video::EIT_16BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Particle::step(float dtime, ClientEnvironment &env)
|
void Particle::step(float dtime)
|
||||||
{
|
{
|
||||||
m_time += dtime;
|
m_time += dtime;
|
||||||
if (m_collisiondetection)
|
if (m_collisiondetection)
|
||||||
@ -143,7 +144,7 @@ void Particle::step(float dtime, ClientEnvironment &env)
|
|||||||
v3f p_pos = m_pos*BS;
|
v3f p_pos = m_pos*BS;
|
||||||
v3f p_velocity = m_velocity*BS;
|
v3f p_velocity = m_velocity*BS;
|
||||||
v3f p_acceleration = m_acceleration*BS;
|
v3f p_acceleration = m_acceleration*BS;
|
||||||
collisionMoveSimple(&env, m_gamedef,
|
collisionMoveSimple(m_env, m_gamedef,
|
||||||
BS*0.5, box,
|
BS*0.5, box,
|
||||||
0, dtime,
|
0, dtime,
|
||||||
p_pos, p_velocity, p_acceleration);
|
p_pos, p_velocity, p_acceleration);
|
||||||
@ -158,13 +159,13 @@ void Particle::step(float dtime, ClientEnvironment &env)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update lighting
|
// Update lighting
|
||||||
updateLight(env);
|
updateLight();
|
||||||
|
|
||||||
// Update model
|
// Update model
|
||||||
updateVertices();
|
updateVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Particle::updateLight(ClientEnvironment &env)
|
void Particle::updateLight()
|
||||||
{
|
{
|
||||||
u8 light = 0;
|
u8 light = 0;
|
||||||
try{
|
try{
|
||||||
@ -173,11 +174,11 @@ void Particle::updateLight(ClientEnvironment &env)
|
|||||||
floor(m_pos.Y+0.5),
|
floor(m_pos.Y+0.5),
|
||||||
floor(m_pos.Z+0.5)
|
floor(m_pos.Z+0.5)
|
||||||
);
|
);
|
||||||
MapNode n = env.getClientMap().getNode(p);
|
MapNode n = m_env->getClientMap().getNode(p);
|
||||||
light = n.getLightBlend(env.getDayNightRatio(), m_gamedef->ndef());
|
light = n.getLightBlend(m_env->getDayNightRatio(), m_gamedef->ndef());
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e){
|
catch(InvalidPositionException &e){
|
||||||
light = blend_light(env.getDayNightRatio(), LIGHT_SUN, 0);
|
light = blend_light(m_env->getDayNightRatio(), LIGHT_SUN, 0);
|
||||||
}
|
}
|
||||||
m_light = decode_light(light);
|
m_light = decode_light(light);
|
||||||
}
|
}
|
||||||
@ -199,6 +200,7 @@ void Particle::updateVertices()
|
|||||||
m_vertices[3] = video::S3DVertex(-m_size/2,m_size/2,0, 0,0,0,
|
m_vertices[3] = video::S3DVertex(-m_size/2,m_size/2,0, 0,0,0,
|
||||||
c, tx0, ty0);
|
c, tx0, ty0);
|
||||||
|
|
||||||
|
v3s16 camera_offset = m_env->getCameraOffset();
|
||||||
for(u16 i=0; i<4; i++)
|
for(u16 i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
if (m_vertical) {
|
if (m_vertical) {
|
||||||
@ -209,17 +211,16 @@ void Particle::updateVertices()
|
|||||||
m_vertices[i].Pos.rotateXZBy(m_player->getYaw());
|
m_vertices[i].Pos.rotateXZBy(m_player->getYaw());
|
||||||
}
|
}
|
||||||
m_box.addInternalPoint(m_vertices[i].Pos);
|
m_box.addInternalPoint(m_vertices[i].Pos);
|
||||||
m_vertices[i].Pos += m_pos*BS;
|
m_vertices[i].Pos += m_pos*BS - intToFloat(camera_offset, BS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Helpers
|
Helpers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void allparticles_step (float dtime, ClientEnvironment &env)
|
void allparticles_step (float dtime)
|
||||||
{
|
{
|
||||||
for(std::vector<Particle*>::iterator i = all_particles.begin();
|
for(std::vector<Particle*>::iterator i = all_particles.begin();
|
||||||
i != all_particles.end();)
|
i != all_particles.end();)
|
||||||
@ -232,7 +233,7 @@ void allparticles_step (float dtime, ClientEnvironment &env)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(*i)->step(dtime, env);
|
(*i)->step(dtime);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,19 +67,20 @@ class Particle : public scene::ISceneNode
|
|||||||
virtual void OnRegisterSceneNode();
|
virtual void OnRegisterSceneNode();
|
||||||
virtual void render();
|
virtual void render();
|
||||||
|
|
||||||
void step(float dtime, ClientEnvironment &env);
|
void step(float dtime);
|
||||||
|
|
||||||
bool get_expired ()
|
bool get_expired ()
|
||||||
{ return m_expiration < m_time; }
|
{ return m_expiration < m_time; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateLight(ClientEnvironment &env);
|
void updateLight();
|
||||||
void updateVertices();
|
void updateVertices();
|
||||||
|
|
||||||
video::S3DVertex m_vertices[4];
|
video::S3DVertex m_vertices[4];
|
||||||
float m_time;
|
float m_time;
|
||||||
float m_expiration;
|
float m_expiration;
|
||||||
|
|
||||||
|
ClientEnvironment *m_env;
|
||||||
IGameDef *m_gamedef;
|
IGameDef *m_gamedef;
|
||||||
core::aabbox3d<f32> m_box;
|
core::aabbox3d<f32> m_box;
|
||||||
core::aabbox3d<f32> m_collisionbox;
|
core::aabbox3d<f32> m_collisionbox;
|
||||||
@ -94,6 +95,7 @@ private:
|
|||||||
u8 m_light;
|
u8 m_light;
|
||||||
bool m_collisiondetection;
|
bool m_collisiondetection;
|
||||||
bool m_vertical;
|
bool m_vertical;
|
||||||
|
v3s16 m_camera_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ParticleSpawner
|
class ParticleSpawner
|
||||||
@ -144,7 +146,7 @@ class ParticleSpawner
|
|||||||
bool m_vertical;
|
bool m_vertical;
|
||||||
};
|
};
|
||||||
|
|
||||||
void allparticles_step (float dtime, ClientEnvironment &env);
|
void allparticles_step (float dtime);
|
||||||
void allparticlespawners_step (float dtime, ClientEnvironment &env);
|
void allparticlespawners_step (float dtime, ClientEnvironment &env);
|
||||||
|
|
||||||
void delete_particlespawner (u32 id);
|
void delete_particlespawner (u32 id);
|
||||||
|
Loading…
Reference in New Issue
Block a user