mirror of
https://github.com/minetest/minetest.git
synced 2024-12-24 23:22:24 +01:00
Added sprite extruder
This commit is contained in:
parent
4ed837bcfa
commit
36bcbca9ac
349
src/camera.cpp
349
src/camera.cpp
@ -63,6 +63,8 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
|
|||||||
m_headnode = smgr->addEmptySceneNode(m_playernode);
|
m_headnode = smgr->addEmptySceneNode(m_playernode);
|
||||||
m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode());
|
m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode());
|
||||||
m_cameranode->bindTargetAndRotation(true);
|
m_cameranode->bindTargetAndRotation(true);
|
||||||
|
m_wieldnode = new ExtrudedSpriteSceneNode(smgr->getRootSceneNode(), smgr, -1, v3f(0, 120, 10), v3f(0, 0, 0), v3f(100, 100, 100));
|
||||||
|
//m_wieldnode = new ExtrudedSpriteSceneNode(smgr->getRootSceneNode(), smgr, -1);
|
||||||
|
|
||||||
updateSettings();
|
updateSettings();
|
||||||
}
|
}
|
||||||
@ -341,3 +343,350 @@ void Camera::updateSettings()
|
|||||||
m_wanted_frametime = 1.0 / wanted_fps;
|
m_wanted_frametime = 1.0 / wanted_fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Camera::wield(InventoryItem* item)
|
||||||
|
{
|
||||||
|
if (item != NULL)
|
||||||
|
{
|
||||||
|
dstream << "wield item: " << item->getName() << std::endl;
|
||||||
|
m_wieldnode->setSprite(item->getImageRaw());
|
||||||
|
m_wieldnode->setVisible(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dstream << "wield item: none" << std::endl;
|
||||||
|
m_wieldnode->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::setDigging(bool digging)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExtrudedSpriteSceneNode::ExtrudedSpriteSceneNode(
|
||||||
|
scene::ISceneNode* parent,
|
||||||
|
scene::ISceneManager* mgr,
|
||||||
|
s32 id,
|
||||||
|
const v3f& position,
|
||||||
|
const v3f& rotation,
|
||||||
|
const v3f& scale
|
||||||
|
):
|
||||||
|
ISceneNode(parent, mgr, id, position, rotation, scale)
|
||||||
|
{
|
||||||
|
m_meshnode = mgr->addMeshSceneNode(NULL, this, -1, v3f(0,0,0), v3f(0,0,0), v3f(1,1,1), true);
|
||||||
|
m_thickness = 0.1;
|
||||||
|
m_cubemesh = NULL;
|
||||||
|
m_is_cube = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtrudedSpriteSceneNode::~ExtrudedSpriteSceneNode()
|
||||||
|
{
|
||||||
|
removeChild(m_meshnode);
|
||||||
|
if (m_cubemesh)
|
||||||
|
m_cubemesh->drop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture)
|
||||||
|
{
|
||||||
|
if (texture == NULL)
|
||||||
|
{
|
||||||
|
m_meshnode->setVisible(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
io::path name = getExtrudedName(texture);
|
||||||
|
scene::IMeshCache* cache = SceneManager->getMeshCache();
|
||||||
|
scene::IAnimatedMesh* mesh = cache->getMeshByName(name);
|
||||||
|
if (mesh != NULL)
|
||||||
|
{
|
||||||
|
// Extruded texture has been found in cache.
|
||||||
|
m_meshnode->setMesh(mesh);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Texture was not yet extruded, do it now and save in cache
|
||||||
|
mesh = extrude(texture);
|
||||||
|
if (mesh == NULL)
|
||||||
|
{
|
||||||
|
dstream << "Warning: failed to extrude sprite" << std::endl;
|
||||||
|
m_meshnode->setVisible(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cache->addMesh(name, mesh);
|
||||||
|
m_meshnode->setMesh(mesh);
|
||||||
|
mesh->drop();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_meshnode->setScale(v3f(1, 1, m_thickness));
|
||||||
|
m_meshnode->getMaterial(0).setTexture(0, texture);
|
||||||
|
m_meshnode->getMaterial(0).setFlag(video::EMF_LIGHTING, false);
|
||||||
|
m_meshnode->getMaterial(0).setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
|
m_meshnode->getMaterial(0).MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||||
|
m_meshnode->setVisible(true);
|
||||||
|
m_is_cube = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtrudedSpriteSceneNode::setCube(video::ITexture* texture)
|
||||||
|
{
|
||||||
|
if (texture == NULL)
|
||||||
|
{
|
||||||
|
m_meshnode->setVisible(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_cubemesh == NULL)
|
||||||
|
m_cubemesh = SceneManager->getGeometryCreator()->createCubeMesh(v3f(1));
|
||||||
|
|
||||||
|
m_meshnode->setMesh(m_cubemesh);
|
||||||
|
m_meshnode->setScale(v3f(1));
|
||||||
|
m_meshnode->getMaterial(0).setTexture(0, texture);
|
||||||
|
m_meshnode->getMaterial(0).setFlag(video::EMF_LIGHTING, false);
|
||||||
|
m_meshnode->getMaterial(0).setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
|
m_meshnode->getMaterial(0).MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||||
|
m_meshnode->setVisible(true);
|
||||||
|
m_is_cube = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtrudedSpriteSceneNode::removeSpriteFromCache(video::ITexture* texture)
|
||||||
|
{
|
||||||
|
scene::IMeshCache* cache = SceneManager->getMeshCache();
|
||||||
|
scene::IAnimatedMesh* mesh = cache->getMeshByName(getExtrudedName(texture));
|
||||||
|
if (mesh != NULL)
|
||||||
|
cache->removeMesh(mesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtrudedSpriteSceneNode::setSpriteThickness(f32 thickness)
|
||||||
|
{
|
||||||
|
m_thickness = thickness;
|
||||||
|
if (!m_is_cube)
|
||||||
|
m_meshnode->setScale(v3f(1, 1, thickness));
|
||||||
|
}
|
||||||
|
|
||||||
|
const core::aabbox3d<f32>& ExtrudedSpriteSceneNode::getBoundingBox() const
|
||||||
|
{
|
||||||
|
return m_meshnode->getBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtrudedSpriteSceneNode::OnRegisterSceneNode()
|
||||||
|
{
|
||||||
|
if (IsVisible)
|
||||||
|
SceneManager->registerNodeForRendering(this);
|
||||||
|
ISceneNode::OnRegisterSceneNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtrudedSpriteSceneNode::render()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
io::path ExtrudedSpriteSceneNode::getExtrudedName(video::ITexture* texture)
|
||||||
|
{
|
||||||
|
io::path path = texture->getName();
|
||||||
|
path.append("/[extruded]");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height, u8* data)
|
||||||
|
{
|
||||||
|
const s32 argb_wstep = 4 * width;
|
||||||
|
const s32 alpha_threshold = 1;
|
||||||
|
|
||||||
|
scene::IMeshBuffer* buf = new scene::SMeshBuffer();
|
||||||
|
video::SColor c(255,255,255,255);
|
||||||
|
|
||||||
|
// Front and back
|
||||||
|
{
|
||||||
|
video::S3DVertex vertices[8] =
|
||||||
|
{
|
||||||
|
video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1),
|
||||||
|
video::S3DVertex(-0.5,0.5,-0.5, 0,0,-1, c, 0,0),
|
||||||
|
video::S3DVertex(0.5,0.5,-0.5, 0,0,-1, c, 1,0),
|
||||||
|
video::S3DVertex(0.5,-0.5,-0.5, 0,0,-1, c, 1,1),
|
||||||
|
video::S3DVertex(0.5,-0.5,0.5, 0,0,1, c, 1,1),
|
||||||
|
video::S3DVertex(0.5,0.5,0.5, 0,0,1, c, 1,0),
|
||||||
|
video::S3DVertex(-0.5,0.5,0.5, 0,0,1, c, 0,0),
|
||||||
|
video::S3DVertex(-0.5,-0.5,0.5, 0,0,1, c, 0,1),
|
||||||
|
};
|
||||||
|
u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
|
||||||
|
buf->append(vertices, 8, indices, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Interior"
|
||||||
|
// (add faces where a solid pixel is next to a transparent one)
|
||||||
|
u8* solidity = new u8[(width+2) * (height+2)];
|
||||||
|
u32 wstep = width + 2;
|
||||||
|
for (u32 y = 0; y < height + 2; ++y)
|
||||||
|
{
|
||||||
|
u8* scanline = solidity + y * wstep;
|
||||||
|
if (y == 0 || y == height + 1)
|
||||||
|
{
|
||||||
|
for (u32 x = 0; x < width + 2; ++x)
|
||||||
|
scanline[x] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scanline[0] = 0;
|
||||||
|
u8* argb_scanline = data + (y - 1) * argb_wstep;
|
||||||
|
for (u32 x = 0; x < width; ++x)
|
||||||
|
scanline[x+1] = (argb_scanline[x*4+3] >= alpha_threshold);
|
||||||
|
scanline[width + 1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// without this, there would be occasional "holes" in the mesh
|
||||||
|
f32 eps = 0.01;
|
||||||
|
|
||||||
|
for (u32 y = 0; y <= height; ++y)
|
||||||
|
{
|
||||||
|
u8* scanline = solidity + y * wstep + 1;
|
||||||
|
for (u32 x = 0; x <= width; ++x)
|
||||||
|
{
|
||||||
|
if (scanline[x] && !scanline[x + wstep])
|
||||||
|
{
|
||||||
|
u32 xx = x + 1;
|
||||||
|
while (scanline[xx] && !scanline[xx + wstep])
|
||||||
|
++xx;
|
||||||
|
f32 vx1 = (x - eps) / (f32) width - 0.5;
|
||||||
|
f32 vx2 = (xx + eps) / (f32) width - 0.5;
|
||||||
|
f32 vy = 0.5 - (y - eps) / (f32) height;
|
||||||
|
f32 tx1 = x / (f32) width;
|
||||||
|
f32 tx2 = xx / (f32) width;
|
||||||
|
f32 ty = (y - 0.5) / (f32) height;
|
||||||
|
video::S3DVertex vertices[8] =
|
||||||
|
{
|
||||||
|
video::S3DVertex(vx1,vy,-0.5, 0,-1,0, c, tx1,ty),
|
||||||
|
video::S3DVertex(vx2,vy,-0.5, 0,-1,0, c, tx2,ty),
|
||||||
|
video::S3DVertex(vx2,vy,0.5, 0,-1,0, c, tx2,ty),
|
||||||
|
video::S3DVertex(vx1,vy,0.5, 0,-1,0, c, tx1,ty),
|
||||||
|
};
|
||||||
|
u16 indices[6] = {0,1,2,2,3,0};
|
||||||
|
buf->append(vertices, 4, indices, 6);
|
||||||
|
x = xx - 1;
|
||||||
|
}
|
||||||
|
if (!scanline[x] && scanline[x + wstep])
|
||||||
|
{
|
||||||
|
u32 xx = x + 1;
|
||||||
|
while (!scanline[xx] && scanline[xx + wstep])
|
||||||
|
++xx;
|
||||||
|
f32 vx1 = (x - eps) / (f32) width - 0.5;
|
||||||
|
f32 vx2 = (xx + eps) / (f32) width - 0.5;
|
||||||
|
f32 vy = 0.5 - (y + eps) / (f32) height;
|
||||||
|
f32 tx1 = x / (f32) width;
|
||||||
|
f32 tx2 = xx / (f32) width;
|
||||||
|
f32 ty = (y + 0.5) / (f32) height;
|
||||||
|
video::S3DVertex vertices[8] =
|
||||||
|
{
|
||||||
|
video::S3DVertex(vx1,vy,-0.5, 0,1,0, c, tx1,ty),
|
||||||
|
video::S3DVertex(vx1,vy,0.5, 0,1,0, c, tx1,ty),
|
||||||
|
video::S3DVertex(vx2,vy,0.5, 0,1,0, c, tx2,ty),
|
||||||
|
video::S3DVertex(vx2,vy,-0.5, 0,1,0, c, tx2,ty),
|
||||||
|
};
|
||||||
|
u16 indices[6] = {0,1,2,2,3,0};
|
||||||
|
buf->append(vertices, 4, indices, 6);
|
||||||
|
x = xx - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 x = 0; x <= width; ++x)
|
||||||
|
{
|
||||||
|
u8* scancol = solidity + x + wstep;
|
||||||
|
for (u32 y = 0; y <= height; ++y)
|
||||||
|
{
|
||||||
|
if (scancol[y * wstep] && !scancol[y * wstep + 1])
|
||||||
|
{
|
||||||
|
u32 yy = y + 1;
|
||||||
|
while (scancol[yy * wstep] && !scancol[yy * wstep + 1])
|
||||||
|
++yy;
|
||||||
|
f32 vx = (x - eps) / (f32) width - 0.5;
|
||||||
|
f32 vy1 = 0.5 - (y - eps) / (f32) height;
|
||||||
|
f32 vy2 = 0.5 - (yy + eps) / (f32) height;
|
||||||
|
f32 tx = (x - 0.5) / (f32) width;
|
||||||
|
f32 ty1 = y / (f32) height;
|
||||||
|
f32 ty2 = yy / (f32) height;
|
||||||
|
video::S3DVertex vertices[8] =
|
||||||
|
{
|
||||||
|
video::S3DVertex(vx,vy1,-0.5, 1,0,0, c, tx,ty1),
|
||||||
|
video::S3DVertex(vx,vy1,0.5, 1,0,0, c, tx,ty1),
|
||||||
|
video::S3DVertex(vx,vy2,0.5, 1,0,0, c, tx,ty2),
|
||||||
|
video::S3DVertex(vx,vy2,-0.5, 1,0,0, c, tx,ty2),
|
||||||
|
};
|
||||||
|
u16 indices[6] = {0,1,2,2,3,0};
|
||||||
|
buf->append(vertices, 4, indices, 6);
|
||||||
|
y = yy - 1;
|
||||||
|
}
|
||||||
|
if (!scancol[y * wstep] && scancol[y * wstep + 1])
|
||||||
|
{
|
||||||
|
u32 yy = y + 1;
|
||||||
|
while (!scancol[yy * wstep] && scancol[yy * wstep + 1])
|
||||||
|
++yy;
|
||||||
|
f32 vx = (x + eps) / (f32) width - 0.5;
|
||||||
|
f32 vy1 = 0.5 - (y - eps) / (f32) height;
|
||||||
|
f32 vy2 = 0.5 - (yy + eps) / (f32) height;
|
||||||
|
f32 tx = (x + 0.5) / (f32) width;
|
||||||
|
f32 ty1 = y / (f32) height;
|
||||||
|
f32 ty2 = yy / (f32) height;
|
||||||
|
video::S3DVertex vertices[8] =
|
||||||
|
{
|
||||||
|
video::S3DVertex(vx,vy1,-0.5, -1,0,0, c, tx,ty1),
|
||||||
|
video::S3DVertex(vx,vy2,-0.5, -1,0,0, c, tx,ty2),
|
||||||
|
video::S3DVertex(vx,vy2,0.5, -1,0,0, c, tx,ty2),
|
||||||
|
video::S3DVertex(vx,vy1,0.5, -1,0,0, c, tx,ty1),
|
||||||
|
};
|
||||||
|
u16 indices[6] = {0,1,2,2,3,0};
|
||||||
|
buf->append(vertices, 4, indices, 6);
|
||||||
|
y = yy - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to mesh
|
||||||
|
scene::SMesh* mesh = new scene::SMesh();
|
||||||
|
mesh->addMeshBuffer(buf);
|
||||||
|
buf->drop();
|
||||||
|
mesh->recalculateBoundingBox();
|
||||||
|
scene::SAnimatedMesh* anim_mesh = new scene::SAnimatedMesh(mesh);
|
||||||
|
mesh->drop();
|
||||||
|
return anim_mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrude(video::ITexture* texture)
|
||||||
|
{
|
||||||
|
scene::IAnimatedMesh* mesh = NULL;
|
||||||
|
core::dimension2d<u32> size = texture->getSize();
|
||||||
|
video::ECOLOR_FORMAT format = texture->getColorFormat();
|
||||||
|
if (format == video::ECF_A8R8G8B8)
|
||||||
|
{
|
||||||
|
// Texture is in the correct color format, we can pass it
|
||||||
|
// to extrudeARGB right away.
|
||||||
|
void* data = texture->lock(true);
|
||||||
|
if (data == NULL)
|
||||||
|
return NULL;
|
||||||
|
mesh = extrudeARGB(size.Width, size.Height, (u8*) data);
|
||||||
|
texture->unlock();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||||
|
|
||||||
|
video::IImage* img1 = driver->createImageFromData(format, size, texture->lock(true));
|
||||||
|
if (img1 == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// img1 is in the texture's color format, convert to 8-bit ARGB
|
||||||
|
video::IImage* img2 = driver->createImage(video::ECF_A8R8G8B8, size);
|
||||||
|
if (img2 != NULL)
|
||||||
|
{
|
||||||
|
img1->copyTo(img2);
|
||||||
|
img1->drop();
|
||||||
|
|
||||||
|
mesh = extrudeARGB(size.Width, size.Height, (u8*) img2->lock());
|
||||||
|
img2->unlock();
|
||||||
|
img2->drop();
|
||||||
|
}
|
||||||
|
img1->drop();
|
||||||
|
}
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
66
src/camera.h
66
src/camera.h
@ -21,14 +21,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define CAMERA_HEADER
|
#define CAMERA_HEADER
|
||||||
|
|
||||||
#include "common_irrlicht.h"
|
#include "common_irrlicht.h"
|
||||||
|
#include "inventory.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
|
||||||
class LocalPlayer;
|
class LocalPlayer;
|
||||||
class MapDrawControl;
|
class MapDrawControl;
|
||||||
|
class ExtrudedSpriteSceneNode;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Client camera class, manages the player and camera scene nodes, the viewing distance
|
Client camera class, manages the player and camera scene nodes, the viewing distance
|
||||||
and performs view bobbing etc.
|
and performs view bobbing etc. It also displays the wielded tool in front of the
|
||||||
|
first-person camera.
|
||||||
*/
|
*/
|
||||||
class Camera
|
class Camera
|
||||||
{
|
{
|
||||||
@ -59,6 +62,12 @@ public:
|
|||||||
return m_cameranode;
|
return m_cameranode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get wielded item scene node.
|
||||||
|
inline ExtrudedSpriteSceneNode* getWieldNode() const
|
||||||
|
{
|
||||||
|
return m_wieldnode;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the camera position (in absolute scene coordinates).
|
// Get the camera position (in absolute scene coordinates).
|
||||||
// This has view bobbing applied.
|
// This has view bobbing applied.
|
||||||
inline v3f getPosition() const
|
inline v3f getPosition() const
|
||||||
@ -107,12 +116,19 @@ public:
|
|||||||
// Update settings from g_settings
|
// Update settings from g_settings
|
||||||
void updateSettings();
|
void updateSettings();
|
||||||
|
|
||||||
|
// Replace the wielded item mesh
|
||||||
|
void wield(InventoryItem* item);
|
||||||
|
|
||||||
|
// Start or stop digging animation
|
||||||
|
void setDigging(bool digging);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Scene manager and nodes
|
// Scene manager and nodes
|
||||||
scene::ISceneManager* m_smgr;
|
scene::ISceneManager* m_smgr;
|
||||||
scene::ISceneNode* m_playernode;
|
scene::ISceneNode* m_playernode;
|
||||||
scene::ISceneNode* m_headnode;
|
scene::ISceneNode* m_headnode;
|
||||||
scene::ICameraSceneNode* m_cameranode;
|
scene::ICameraSceneNode* m_cameranode;
|
||||||
|
ExtrudedSpriteSceneNode* m_wieldnode;
|
||||||
|
|
||||||
// draw control
|
// draw control
|
||||||
MapDrawControl& m_draw_control;
|
MapDrawControl& m_draw_control;
|
||||||
@ -151,5 +167,51 @@ private:
|
|||||||
f32 m_view_bobbing_speed;
|
f32 m_view_bobbing_speed;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
A scene node that displays a 2D mesh extruded into the third dimension,
|
||||||
|
to add an illusion of depth.
|
||||||
|
|
||||||
|
Since this class was created to display the wielded tool of the local
|
||||||
|
player, and only tools and items are rendered like this (but not solid
|
||||||
|
content like stone and mud, which are shown as cubes), the option to
|
||||||
|
draw a textured cube instead is provided.
|
||||||
|
*/
|
||||||
|
class ExtrudedSpriteSceneNode: public scene::ISceneNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExtrudedSpriteSceneNode(
|
||||||
|
scene::ISceneNode* parent,
|
||||||
|
scene::ISceneManager* mgr,
|
||||||
|
s32 id = -1,
|
||||||
|
const v3f& position = v3f(0,0,0),
|
||||||
|
const v3f& rotation = v3f(0,0,0),
|
||||||
|
const v3f& scale = v3f(0,0,0));
|
||||||
|
~ExtrudedSpriteSceneNode();
|
||||||
|
|
||||||
|
void setSprite(video::ITexture* texture);
|
||||||
|
void setCube(const TileSpec faces[6]);
|
||||||
|
|
||||||
|
f32 getSpriteThickness() const { return m_thickness; }
|
||||||
|
void setSpriteThickness(f32 thickness);
|
||||||
|
|
||||||
|
void removeSpriteFromCache(video::ITexture* texture);
|
||||||
|
|
||||||
|
virtual const core::aabbox3d<f32>& getBoundingBox() const;
|
||||||
|
virtual void OnRegisterSceneNode();
|
||||||
|
virtual void render();
|
||||||
|
|
||||||
|
private:
|
||||||
|
scene::IMeshSceneNode* m_meshnode;
|
||||||
|
f32 m_thickness;
|
||||||
|
scene::IMesh* m_cubemesh;
|
||||||
|
bool m_is_cube;
|
||||||
|
|
||||||
|
// internal extrusion helper methods
|
||||||
|
io::path getExtrudedName(video::ITexture* texture);
|
||||||
|
scene::IAnimatedMesh* extrudeARGB(u32 width, u32 height, u8* data);
|
||||||
|
scene::IAnimatedMesh* extrude(video::ITexture* texture);
|
||||||
|
scene::IMesh* createCubeMesh();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -2004,14 +2004,6 @@ LocalPlayer* Client::getLocalPlayer()
|
|||||||
return m_env.getLocalPlayer();
|
return m_env.getLocalPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::setPlayerWield(scene::ISceneNode *wield)
|
|
||||||
{
|
|
||||||
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
|
|
||||||
LocalPlayer *player = m_env.getLocalPlayer();
|
|
||||||
assert(player != NULL);
|
|
||||||
player->wield = wield;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::setPlayerControl(PlayerControl &control)
|
void Client::setPlayerControl(PlayerControl &control)
|
||||||
{
|
{
|
||||||
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
|
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
|
||||||
|
@ -210,7 +210,6 @@ public:
|
|||||||
|
|
||||||
LocalPlayer* getLocalPlayer();
|
LocalPlayer* getLocalPlayer();
|
||||||
|
|
||||||
void setPlayerWield(scene::ISceneNode *wield);
|
|
||||||
void setPlayerControl(PlayerControl &control);
|
void setPlayerControl(PlayerControl &control);
|
||||||
|
|
||||||
void selectPlayerItem(u16 item);
|
void selectPlayerItem(u16 item);
|
||||||
|
70
src/game.cpp
70
src/game.cpp
@ -819,44 +819,6 @@ void the_game(
|
|||||||
f32 camera_yaw = 0; // "right/left"
|
f32 camera_yaw = 0; // "right/left"
|
||||||
f32 camera_pitch = 0; // "up/down"
|
f32 camera_pitch = 0; // "up/down"
|
||||||
|
|
||||||
/*
|
|
||||||
Tool
|
|
||||||
*/
|
|
||||||
|
|
||||||
v3f tool_wield_position(0.06*BS, -0.06*BS, 0.1*BS);
|
|
||||||
v3f tool_wield_rotation(-25, 180, -25);
|
|
||||||
float tool_wield_animation = 0.0;
|
|
||||||
scene::IMeshSceneNode *tool_wield;
|
|
||||||
{
|
|
||||||
scene::SMesh *mesh = new scene::SMesh();
|
|
||||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
|
||||||
video::SColor c(255,255,255,255);
|
|
||||||
video::S3DVertex vertices[4] =
|
|
||||||
{
|
|
||||||
video::S3DVertex(-0.5,0,0, 0,0,0, c, 0,1),
|
|
||||||
video::S3DVertex(0.5,0,0, 0,0,0, c, 1,1),
|
|
||||||
video::S3DVertex(0.5,0.5,0, 0,0,0, c, 1,0),
|
|
||||||
video::S3DVertex(-0.5,0.5,0, 0,0,0, c, 0,0),
|
|
||||||
};
|
|
||||||
u16 indices[] = {0,1,2,2,3,0};
|
|
||||||
buf->append(vertices, 4, indices, 6);
|
|
||||||
// Set material
|
|
||||||
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
|
||||||
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
|
||||||
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
|
||||||
// Add to mesh
|
|
||||||
mesh->addMeshBuffer(buf);
|
|
||||||
buf->drop();
|
|
||||||
|
|
||||||
tool_wield = smgr->addMeshSceneNode(mesh, camera.getHeadNode());
|
|
||||||
mesh->drop();
|
|
||||||
}
|
|
||||||
tool_wield->setVisible(false);
|
|
||||||
tool_wield->setPosition(tool_wield_position);
|
|
||||||
tool_wield->setRotation(tool_wield_rotation);
|
|
||||||
|
|
||||||
client.setPlayerWield(tool_wield);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Clouds
|
Clouds
|
||||||
*/
|
*/
|
||||||
@ -1552,6 +1514,7 @@ void the_game(
|
|||||||
std::cout<<DTIME<<"Left-clicked object"<<std::endl;
|
std::cout<<DTIME<<"Left-clicked object"<<std::endl;
|
||||||
client.clickObject(0, selected_object->getBlock()->getPos(),
|
client.clickObject(0, selected_object->getBlock()->getPos(),
|
||||||
selected_object->getId(), g_selected_item);
|
selected_object->getId(), g_selected_item);
|
||||||
|
camera.setDigging(true);
|
||||||
}
|
}
|
||||||
else if(input->getRightClicked())
|
else if(input->getRightClicked())
|
||||||
{
|
{
|
||||||
@ -1619,6 +1582,7 @@ void the_game(
|
|||||||
std::cout<<DTIME<<"Left-clicked object"<<std::endl;
|
std::cout<<DTIME<<"Left-clicked object"<<std::endl;
|
||||||
client.clickActiveObject(0,
|
client.clickActiveObject(0,
|
||||||
selected_active_object->getId(), g_selected_item);
|
selected_active_object->getId(), g_selected_item);
|
||||||
|
camera.setDigging(true);
|
||||||
}
|
}
|
||||||
else if(input->getRightClicked())
|
else if(input->getRightClicked())
|
||||||
{
|
{
|
||||||
@ -1792,6 +1756,8 @@ void the_game(
|
|||||||
}
|
}
|
||||||
|
|
||||||
dig_time += dtime;
|
dig_time += dtime;
|
||||||
|
|
||||||
|
camera.setDigging(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1859,16 +1825,6 @@ void the_game(
|
|||||||
|
|
||||||
nodepos_old = nodepos;
|
nodepos_old = nodepos;
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(input->getLeftState())
|
|
||||||
// Tool animation loops 0.0 - 1.0
|
|
||||||
tool_wield_animation = fmod(tool_wield_animation + dtime * 3.0, 1.0);
|
|
||||||
else
|
|
||||||
// Return tool to holding position if not digging
|
|
||||||
tool_wield_animation /= 1.5;
|
|
||||||
|
|
||||||
} // selected_object == NULL
|
} // selected_object == NULL
|
||||||
|
|
||||||
@ -1880,6 +1836,7 @@ void the_game(
|
|||||||
std::cout<<DTIME<<"Left button released (stopped digging)"
|
std::cout<<DTIME<<"Left button released (stopped digging)"
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
client.groundAction(2, v3s16(0,0,0), v3s16(0,0,0), 0);
|
client.groundAction(2, v3s16(0,0,0), v3s16(0,0,0), 0);
|
||||||
|
camera.setDigging(false);
|
||||||
}
|
}
|
||||||
if(input->getRightReleased())
|
if(input->getRightReleased())
|
||||||
{
|
{
|
||||||
@ -1985,16 +1942,6 @@ void the_game(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Animate tool
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
f32 tool_wield_sin = sin(tool_wield_animation * PI);
|
|
||||||
tool_wield->setRotation(tool_wield_rotation - tool_wield_sin * 40.0);
|
|
||||||
tool_wield->setPosition(tool_wield_position - tool_wield_sin * BS / 30.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Update gui stuff (0ms)
|
Update gui stuff (0ms)
|
||||||
*/
|
*/
|
||||||
@ -2140,6 +2087,13 @@ void the_game(
|
|||||||
old_selected_item = g_selected_item;
|
old_selected_item = g_selected_item;
|
||||||
//std::cout<<"Updating local inventory"<<std::endl;
|
//std::cout<<"Updating local inventory"<<std::endl;
|
||||||
client.getLocalInventory(local_inventory);
|
client.getLocalInventory(local_inventory);
|
||||||
|
|
||||||
|
// Update wielded tool
|
||||||
|
InventoryList *mlist = local_inventory.getList("main");
|
||||||
|
InventoryItem *item = NULL;
|
||||||
|
if(mlist != NULL)
|
||||||
|
item = mlist->getItem(g_selected_item);
|
||||||
|
camera.wield(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -56,8 +56,6 @@ public:
|
|||||||
// Return the name of the image for this item
|
// Return the name of the image for this item
|
||||||
virtual std::string getBasename() { return ""; }
|
virtual std::string getBasename() { return ""; }
|
||||||
// Shall return an image of the item (or NULL)
|
// Shall return an image of the item (or NULL)
|
||||||
virtual video::ITexture * getImageRaw() { return NULL; }
|
|
||||||
// Shall return an image to show in the GUI (or NULL)
|
|
||||||
virtual video::ITexture * getImage() { return NULL; }
|
virtual video::ITexture * getImage() { return NULL; }
|
||||||
#endif
|
#endif
|
||||||
// Shall return a text to show in the GUI
|
// Shall return a text to show in the GUI
|
||||||
@ -156,7 +154,6 @@ public:
|
|||||||
video::ITexture * getImage()
|
video::ITexture * getImage()
|
||||||
{
|
{
|
||||||
return content_features(m_content).inventory_texture;
|
return content_features(m_content).inventory_texture;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
std::string getText()
|
std::string getText()
|
||||||
@ -388,14 +385,6 @@ public:
|
|||||||
return "cloud.png";
|
return "cloud.png";
|
||||||
}
|
}
|
||||||
|
|
||||||
video::ITexture * getImageRaw()
|
|
||||||
{
|
|
||||||
if(g_texturesource == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return g_texturesource->getTextureRaw(getBasename());
|
|
||||||
}
|
|
||||||
|
|
||||||
video::ITexture * getImage()
|
video::ITexture * getImage()
|
||||||
{
|
{
|
||||||
if(g_texturesource == NULL)
|
if(g_texturesource == NULL)
|
||||||
|
@ -309,31 +309,12 @@ LocalPlayer::LocalPlayer():
|
|||||||
// Initialize hp to 0, so that no hearts will be shown if server
|
// Initialize hp to 0, so that no hearts will be shown if server
|
||||||
// doesn't support health points
|
// doesn't support health points
|
||||||
hp = 0;
|
hp = 0;
|
||||||
|
|
||||||
// No tool wielded initially
|
|
||||||
wield = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalPlayer::~LocalPlayer()
|
LocalPlayer::~LocalPlayer()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalPlayer::wieldItem(u16 item)
|
|
||||||
{
|
|
||||||
m_selected_item = item;
|
|
||||||
|
|
||||||
if(wield) {
|
|
||||||
InventoryItem* i = inventory.getList("main")->getItem(m_selected_item);
|
|
||||||
|
|
||||||
if(i && strcmp(i->getName(), "ToolItem") == 0) {
|
|
||||||
wield->getMaterial(0).setTexture(0, i->getImageRaw());
|
|
||||||
wield->setVisible(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
wield->setVisible(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
|
void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
|
||||||
core::list<CollisionInfo> *collision_info)
|
core::list<CollisionInfo> *collision_info)
|
||||||
{
|
{
|
||||||
|
@ -357,8 +357,6 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wieldItem(u16 item);
|
|
||||||
|
|
||||||
void move(f32 dtime, Map &map, f32 pos_max_d,
|
void move(f32 dtime, Map &map, f32 pos_max_d,
|
||||||
core::list<CollisionInfo> *collision_info);
|
core::list<CollisionInfo> *collision_info);
|
||||||
void move(f32 dtime, Map &map, f32 pos_max_d);
|
void move(f32 dtime, Map &map, f32 pos_max_d);
|
||||||
@ -367,8 +365,6 @@ public:
|
|||||||
|
|
||||||
PlayerControl control;
|
PlayerControl control;
|
||||||
|
|
||||||
scene::ISceneNode *wield;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This is used for determining the sneaking range
|
// This is used for determining the sneaking range
|
||||||
v3s16 m_sneak_node;
|
v3s16 m_sneak_node;
|
||||||
|
Loading…
Reference in New Issue
Block a user