Home > front end >  Raycasting rendering - wall's edge crossing issue
Raycasting rendering - wall's edge crossing issue

Time:04-23

I'm implementing a fake 3D rendering using raycasting method (such as Wolfenstein3D). I have following the permandi's tutorial (enter image description here

But this not always the case. Sometimes it works well, depending the player's orientation. enter image description here

After rendering the scene in 2D I can see that the rays are indeed not detecting the wall. But depending the orientation, this is not always the case.

enter image description here

On the screenshot above, on the left this is not working but on the right this is working.

This is how I detect the wall and get the distance and the Y axis

float getDistanceOnHorizontalGrid(float rayAngle, float playerPosX, float playerPosY)
{
    float pointInRayY = playerPosY   (100 * sin(DEGREE_TO_RADIAN(rayAngle))); // Arbitrary Point to evaluate whether ray is facing up or down
    float firstIntersectPointY;
    float ya;
    float xa;

    if (pointInRayY <= playerPosY) // ray is facing up
    {
        firstIntersectPointY = floorf(playerPosY / WALL_SIZE) * (WALL_SIZE)-1;
        ya = -WALL_SIZE;
        xa = WALL_SIZE / tan(DEGREE_TO_RADIAN(rayAngle)) * -1;
    }
    else // ray is facing down
    {
        firstIntersectPointY = floorf(playerPosY / WALL_SIZE) * (WALL_SIZE) WALL_SIZE;
        ya = WALL_SIZE;
        xa = WALL_SIZE / tan(DEGREE_TO_RADIAN(rayAngle));
    }

    float firstIntersectPointX = playerPosX - (playerPosY - firstIntersectPointY) / tan(DEGREE_TO_RADIAN(rayAngle));

    float nextPointX = firstIntersectPointX;
    float nextPointY = firstIntersectPointY;

    for (int i = 0; i < MAP_HEIGHT; i  )
    {
        int toMapX = convertWorldToGridCoordinate(floor(nextPointX));
        int toMapY = convertWorldToGridCoordinate(floor(nextPointY));

        if (!(toMapX >= 0 && toMapX <= MAP_WIDTH - 1 && toMapY >= 0 && toMapY <= MAP_HEIGHT - 1))
        {
            return 0.0f;
        }

        if (map[toMapY][toMapX] == 1)
        {
            return abs(sqrt(((playerPosX - nextPointX) * (playerPosX - nextPointX))   ((playerPosY - nextPointY) * (playerPosY - nextPointY))));
        }

        nextPointX  = xa;
        nextPointY  = ya;
    }

    return 0.0f;
}

And the same for X axis

float getDistanceOnverticalGrid(float rayAngle, float playerPosX, float playerPosY)
{
    float pointInRayX = playerPosX   (100 * cos(DEGREE_TO_RADIAN(rayAngle))); // Arbitrary Point to evaluate whether ray is facing left or right
    float firstIntersectX;
    float firstIntersectY;
    float xa;
    float ya;

    if (pointInRayX <= playerPosX) // ray facing left
    {
        firstIntersectX = floorf(playerPosX / WALL_SIZE) * (WALL_SIZE)-1;
        xa = -WALL_SIZE;
        ya = (WALL_SIZE * tan(DEGREE_TO_RADIAN(rayAngle))) * -1;
    }
    else
    {
        firstIntersectX = floorf(playerPosX / WALL_SIZE) * (WALL_SIZE) WALL_SIZE;
        ya = WALL_SIZE * tan(DEGREE_TO_RADIAN(rayAngle));
        xa = WALL_SIZE;
    }

    firstIntersectY = playerPosY - (playerPosX - firstIntersectX) * tan(DEGREE_TO_RADIAN(rayAngle));

    float nextPointX = firstIntersectX;
    float nextPointY = firstIntersectY;


    for (int i = 0; i < MAP_WIDTH; i  )
    {
        int toMapX = convertWorldToGridCoordinate(floorf(nextPointX));
        int toMapY = convertWorldToGridCoordinate(floorf(nextPointY));

        if (!(toMapX >= 0 && toMapX <= (MAP_WIDTH - 1) && toMapY >= 0 && toMapY <= (MAP_HEIGHT - 1)))
        {
            return 0.0f;
        }

        if (map[toMapY][toMapX] == 1)
        {
            return abs(sqrt(((playerPosX - nextPointX) * (playerPosX - nextPointX))   ((playerPosY - nextPointY) * (playerPosY - nextPointY))));
        }

        nextPointX  = xa;
        nextPointY  = ya;
    }

    return 0.0f;
}

I must do something wrong, but I don't know where. Thank you for your help

UPDATE

What Mentionned BCT was actually right even though decreasing the value from 1 is still necessary, but not in that calculation. After taking a loog closer to permadi's implementation, after doing this

horizontalGrid = Math.floor(this.fPlayerY/this.TILE_SIZE)*this.TILE_SIZE    this.TILE_SIZE;

He did :

horizontalGrid--;

I thought at first it's equal to what I have done but actually no. The reason he decrease the value later it's because this is only to get the grid coordinate.

To resolve my issue, I have removed the -1 from the calculation, and decrease the value only when I'm looking for the grid coordinate.

CodePudding user response:

I looked at the link you sent. And it seems like one of the if blocks has a bad value:

This is the tutorial code:

// Ray is facing down
        if (castArc > this.ANGLE0 && castArc < this.ANGLE180)
        {
            // truncuate then add to get the coordinate of the FIRST grid (horizontal
            // wall) that is in front of the player (this is in pixel unit)
            // ROUNDED DOWN
            horizontalGrid = Math.floor(this.fPlayerY/this.TILE_SIZE)*this.TILE_SIZE    this.TILE_SIZE;

This is your code:

 if (pointInRayY <= playerPosY) // ray is facing up
 {
     firstIntersectPointY = floorf(playerPosY / WALL_SIZE) * (WALL_SIZE)-1;

Notice you have -1 at the end instead of this.TILE_SIZE which in your case should be WALL_SIZE

  • Related