Revert "Fast map raycasting"

This reverts commit d563fd964f.
This commit is contained in:
Menche 2016-08-15 19:55:04 -07:00
parent 3c94ab6199
commit 70495d8ebe
1 changed files with 181 additions and 163 deletions

View File

@ -250,88 +250,59 @@ public:
/*
Find what the player is pointing at
*/
void getPointedNode(Client *client,
v3f camera_direction,v3f camera_position,
void getPointedNode(Client *client, v3f player_position,
v3f camera_direction, v3f camera_position,
bool &nodefound, core::line3d<f32> shootline,
v3s16 &nodepos, v3s16 &neighbourpos, v3s16 camera_offset,
core::aabbox3d<f32> &nodehilightbox,
f32 d)
{
//inventory
f32 mindistance = BS * 1001;
v3s16 pos_i = floatToInt(player_position, BS);
/*infostream<<"pos_i=("<<pos_i.X<<","<<pos_i.Y<<","<<pos_i.Z<<")"
<<std::endl;*/
//printf("%f,%f,%f - %f,%f,%f\n",shootline.start.X,shootline.start.Y,shootline.start.Z,shootline.end.X,shootline.end.Y,shootline.end.Z);
s16 a = d;
s16 ystart = pos_i.Y + 0 - (camera_direction.Y<0 ? a : 1);
s16 zstart = pos_i.Z - (camera_direction.Z<0 ? a : 1);
s16 xstart = pos_i.X - (camera_direction.X<0 ? a : 1);
s16 yend = pos_i.Y + 1 + (camera_direction.Y>0 ? a : 1);
s16 zend = pos_i.Z + (camera_direction.Z>0 ? a : 1);
s16 xend = pos_i.X + (camera_direction.X>0 ? a : 1);
InventoryItem *wield = (InventoryItem*)client->getLocalPlayer()->getWieldItem();
bool wield_is_hand = (wield == NULL);
bool wield_is_tool = (wield && wield->getContent()&CONTENT_TOOLITEM_MASK);
bool wield_is_craft = (wield && wield->getContent()&CONTENT_CRAFTITEM_MASK);
bool wield_is_material = (!wield_is_hand && !wield_is_tool && !wield_is_craft);
//initialize iteration
content_t content = CONTENT_IGNORE;
v3s16 cam_i = floatToInt(camera_position, BS);
//coordinates of current node
s16 x=cam_i.X;
s16 y=cam_i.Y;
s16 z=cam_i.Z;
s16 oldx=x;
s16 oldy=y;
s16 oldz=z;
v3f norm_pos=camera_position/BS;//divide by BS so one node is one unit
v3f norm_dir=v3f(camera_direction);
norm_dir.normalize();
norm_dir*=d;
f32 rx=2;//ratio by which we multiply norm_dir to hit node (ratio x)
f32 rxs=1;//incrementing rx by rxs gives the next node in x direction (ratio x step)
s16 xs=1;//incrementing rx involves incrementing x by xs (x step)
if(norm_dir.X>0){//set rx,rxs and xs
rx=(floorf(norm_pos.X-0.5)+1.5-norm_pos.X)/norm_dir.X;
rxs=1/norm_dir.X;
}else if(norm_dir.X<0){
rx=(floorf(norm_pos.X-0.5)-norm_pos.X+0.5)/norm_dir.X;
rxs=-1/norm_dir.X;
xs=-1;
}//other directions
f32 rz=2;
f32 rzs=1;
s16 zs=1;
if(norm_dir.Z>0){
rz=(floorf(norm_pos.Z-0.5)+1.5-norm_pos.Z)/norm_dir.Z;
rzs=1/norm_dir.Z;
}else if(norm_dir.Z<0){
rz=(floorf(norm_pos.Z-0.5)-norm_pos.Z+0.5)/norm_dir.Z;
rzs=-1/norm_dir.Z;
zs=-1;
}
f32 ry=2;
f32 rys=1;
s16 ys=1;
if(norm_dir.Y>0){
ry=(floorf(norm_pos.Y-0.5)+1.5-norm_pos.Y)/norm_dir.Y;
rys=1/norm_dir.Y;
}else if(norm_dir.Y<0){
ry=(floorf(norm_pos.Y-0.5)-norm_pos.Y+0.5)/norm_dir.Y;
rys=-1/norm_dir.Y;
ys=-1;
}
//now iterate through nodes
do{
bool testable=true;
for(s16 y = ystart; y <= yend; y++)
for(s16 z = zstart; z <= zend; z++)
for(s16 x = xstart; x <= xend; x++)
{
//printf("%d,%d,%d\n",x,y,z);
MapNode n;
try
{
n = client->getNode(v3s16(x,y,z));
if (content_features(n.getContent()).pointable == false) {
if (content_features(n.getContent()).liquid_type != LIQUID_SOURCE)
testable=false;
continue;
if (!wield || content_toolitem_features(wield->getContent()).liquids_pointable == false)
testable=false;
continue;
}else if (content_features(n.getContent()).material_pointable == false && wield_is_material) {
testable=false;
continue;
}
}
catch(InvalidPositionException &e)
{
testable=false;
continue;
}
//if node is valid
if(testable){
v3s16 np(x,y,z);
v3f npf = intToFloat(np, BS);
@ -355,6 +326,7 @@ void getPointedNode(Client *client,
v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
dir_f *= BS/2 - BS/6 - BS/20;
v3f cpf = npf + dir_f;
f32 distance = (cpf - camera_position).getLength();
core::aabbox3d<f32> box;
@ -382,17 +354,24 @@ void getPointedNode(Client *client,
cpf + v3f(BS/6, BS/3, BS/6)
);
}
if(box.intersectsWithLine(shootline))
if(distance < mindistance)
{
nodefound = true;
nodepos = np;
content = n.getContent();
neighbourpos = np;
box.MinEdge -= intToFloat(camera_offset,BS);
box.MaxEdge -= intToFloat(camera_offset,BS);
nodehilightbox = box;
if(box.intersectsWithLine(shootline))
{
nodefound = true;
nodepos = np;
content = n.getContent();
neighbourpos = np;
mindistance = distance;
box.MinEdge -= intToFloat(camera_offset,BS);
box.MaxEdge -= intToFloat(camera_offset,BS);
nodehilightbox = box;
}
}
}else if(n.getContent() == CONTENT_RAIL) {
f32 distance = (npf - camera_position).getLength();
float d = (float)BS/8;
v3f vertices[4] =
{
@ -410,15 +389,19 @@ void getPointedNode(Client *client,
box = core::aabbox3d<f32>(vertices[0]);
box.addInternalPoint(vertices[1]);
if(box.intersectsWithLine(shootline))
if(distance < mindistance)
{
nodefound = true;
nodepos = np;
content = n.getContent();
neighbourpos = np;
box.MinEdge -= intToFloat(camera_offset,BS);
box.MaxEdge -= intToFloat(camera_offset,BS);
nodehilightbox = box;
if(box.intersectsWithLine(shootline))
{
nodefound = true;
nodepos = np;
content = n.getContent();
neighbourpos = np;
mindistance = distance;
box.MinEdge -= intToFloat(camera_offset,BS);
box.MaxEdge -= intToFloat(camera_offset,BS);
nodehilightbox = box;
}
}
/*
Roofs and Node boxes
@ -434,104 +417,139 @@ void getPointedNode(Client *client,
|| content_features(n).draw_type == CDT_SLABLIKE
|| content_features(n).draw_type == CDT_FLAGLIKE
) {
aabb3f box;
aabb3f nhbox(0.5*BS,0.5*BS,0.5*BS,-0.5*BS,-0.5*BS,-0.5*BS);
bool hit = false;
std::vector<NodeBox> boxes = content_features(n).getNodeBoxes(n);
for (std::vector<NodeBox>::iterator b = boxes.begin(); b != boxes.end(); b++) {
box = b->m_box;
if (nhbox.MinEdge.X > box.MinEdge.X)
nhbox.MinEdge.X = box.MinEdge.X;
if (nhbox.MinEdge.Y > box.MinEdge.Y)
nhbox.MinEdge.Y = box.MinEdge.Y;
if (nhbox.MinEdge.Z > box.MinEdge.Z)
nhbox.MinEdge.Z = box.MinEdge.Z;
if (nhbox.MaxEdge.X < box.MaxEdge.X)
nhbox.MaxEdge.X = box.MaxEdge.X;
if (nhbox.MaxEdge.Y < box.MaxEdge.Y)
nhbox.MaxEdge.Y = box.MaxEdge.Y;
if (nhbox.MaxEdge.Z < box.MaxEdge.Z)
nhbox.MaxEdge.Z = box.MaxEdge.Z;
box.MinEdge += npf;
box.MaxEdge += npf;
if (box.intersectsWithLine(shootline)) {
for(u16 i=0; i<6; i++) {
v3f dir_f = v3f(dirs[i].X,
dirs[i].Y, dirs[i].Z);
f32 distance = (npf - camera_position).getLength();
core::CMatrix4<f32> m;
m.buildRotateFromTo(v3f(0,0,1), dir_f);
if (distance < mindistance) {
aabb3f box;
aabb3f nhbox(0.5*BS,0.5*BS,0.5*BS,-0.5*BS,-0.5*BS,-0.5*BS);
bool hit = false;
std::vector<NodeBox> boxes = content_features(n).getNodeBoxes(n);
for (std::vector<NodeBox>::iterator b = boxes.begin(); b != boxes.end(); b++) {
box = b->m_box;
// This is the back face
v3f corners[2] = {
v3f(BS/2, BS/2, BS/2),
v3f(-BS/2, -BS/2, BS/2+d)
};
for(u16 j=0; j<2; j++)
{
m.rotateVect(corners[j]);
corners[j] += npf;
}
core::aabbox3d<f32> facebox(corners[0]);
facebox.addInternalPoint(corners[1]);
if (nhbox.MinEdge.X > box.MinEdge.X)
nhbox.MinEdge.X = box.MinEdge.X;
if (nhbox.MinEdge.Y > box.MinEdge.Y)
nhbox.MinEdge.Y = box.MinEdge.Y;
if (nhbox.MinEdge.Z > box.MinEdge.Z)
nhbox.MinEdge.Z = box.MinEdge.Z;
if (nhbox.MaxEdge.X < box.MaxEdge.X)
nhbox.MaxEdge.X = box.MaxEdge.X;
if (nhbox.MaxEdge.Y < box.MaxEdge.Y)
nhbox.MaxEdge.Y = box.MaxEdge.Y;
if (nhbox.MaxEdge.Z < box.MaxEdge.Z)
nhbox.MaxEdge.Z = box.MaxEdge.Z;
if(facebox.intersectsWithLine(shootline))
{
nodefound = true;
nodepos = np;
content = n.getContent();
neighbourpos = np + dirs[i];
hit = true;
}
} // for dirs
box.MinEdge += npf;
box.MaxEdge += npf;
if (box.intersectsWithLine(shootline)) {
for(u16 i=0; i<6; i++) {
v3f dir_f = v3f(dirs[i].X,
dirs[i].Y, dirs[i].Z);
v3f centerpoint = npf + dir_f * BS/2;
f32 distance =
(centerpoint - camera_position).getLength();
if(distance < mindistance)
{
core::CMatrix4<f32> m;
m.buildRotateFromTo(v3f(0,0,1), dir_f);
// This is the back face
v3f corners[2] = {
v3f(BS/2, BS/2, BS/2),
v3f(-BS/2, -BS/2, BS/2+d)
};
for(u16 j=0; j<2; j++)
{
m.rotateVect(corners[j]);
corners[j] += npf;
}
core::aabbox3d<f32> facebox(corners[0]);
facebox.addInternalPoint(corners[1]);
if(facebox.intersectsWithLine(shootline))
{
nodefound = true;
nodepos = np;
content = n.getContent();
neighbourpos = np + dirs[i];
mindistance = distance;
hit = true;
}
} // if distance < mindistance
} // for dirs
}
}
if (hit) {
nhbox.MinEdge -= 0.002;
nhbox.MaxEdge += 0.002;
v3f nodepos_f = intToFloat(nodepos-camera_offset, BS);
nhbox.MinEdge += nodepos_f;
nhbox.MaxEdge += nodepos_f;
nodehilightbox = nhbox;
}
boxes.clear();
}
if (hit) {
nhbox.MinEdge -= 0.002;
nhbox.MaxEdge += 0.002;
v3f nodepos_f = intToFloat(nodepos-camera_offset, BS);
nhbox.MinEdge += nodepos_f;
nhbox.MaxEdge += nodepos_f;
nodehilightbox = nhbox;
}
boxes.clear();
/*
Regular blocks
*/
}else{
nodefound = true;
nodepos = np;
content = n.getContent();
neighbourpos.set(oldx,oldy,oldz);
const float d = 0.502;
core::aabbox3d<f32> nodebox
(-BS*d, -BS*d, -BS*d, BS*d, BS*d, BS*d);
v3f nodepos_f = intToFloat(nodepos-camera_offset, BS);
nodebox.MinEdge += nodepos_f;
nodebox.MaxEdge += nodepos_f;
nodehilightbox = nodebox;
for(u16 i=0; i<6; i++)
{
v3f dir_f = v3f(dirs[i].X,
dirs[i].Y, dirs[i].Z);
v3f centerpoint = npf + dir_f * BS/2;
f32 distance =
(centerpoint - camera_position).getLength();
//printf("%f %f - %d,%d,%d\n",distance, mindistance,x,y,z);
if(distance < mindistance)
{
core::CMatrix4<f32> m;
m.buildRotateFromTo(v3f(0,0,1), dir_f);
// This is the back face
v3f corners[2] = {
v3f(BS/2, BS/2, BS/2),
v3f(-BS/2, -BS/2, BS/2+d)
};
for(u16 j=0; j<2; j++)
{
m.rotateVect(corners[j]);
corners[j] += npf;
}
core::aabbox3d<f32> facebox(corners[0]);
facebox.addInternalPoint(corners[1]);
if(facebox.intersectsWithLine(shootline))
{
nodefound = true;
nodepos = np;
content = n.getContent();
neighbourpos = np + dirs[i];
mindistance = distance;
//nodehilightbox = facebox;
const float d = 0.502;
core::aabbox3d<f32> nodebox
(-BS*d, -BS*d, -BS*d, BS*d, BS*d, BS*d);
v3f nodepos_f = intToFloat(nodepos-camera_offset, BS);
nodebox.MinEdge += nodepos_f;
nodebox.MaxEdge += nodepos_f;
nodehilightbox = nodebox;
}
} // if distance < mindistance
} // for dirs
} // regular block
} //testable
//if found node, it is the closest
if(nodefound)break;
//check if we can step forward
if(rx>1&&ry>1&&rz>1)break;
//step to next node
oldx=x;
oldy=y;
oldz=z;
if((rx<ry)&&(rx<rz)){
rx+=rxs;
x+=xs;
}else if(ry<rz){
ry+=rys;
y+=ys;
}else{
rz+=rzs;
z+=zs;
}
}while(true);
} // for coords
if (nodefound) {
client->setPointedNode(nodepos);
client->setPointedContent(content);
@ -1615,7 +1633,7 @@ void the_game(
v3s16 neighbourpos;
core::aabbox3d<f32> nodehilightbox;
getPointedNode(&client,
getPointedNode(&client, player_position,
camera_direction, camera_position,
nodefound, shootline,
nodepos, neighbourpos, camera_offset,