DieHard Wolfers Forum Index DieHard Wolfers
A Wolfenstein 3d Fan Community


  Hosted by: MCS & Areyep.com - Designed by: BrotherTank

Original Yahoo Forum - Die Hard Archives

AReyeP HomepageAreyep Homepage DieHard Wolfenstein BunkerDieHard Wolfenstein Bunker Log inLog in RegisterRegister Banlist FAQFAQ Search ForumsSearch

  Username:    Password:      Remember me       

Clipping on y plane directional 3d sprites bug
Page 1 of 1
DieHard Wolfers Forum Index -> Code Crackers View Previous TopicRefresh this PageAdd Topic to your Browser FavoritesSearch ForumsPrint this TopicE-mail TopicGoto Page BottomView Next Topic
Post new topicReply to topic
Author Message
Ringman
DieHard Wolfer
DieHard Wolfer


Joined: 31 Jul 2003
Last Visit: 15 Jul 2019

Topics: 56
Posts: 1180
Location: up my nose
usa.gif

PostPosted: Mon Jun 24, 2019 3:54 am
   Subject: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Next PostGoto Bottom of Posts

This is directed more towards ecwolf Scale3dShaper, but it happens in dark one's Scale3dSpriterr as well, which is what the ecwolf routine was based on. This is ancient, and I've never seen it addressed in the forum. I was looking EVERYWHERE but I haven't seen a fix for it.


The issue is that when the sprite extends passed the view-plane it ends up with a negative coordinate, which would cause a divide by zero error, so it is just rendered invisible instead. Mostly this can be ignored as long as you never allow the player to get close enough to the sprite for this to happen. However, for things like "long" archways this can be extremely noticeable.

I've been able to come up with an ugly fix, that allows the player to get close enough and avoids the divide by zero errors, but there's alot of distortion in some cases because it appears my math is off. I don't fully understand all the pieces involved so its rather hard to address on my own.

Has anyone figured out a solution for this other than writing a "maskwall" routine similar to ROTT? I looked into the old BrotherTank Raycastor code, but I didn't feel like diving into that if I could simply adjust the clipping part of DarkOne's code. That seems to be the path of least resistance.

Here's the start of the original code:

::: CODE :::
 if(nx1 < 0 || nx2 < 0) return;      // TODO: Clip on viewplane

    //
    // calculate perspective ratio
    //
    if(nx1>=0 && nx1<=1792) nx1=1792;
    if(nx1<0 && nx1>=-1792) nx1=-1792;
    if(nx2>=0 && nx2<=1792) nx2=1792;
    if(nx2<0 && nx2>=-1792) nx2=-1792;

    viewx1=(int)(centerx+ny1*scale/nx1);
    viewx2=(int)(centerx+ny2*scale/nx2);

    if(viewx2 < viewx1)
    {
        Scale3DShaper(viewx2,viewx1,ob->shapenum,ob->flags,ny2,ny1,nx2,nx1,vbuf,vbufPitch);
    }
    else
    {
        Scale3DShaper(viewx1,viewx2,ob->shapenum,ob->flags,ny1,ny2,nx1,nx2,vbuf,vbufPitch);
    }


The obvious thing to do in my opinion would be to figure out where on the texture the yplane intersects and then just draw from there, however, given the complexity of the code, this wasn't simple to figure out. Furthermore, ecwolf's scale3dspriter is vastly different, so I don't know how I could implement the fix in both. This also ignores that fact that 3d sprites aren't sorted by stripe when being drawn which means sprites intersecting them at certain distances will be rendered in front of them when they should be behind them, but this is less of an issue in my opinion.

_________________
One day I saw upon a stair a little man who wasn't there. He wasn't there again today. My gosh I'd wish he'd go away.


Last edited by Ringman on Mon Jun 24, 2019 8:41 am; edited 1 time in total
Ringman
DieHard Wolfer
DieHard Wolfer


Joined: 31 Jul 2003
Last Visit: 15 Jul 2019

Topics: 56
Posts: 1180
Location: up my nose
usa.gif

PostPosted: Mon Jun 24, 2019 8:39 am
   Subject: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Here's what I have in place now, please forgive the code duplication and the experimental values

::: CODE :::

//if(nx1 < 0 || nx2 < 0) return; // TODO: Clip on viewplane
   
   // calculate perspective ratio
   //if(nx1>=0 && nx1<=1792) nx1=1792;
   //if(nx1<0 && nx1>=-1792) nx1=-1792;
   /*if (nx2 >= 0 && nx2 <= 1792) nx2 = 1792;
   if (nx2<0 && nx2 >= -1792) nx2 = -1792;*/
   fixed den1 = nx1;
   fixed den2 = nx2;
   if (den1 <= 1792) den1 = 1792;
   if (den2 <= 1792) den2 = 1792;
   
   
   viewx1=(int)(centerx+ny1*scale/den1);
   viewx2=(int)(centerx+ny2*scale/den2);

...

else
   {
      if(viewx2 < viewx1)
      {
         Scale3DSpriter(actor, viewx2, viewx1+1, tex, flip, frame, ny2, ny1, nx2, nx1);
      }
      else
      {
         Scale3DSpriter(actor, viewx1, viewx2+1, tex, flip, frame, ny1, ny2, nx1, nx2);
      }
   }
....

void Scale3DSpriter(AActor *actor, int x1, int x2, FTexture *tex, bool flip, const Frame *frame, fixed ny1, fixed ny2, fixed nx1, fixed nx2)
{
   if(actor->sprite == SPR_NONE || loadedSprites[actor->sprite].numFrames == 0)
      return;
   unsigned int texWidth = tex->GetWidth();
   unsigned int  xstart=0;
   
   fixed nxDist = abs(nx2 - nx1);
   word heightAdd1 = (word)0;
   word heightAdd2 = (word)0;
   if (nx1 < 1792) {
      fixed extra = abs(1792-nx1);
      if (extra < 1792)extra = 1792;
      heightAdd1 = (word)(1-(heightnumerator / (extra >> 8)));
      nx1 = 1792;
      
         xstart = (unsigned int)round((double)nx1 / (double)nxDist*(double)texWidth);
         nxDist = abs(nx2 - nx1);
      
   }
   if (nx2 < 1792) {
      fixed extra = abs(1792 - nx2);
      if (extra < 1792)extra = 1792;
      heightAdd2 = (word)(1-(heightnumerator / (extra >> 8)));
      nx2 = 1792;
      xstart = (unsigned int)round((double)nx2 / (double)nxDist*(double)texWidth);
   }
   unsigned height1 = (word)(heightnumerator/(nx1>>8))+heightAdd1;
   unsigned height2 = (word)(heightnumerator/(nx2>>8))+heightAdd2;


This works in the sense that it doesn't crash, but it fails to properly calculate the y position on the screen when the sprite gets clipped. I was messing around with height1 and height2 a bit to try and correct this, but they seem to be dependent on some other factor that I'm missing.

_________________
One day I saw upon a stair a little man who wasn't there. He wasn't there again today. My gosh I'd wish he'd go away.
Aryan_Wolf3D
DieHard Guard
DieHard Guard


Joined: 21 Jul 2011
Last Visit: 15 Oct 2019

Topics: 6
Posts: 256

blank.gif

PostPosted: Mon Jun 24, 2019 12:54 pm
   Subject: Re: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Ringman wrote:
Has anyone figured out a solution for this other than writing a "maskwall" routine similar to ROTT? I looked into the old BrotherTank Raycastor code, but I didn't feel like diving into that if I could simply adjust the clipping part of DarkOne's code. That seems to be the path of least resistance.

I wouldn't recommend that raycaster code for this, because it has too many drawbacks. However, I actually have ported RoTT's masked wall code into Wolf4SDL, and it works wonderfully...




At first it looked like it would be complicated to do, but it was surprisingly easy to port (luckily, it's not dependent on RoTT's cryptic raycaster code). Unfortunately, I've been unable to fix the bug where a visible gap appears between masked walls that are adjacent to opaque walls...



I'd hoped that the RoTT code would fix this, but it actually appears to be related to the solid walls themselves. You can kind of see the same thing happen with doors in the original Wolf... As you move further away from them, you should see the wall posts at the side appear to "cycle" through different columns of the wall texture and the door side. I'm really not sure what causes this to happen.

Anyway, if anyone would be interested in a tutorial for porting RoTT's masked walls, then I'll see if I can find the time to write one.

_________________
"Way too many #ifdefs in the code!" - John Carmack
Ringman
DieHard Wolfer
DieHard Wolfer


Joined: 31 Jul 2003
Last Visit: 15 Jul 2019

Topics: 56
Posts: 1180
Location: up my nose
usa.gif

PostPosted: Mon Jun 24, 2019 1:37 pm
   Subject: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Thanks. I actually looked into that as well, it looked like it could be pretty complicated, but I didn't read into it very far, before trying another crack at getting proper y plane clipping to work. I'll take another look, now that I know someone else has tried it. You can help me if I trip up. Very Happy

_________________
One day I saw upon a stair a little man who wasn't there. He wasn't there again today. My gosh I'd wish he'd go away.
Aryan_Wolf3D
DieHard Guard
DieHard Guard


Joined: 21 Jul 2011
Last Visit: 15 Oct 2019

Topics: 6
Posts: 256

blank.gif

PostPosted: Tue Jun 25, 2019 12:26 am
   Subject: Re: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Sure thing. I guess the most important things to know would be that RoTT uses very different values for the derived constants "heightnumerator" & "scale", which are used in the TransformPoint & TransformSimplePoint routines. I'm not quite sure how it all works, but you can still use the Wolf3D values, just divide "nx" by 256 as usual (check TransformActor to see what I mean.) Plus all the height stuff needs to be changed to 16 bit integers (they're 32 bit in RoTT because heightnumerator is so large.) And finally, although RoTT uses sprites for the masked walls, I'd recommend using walls for them in Wolf, because then you won't have to mess with the godawful "line commands" pointer stuff to get them working.

Hopefully this will get you started, good luck!

_________________
"Way too many #ifdefs in the code!" - John Carmack
Ringman
DieHard Wolfer
DieHard Wolfer


Joined: 31 Jul 2003
Last Visit: 15 Jul 2019

Topics: 56
Posts: 1180
Location: up my nose
usa.gif

PostPosted: Tue Jun 25, 2019 3:28 am
   Subject: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

The bug you mentioned earlier is caused by the ray missing an intersection between the mask wall and the side wall because the precision was meant for walls that are always 1 block apart. The farther away you are from the wall the less precise these intersection calculations become.

One fix for this is to increase the intersection precision by temporarily decreasing the distance that the ray "jumps" (ytilestep or xtilestep) when inside a block that's either a masked wall or a door. You'd decrease it by how much the masked wall's position is offset from its normal position.

What I mean is if the wall is a middle wall, you temporarily decrease the ytilestep or xtilestep by 0.5, if its a quarter wall, you decrease it by 0.75, and so on. But only if the ray is already inside a wall.

So if lasthit==door or lasthit==maskedwall temperorarily decrease the tilestep

I'm not sure if this is easily done in wolf because wolf doesn't use floating point to check its hits.

You'd need to somehow refine the calculations done here I think:
::: CODE :::
 int32_t xintbuf=xintercept+(xstep>>1);
                    if((xintbuf>>16)!=(xintercept>>16))
                        goto passhoriz;



For a less refined solution you could just check if lasthit==door or lasthit==masked wall and the door is closed and the camera is not inside the doortile/maskedtile then you always return a hit to something.

Unfortunately because of all the code duplication and lack of encapsulation in the original wolf code a simple change like this becomes harder than it should be. I'm sure there are refactored versions out there, but at this point the path of least resistance for anyone just looking to make a basic modification is to change as little as possible.[/code]

_________________
One day I saw upon a stair a little man who wasn't there. He wasn't there again today. My gosh I'd wish he'd go away.
Aryan_Wolf3D
DieHard Guard
DieHard Guard


Joined: 21 Jul 2011
Last Visit: 15 Oct 2019

Topics: 6
Posts: 256

blank.gif

PostPosted: Tue Jun 25, 2019 4:11 am
   Subject: Re: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Interesting... So have you actually done this yourself before, or is it just a theoretical solution?

As far as I can tell, the problem doesn't exist in RoTT. I imagine that the raycaster it uses is a whole lot more precise, despite being a whole lot more cryptic than Wolf's version... I wish the programmer (Mark Dochtermann, I'm guessing) had been bothered to use proper commenting with his code. Nonetheless, I had some limited success with porting it into Wolf. If I can figure out how it works, maybe it would be a lot easier to get stuff like this to work with less imperfections.

_________________
"Way too many #ifdefs in the code!" - John Carmack
Ringman
DieHard Wolfer
DieHard Wolfer


Joined: 31 Jul 2003
Last Visit: 15 Jul 2019

Topics: 56
Posts: 1180
Location: up my nose
usa.gif

PostPosted: Tue Jun 25, 2019 6:09 am
   Subject: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

I actually wrote a raycaster in java while I was in college that used "masked walls" and I ran into a similar problem. Actually in the java raycaster I would do a "line intersect" check whenever I entered a masked wall tile, so I could have crazy things like angled walls, and curved walls and what not. However the code I had for raycasting was easier to manage than the wolf code in some ways, but wasn't as fast. I was using full color bmp's though, which might have had something to do with it. I could try to find my old code, but it would difficult to implement smoothly into current wolf3d code I think.

EDIT:
here's an older less complicated iteration I found that didn't take into account masked walls other than "midway" walls:
::: CODE :::

  //jump to next map square, OR in x-direction, OR in y-direction
        stepMap(stepX,stepY);

        //Check if ray has hit a wall
        currWall=wallMap.queryMap(mapX,mapY);
        hitX=mapX;
        hitY=mapY;
        hitStepX=stepX;
        hitStepY=stepY;
        if ( currWall > 0 ){
                hit=1;
                double newStep=0.5;
                if(wallMap.isNSMask(currWall)){
                    hitStepY=0;
                    double hitCheck=rayPosY-newStep;
                    double nextHit=hitY+stepY;
                    if(side==0){
                        if((hitCheck>hitY && hitCheck<nextHit)
                            ||(hitCheck<hitY && hitCheck>nextHit))

                            hit=0;
                    }
                    side=1;
                    if(sideDistX+deltaDistY*newStep < sideDistY)
                            hit=0;
                }else if(wallMap.isEWMask(currWall)){
                   
                    hitStepX=0;
                    double hitCheck=rayPosX-newStep;
                    double nextHit=hitX+stepX;
                    if(side==1){
                         if((hitCheck>hitX && hitCheck<nextHit)
                            ||(hitCheck<hitX && hitCheck>nextHit))

                            hit=0;
                    }
                    side=0;
                    if(sideDistY+deltaDistX*newStep < sideDistX)
                            hit=0;
                }
               
        }
        double wallX;
        if(hit == 1){
           
               //calculate value of wallX
                 //where exactly the wall was hit
           
            if (side == 1) {
               
                wallX = rayPosX + ((hitY - rayPosY + (1 - hitStepY) / 2) / rayDirY) * rayDirX;             
               
            }
            else {
               
                wallX = rayPosY + ((hitX - rayPosX + (1 - hitStepX) / 2) / rayDirX) * rayDirY;
            }
            wallX -= Math.floor((wallX));
           
            drawOffset=(int)(wallX*64d);
           
        }

My raycaster did not feature "sliding doors" just animated ones so I didn't have to deal with wall offsets. Also doors didn't have automatically textured side panels, but you could set a boolean if you had passed through a mask wall and hit the opposite side panel on the next loop.[/code]

_________________
One day I saw upon a stair a little man who wasn't there. He wasn't there again today. My gosh I'd wish he'd go away.
Aryan_Wolf3D
DieHard Guard
DieHard Guard


Joined: 21 Jul 2011
Last Visit: 15 Oct 2019

Topics: 6
Posts: 256

blank.gif

PostPosted: Tue Jun 25, 2019 3:06 pm
   Subject: Re: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Cool, thanks for sharing that.

_________________
"Way too many #ifdefs in the code!" - John Carmack
Ringman
DieHard Wolfer
DieHard Wolfer


Joined: 31 Jul 2003
Last Visit: 15 Jul 2019

Topics: 56
Posts: 1180
Location: up my nose
usa.gif

PostPosted: Sun Jul 14, 2019 11:09 am
   Subject: Re: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Ok, I tried doing this but I got really confused about how ROTT is actually handling all of it.

I assumed it was raycasting as normal and if it hit a maskedwall it would store the "post" in a list somewhere than continue casting.

When it came time to draw sprites and whatnot it would merge the post with the sprite list and sort them by depth, then draw as normal.
However it almost appears that it doesn't seem to be doing that. Which methods should I be focusing on here?
I tried doing the method I just mentioned above myself in the wolf3d code, but I ran into so many problems because of all the global variables, like postsource, lasthit, that it caused some serious issues. I'd rewrite the raycaster code entirely to be much simpler but I'm not sure if its worth doing that.

So if you have the time can show me the quick and dirty of what you did. It doesn't have to be exact.

_________________
One day I saw upon a stair a little man who wasn't there. He wasn't there again today. My gosh I'd wish he'd go away.
Aryan_Wolf3D
DieHard Guard
DieHard Guard


Joined: 21 Jul 2011
Last Visit: 15 Oct 2019

Topics: 6
Posts: 256

blank.gif

PostPosted: Sun Jul 14, 2019 2:48 pm
   Subject: Re: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

OK, first off, no, ROTT's masked walls are NOT drawn via the raycaster (if you check the routines Cast & InitialCast in ENGINE.C, notice how it just continues the while loop if "tilemap & 0x4000" is 1.) They're pretty much the same deal as Ripper's 3D sprites, but with proper clipping.

So first off, you should set up a new struct and objlist for the masked walls, and rearrange tilemap so that you have a BIT_MASKED flag between BIT_WALL and BIT_DOOR (this is assuming you're using Chris' tutorial, I'm not going to get into all that stuff here.) Then just hack up the door code in wl_act1.cpp to have a masked wall spawning routine and call it in SetupGameLevel. The reason I did this is because it's much easier to deal with the wall plane rather than the object plane with the interpolation, because of the god awful way the sprites are stored.

Right, now in rendering time we need to make sure all the walls are drawn first, so in AsmRefresh, tell the loops to skip BIT_MASKED when checking for "tilehit". Then in DrawScaleds, you can pretty much copy + paste what you see in RoTT's version. Then you need this stuff:

1: TransformPlane
2: TransformSimplePoint
3: TransformPoint
4: InterpolateMaskedWall
5: A few members added to visstruct

The first 3 are more or less a copy + paste job, but you need to use 16 bit integers for the heights and divide nx by 256. For example, where they put "*height = heightnumerator/nx;", replace it with what Wolf uses (i.e. nx >> 8.) You'll also need to change the minimum allowed distances to something larger than 10 (0x2700 should be alright), and change the 20000 << HEIGHTFRACTION stuff to 0 (not sure if 0 is the best number, you could try using 0x7fff instead.)

And now for InterpolateMaskedWall... That's not a simple copy + paste, because it uses RoTT's sprite format, plus the VGA mask hassle that had to be dealt with back then. So to save you some pain, here's something for you to try...

::: CODE :::
void InterpolateMaskedWall (void)
{
    int      i;
    byte     *curshades,*src;
    uint16_t texoffs;
    int16_t  d1,d2;
    int16_t  dh,dx;
    int16_t  scale;
    int32_t  top,topinc;
    int32_t  bot,botinc;
    int32_t  height;

    dx = farthest->x2 - farthest->x1 + 1;

    if (farthest->h1 <= 0 || farthest->h2 <= 0 || !dx)
        return;

    src = PM_GetPage(farthest->shapenum);

    //
    // set shading
    //
    if (farthest->flags & FL_FULLBRIGHT)
        curshades = shadetable[0];
    else
        curshades = shadetable[GetShade(farthest->viewheight)];

    d1 = TILEGLOBAL / farthest->h1;
    d2 = TILEGLOBAL / farthest->h2;
    dh = (((farthest->h2 - farthest->h1) << 8) + 128) / dx;

    topinc = FixedMulShift(d1,farthest->textureend - farthest->texturestart,TEXTUREFROMFIXEDSHIFT);
    botinc = d1 - d2;

    if (farthest->x1 >= viewwidth)
        return;

    top = 0;
    bot = d2 * dx;
    height = farthest->h1 << 8;

    for (i = farthest->x1; i <= farthest->x2; i++)
    {
        scale = height >> 8;

        if ((i >= 0 && i < viewwidth) && bot && wallheight[i] <= scale)
        {
            texoffs = ((top / bot) + (farthest->texturestart >> TEXTUREFROMFIXEDSHIFT)) & TEXTUREMASK;
            postx = i;
            postsource = &src[texoffs];

            ScaleMaskedPost (scale,texoffs,curshades,farthest->flags);
        }

        top += topinc;
        bot += botinc;
        height += dh;
    }
}


void ScaleMaskedPost (int16_t scale, uint16_t texoffs, byte *curshades, uint32_t flags)
{
    byte    col;
    int16_t ywcount,yw,height;
    int32_t yoffs,yendoffs;

    ywcount = height = postheight >> 3;

    yoffs = ((centery - ywcount) * vbufPitch) + postx;

    if (yoffs < postx)
        yoffs = postx;

    yw = TEXTURESIZE - 1;

    for (yendoffs = (centery + ywcount) - 1; yendoffs >= viewheight; yendoffs--)
    {
        ywcount -= (TEXTURESIZE >> 1);

        while (ywcount <= 0)
        {
            ywcount += height;
            yw--;
        }
    }

    yendoffs = (yendoffs * vbufPitch) + postx;

    curshades = shadetable[GetShade(postheight)];

    if (curshades[postsource[yw]] == 0xff)
        col = postsource[yw];
    else
        col = curshades[postsource[yw]];

    while (yoffs <= yendoffs)
    {
        if (col != 0xff)
            vbuf[yendoffs] = col;

        ywcount -= (TEXTURESIZE >> 1);

        if (ywcount <= 0)
        {
            while (ywcount <= 0)
            {
                ywcount += height;
                yw--;
            }

            if (yw < 0)
                return;

            if (curshades[postsource[yw]] == 0xff)
                col = postsource[yw];
            else
                col = curshades[postsource[yw]];
        }
       
        yendoffs -= vbufPitch;
    }
}


Note that it's safe to use the global variables postx & postsource here, since the wall drawing has already been completed.

I think that's more or less everything... Though you need FixedScale and FixedMulShift:

::: CODE :::
fixed FixedScale (fixed orig, fixed factor, fixed divisor)
{
   int64_t x = orig;
   int64_t y = factor;
   int64_t z = divisor;
   
   int64_t w = (x * y) / z;
   
   return w & 0xffffffff;
}

fixed FixedMulShift (fixed a, fixed b, fixed shift)
{
    int64_t x = a;
   int64_t y = b;
   int64_t z = x * y;
   
   return (((uint64_t)z) >> shift) & 0xffffffff;
}


Note that the divisor is assumed to be a non-zero value. Wink

Alright, that should be about it. Let me know if you get it to work, or if I missed anything (which I probably did!)

_________________
"Way too many #ifdefs in the code!" - John Carmack
Ringman
DieHard Wolfer
DieHard Wolfer


Joined: 31 Jul 2003
Last Visit: 15 Jul 2019

Topics: 56
Posts: 1180
Location: up my nose
usa.gif

PostPosted: Mon Jul 15, 2019 2:34 am
   Subject: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

No, that's fine. I think I needed more of verification than anything else. I thought I was going nuts there for a second. I should've imported the ROTT code into a project so I could search it easier. I couldn't figure out where the struct visobj_t (farthest as the instance in your case) actually defined.

Question:
If you can define x1, x2 and y1 y2 here, can you have non 90 degree walls?
At first glance, I can't seem to see how this handles the drawing order of a sprite that is really close to a maskwall. It seems to me if you don't sort visibility by post you are going to have some drawing bugs where a sprite flashes in front of a mask wall depending on the angle of the view. Like if a sprite is standing in the middle of an archway and the archway is at an angle to your viewplane. In that case you should see part of the maskwall covering one half of the sprite, then the sprite, then the rest of the maskwall behind the sprite.
I'm worried you'll see this:

when you should see this:

Is that being addressed somehow?

_________________
One day I saw upon a stair a little man who wasn't there. He wasn't there again today. My gosh I'd wish he'd go away.
Aryan_Wolf3D
DieHard Guard
DieHard Guard


Joined: 21 Jul 2011
Last Visit: 15 Oct 2019

Topics: 6
Posts: 256

blank.gif

PostPosted: Mon Jul 15, 2019 4:36 am
   Subject: Re: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Ringman wrote:
No, that's fine. I think I needed more of verification than anything else. I thought I was going nuts there for a second. I should've imported the ROTT code into a project so I could search it easier. I couldn't figure out where the struct visobj_t (farthest as the instance in your case) actually defined.

Ah yes, farthest will need to be declared globally. Or you could just pass it as a pointer argument in InterpolateMaskedWall. I think RoTT's visstruct is in RT_DRAW.H, right? You might want to use int16_t for the new members instead of int.

Quote:
Question:
If you can define x1, x2 and y1 y2 here, can you have non 90 degree walls?

I don't know, I haven't explored that possibility.

Quote:
At first glance, I can't seem to see how this handles the drawing order of a sprite that is really close to a maskwall. It seems to me if you don't sort visibility by post you are going to have some drawing bugs where a sprite flashes in front of a mask wall depending on the angle of the view. Like if a sprite is standing in the middle of an archway and the archway is at an angle to your viewplane. In that case you should see part of the maskwall covering one half of the sprite, then the sprite, then the rest of the maskwall behind the sprite.
I'm worried you'll see this:

when you should see this:

Is that being addressed somehow?

Unfortunately not, since sprites are sorted only by their "height". What you show in those pictures does indeed happen, though it's not very noticeable. I don't know if there is a good way around this, because the back to front sorting is the only way to get the transparency to work. At first I did have masked walls working via the raycaster using a list of stored posts that got sorted and drawn with the sprites in DrawScaleds after the walls, but I couldn't figure out how to stop the masked walls from "flipping" around to face the player when looking at a horizontal masked wall plane from a vertical viewpoint, and vice versa (noclip inside a door tile and look at it from the side to see what I mean.) It was also pretty slow when drawing a lot of masked walls behind each other, because the amount of posts to loop over and draw could get pretty insane, especially at high resolutions. And with transparency, you can't easily prevent the overdraw.

I also had masked doors working with it, but I haven't got them to work with RoTT's stuff yet, since I'm not sure how to calculate the texture with the door position. Funnily enough, RoTT's doors used 2 drawing methods... If the door is fully closed, it uses the raycaster, but otherwise they're drawn as sprites using interpolation similar to the masked walls.

Once again though, I favour using walls because you don't have to mess around with the annoying "linecmds" pointer stuff to deal with the sprite compression. Plus it's easier to keep track of them in tilemap instead of looping through statobjlist.

_________________
"Way too many #ifdefs in the code!" - John Carmack
Ringman
DieHard Wolfer
DieHard Wolfer


Joined: 31 Jul 2003
Last Visit: 15 Jul 2019

Topics: 56
Posts: 1180
Location: up my nose
usa.gif

PostPosted: Mon Jul 15, 2019 7:29 am
   Subject: Re: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Alot of what you are talking about goes back to my original hand coded raycaster, which I found the latest version of that, but again it did things differently and was written in java.
Anyway, the flipping you mention, is taken care of by only adding a post if there is an actual connection between the ray and the wall. To do that, you have to actually calculate an intersection in the square itself. Which means you need the x1,y1 x2,y2, and the vector and origin of your camera. If the line is intersected, you draw, otherwise you don't. This means you can't really have "side door walls" like rott does, but it does allow you to do some crazy things.
Finally, on the nature of too many posts to loop through to avoid sorting altogether you can make the wallheight array a 2d buffer instead of a 3d one, then store the heights of any "drawn" pixels, but this doesn't allow for translucency. The other option is to merge the 2 pre-sorted lists (maskwalls and sprites) to avoid too many loops caused by the sort. http://www.codebind.com/cpp-tutorial/cpp-example-merge-sort-algorithm/

_________________
One day I saw upon a stair a little man who wasn't there. He wasn't there again today. My gosh I'd wish he'd go away.
Aryan_Wolf3D
DieHard Guard
DieHard Guard


Joined: 21 Jul 2011
Last Visit: 15 Oct 2019

Topics: 6
Posts: 256

blank.gif

PostPosted: Mon Jul 15, 2019 11:07 am
   Subject: Re: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Ringman wrote:
Anyway, the flipping you mention, is taken care of by only adding a post if there is an actual connection between the ray and the wall. To do that, you have to actually calculate an intersection in the square itself. Which means you need the x1,y1 x2,y2, and the vector and origin of your camera. If the line is intersected, you draw, otherwise you don't. This means you can't really have "side door walls" like rott does, but it does allow you to do some crazy things.

That sounds promising, but it's somewhat beyond my skill at present.

Quote:
Finally, on the nature of too many posts to loop through to avoid sorting altogether you can make the wallheight array a 2d buffer instead of a 3d one, then store the heights of any "drawn" pixels, but this doesn't allow for translucency. The other option is to merge the 2 pre-sorted lists (maskwalls and sprites) to avoid too many loops caused by the sort. http://www.codebind.com/cpp-tutorial/cpp-example-merge-sort-algorithm/

The masked posts themselves don't need to be sorted, but with potentially a few thousand posts needing to be drawn (many of them redundant because of overdraw), that's a lot of work for the renderer to do.

_________________
"Way too many #ifdefs in the code!" - John Carmack
Ringman
DieHard Wolfer
DieHard Wolfer


Joined: 31 Jul 2003
Last Visit: 15 Jul 2019

Topics: 56
Posts: 1180
Location: up my nose
usa.gif

PostPosted: Mon Jul 15, 2019 1:56 pm
   Subject: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

This talks a lot about the things we've been discussing:
https://lodev.org/cgtutor/raycasting4.html

_________________
One day I saw upon a stair a little man who wasn't there. He wasn't there again today. My gosh I'd wish he'd go away.
Tricob
Moderator
<B>Moderator</B>


Joined: 14 Mar 2005
Last Visit: 16:18 ago.

Topics: 167
Posts: 8451
Location: Neo-traditions, Inc.
usa.gif

PostPosted: Mon Jul 15, 2019 6:41 pm
   Subject: Re: Clipping on y plane directional 3d sprites bug
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Bottom of Posts

Ringman wrote:
Question:
If you can define x1, x2 and y1 y2 here, can you have non 90 degree walls?
At first glance, I can't seem to see how this handles the drawing order of a sprite that is really close to a maskwall. It seems to me if you don't sort visibility by post you are going to have some drawing bugs where a sprite flashes in front of a mask wall depending on the angle of the view. Like if a sprite is standing in the middle of an archway and the archway is at an angle to your viewplane. In that case you should see part of the maskwall covering one half of the sprite, then the sprite, then the rest of the maskwall behind the sprite.
I'm worried you'll see this:

when you should see this:

Is that being addressed somehow?

My solution was spawning two different objects in the same square in WL_GAME.CPP. It looked something like this:
::: CODE :::
                case 15:
                    SpawnStatic(x,y,63);
                    SpawnStatic(x,y,64);
                    break;
The sprite you wanted overlapped should always be the first of these two objects. The catch is that you have to know *exactly* what the object numbers are in the code for this to work. There's probably a better way of writing this code, but I don't know what it is just yet. Sad
Display posts from previous:   
Post new topicReply to topic Time synchronized with the forum server time
DieHard Wolfers Forum Index -> Code Crackers View Previous TopicRefresh this PageAdd Topic to your Browser FavoritesSearch ForumsPrint this TopicE-mail TopicGoto Page TopView Next Topic
Page 1 of 1
Jump to:  

Related topics
 Topics   Replies   Views   Last Post 
No new posts Sticky: [Info] Compiling the Source Code...
Author: Guest
52 5275 Sat Feb 10, 2007 12:38 pm
Harry sr View latest post
No new posts [Info] Black & White Effect - Tutorial
Author: Guest
10 299 Thu Mar 17, 2005 6:24 pm
Dugtrio17 View latest post
No new posts [Code] Run with Stamina - TekZK
Author: BrotherTank
8 3793 Sun May 16, 2004 12:54 am
Codetech84 View latest post
This topic is locked: you cannot edit posts or make replies. [Info] Source code for Darkone's NewWolf Classic
Author: Raistlin
1 2108 Tue Feb 10, 2004 10:18 am
BrotherTank View latest post
No new posts [Info] Slideshows Between Levels? - SoD side of Code
Author: Hair Machine
2 1865 Fri Dec 26, 2003 11:02 am
jamez View latest post
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
   You cannot delete your posts in this forum
You cannot vote in polls in this forum


Copyright ©2003-2008 DieHard Wolfers
A Modified subBunker Theme by BrotherTank
Powered by phpBB © 2001, 2005 phpBB Group