# Non-tile based raycasting problems

This topic is 3727 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi there! I'm currently working on a more advanced form of raycasting that is free from the restrictions of the grid based map. Basically the renderer works with lines and intersections, where a wall only consists of two arbitrary points in a coordinate system. Anyhow, I've run into problems. Some walls do not get drawn properly (they tear). Some of you have more experience than I do in this field, so I figured that someone might know what this problem is caused by? The code below is the full code for the renderer:
float32 ray_angle = camera->GetViewAngle() -(camera->GetFOV() /2),
ray_angle_increment = camera->GetFOV() /i2Screen.GetWidth() *quality_loss,
screen_distance = camera->GetScreenDistance(),
x1 = camera->GetPosition().x,
y1 = camera->GetPosition().y; //camera coordinates

for (uint32 x = 0; x < i2Screen.GetWidth(); x += quality_loss, ray_angle += ray_angle_increment){

ray_angle = i2::ForceInterval(ray_angle, 0, 360);
float32 x2 = (cos(i2::DegreesToRadians(ray_angle)) *screen_distance) +x1,
y2 = (sin(i2::DegreesToRadians(ray_angle)) *screen_distance) +y1; //screen-ray intersection coordinates

for (uint64 i = 0; i < map->GetSize(); ++i){

i2::MapRC::Wall * wall = &map->GetWall(i);
float32	x3 = wall->a.x,
y3 = wall->a.y,
x4 = wall->b.x,
y4 = wall->b.y; //wall coordinates

float32 div = ((x1-x2)*(y3-y4) - (y1-y2)*(x3-x4));
float32 wix = ((x1*y2 - y1*x2)*(x3-x4) - (x1-x2)*(x3*y4-y3*x4)) / div,
wiy = ((x1*y2 - y1*x2)*(y3-y4) - (y1-y2)*(x3*y4-y3*x4)) / div; //wall-ray intersection coordinates

if (wix >= x3 && wix <= x4 && wiy >= y3 && wiy <= y4){ //intersection is in wall interval

uint8 rq = 0; //ray quadrant
if (ray_angle >= 0.f && ray_angle < 90.f) { rq = 1; }
else if (ray_angle >= 90.f && ray_angle < 180.f) { rq = 2; }
else if (ray_angle >= 180.f && ray_angle < 270.f) { rq = 3; }
else if (ray_angle >= 270.f && ray_angle < 360.f) { rq = 4; }

float32 a = wix -x1,
b = wiy -y1;

uint8 wiq = rq; //wall intersection quadrant
if (a > 0.f){
if (b > 0.f) { wiq = 1; }
else if (b < 0.f) { wiq = 4; }
} else if (a < 0.f){
if (b > 0.f) { wiq = 2; }
else if (b < 0.f) { wiq = 3; }
} else if (a == 0.f){
if (b > 0.f) { wiq = 2; }
else if (b < 0.f) { wiq = 4; }
} else if (b == 0.f) {
if (a > 0.f) { wiq = 1; }
else if (a < 0.f) { wiq = 3; }
}

if (rq == wiq){ //ray quadrant must be same as wall intersection quadrant
float32 c = sqrt((a*a) +(b*b)) *cos(i2::DegreesToRadians(camera->GetViewAngle() -ray_angle)); //distance to intersection
uint32 h = static_cast<uint32>(wall->height /c); // wall height on-screen
byte color = static_cast<byte>(BYTE_MAX /(c +1.f)); //shade pixels

i2Screen.Fill(i2::Rectangle(x, (i2Screen.GetHeight() -h) /2, quality_loss, h), pixel32(i2::Color(color, color, color))); //draw pixels on screen
}
}
}
}

I should add that I suspect that the problem occurs in the section where I'm determining what quadrant (relative to the player/camera) the ray and the intersection are located in, i.e. somewhere between
uint8 rq = 0; //ray quadrant

and
if (rq == wiq){ //ray quadrant must be same as wall intersection quadrant

As you can see, I'm using a few user defined types, but I think they're named clearly enough for you to understand what they are. If not, don't hesitate to ask. Thank you for your time! /Jonathan [Edited by - JNT on July 18, 2008 3:58:05 PM]

##### Share on other sites
Sounds like you are doing something like doom but a little bit different.
Doom wasn't restricted to grid too. It used arbitary shaped sectors built of lines (polygons).
It might be worth for you to look at the doom source codes!

##### Share on other sites
Correct me if I'm wrong, but I don't think that the Doom engine is a raycaster at all, so Carmack's way of solving this problem probably won't apply to my situation.

I wish I could submit images on this forum (can you? am I missing something?), since I think it would clearly show what I mean by "tearing".

##### Share on other sites
Doom was using raycasting !
It sent rays through each screen column and calculated the intersection between rays and sectors/lines. Its advantage over wolfenstein was that it wasnt restricted to a grid and could produce arbitary looking levels (but with no room over room).

##### Share on other sites
Huh. I distinctly remember reading that the Doom engine wasn't a raycaster, but of course, I haven't read the source code until recently so I really couldn't tell one way or the other.

I just checked Wikipedia about the Doom engine and it seems like it checks intersections the same principal way my renderer does, just as you guys stated earlier. I looked around a bit in the Doom source but I didn't really find anything useful for my particular problem. It seems that the intersection problem is solved differently, circumventing my predicament all together. Then again, I only skimmed through the Doom code...

##### Share on other sites
To anyone interested, I found what was causing the walls to tear:

if (wix >= x3 && wix <= x4 && wiy >= y3 && wiy <= y4){ //intersection is in wall interval

The problem concerned inaccuracies in the floating-point values wix and wiy. I solved the problem by adding or subracting a small, near zero value to the floating-point variables, like so:

static const float32 ROUND = 0.000001f;if (wix +ROUND >= x3 && wix -ROUND <= x4 && wiy +ROUND >= y3 && wiy -ROUND <= y4){

Still, thanks for your time and help!

1. 1
Rutin
32
2. 2
3. 3
4. 4
5. 5

• 13
• 70
• 11
• 10
• 14
• ### Forum Statistics

• Total Topics
632967
• Total Posts
3009572
• ### Who's Online (See full list)

There are no registered users currently online

×