XNA Creators Club Online
Page 1 of 1 (11 items)
Sort Posts: Previous Next

spot the mistake... please

Last post 06/07/2009 1:23 by Thundy. 10 replies.
  • 02/07/2009 15:20

    spot the mistake... please

    im using the following code to perform a quick ray test across my terrain, and draw a flag at the output co-ordinates. It uses bilinear interpolation to scan along the camera look at line until it hits the terrain, and then return the flag co-ordinates.
    well thats the theory, it isnt working though :S

     public void raytest2()  
            {  
                Vector3 dir = cameraLookAt - dudepos;  
                for (float x = cameraLookAt.X; x > dudepos.X; x -= (dir.X / 50))  
                {  
                    for (float y = cameraLookAt.Z; y > dudepos.Z; y += (dir.Z / 50))  
                    {  
                        for (float z = cameraLookAt.Y +1; z > dudepos.Y; z += (dir.Y/50))  
                        {  
                            int x0 = (int)x;  
                            int y0 = -(int)y;  
                            double dx = x- x0;  
                            double dy = -y - y0;  
                            double omdx = 1 - dx;  
                            double omdy = 1 - dy;  
                            double bilinear = omdx * omdy * heightData[x0, y0] +  
                            omdx * dy * heightData[x0, y0 + 1] +  
                            dx * omdy * heightData[x0 + 1, y0] +  
                            dx * dy * heightData[x0 + 1, y0 + 1];  
     
                            if (z < bilinear)  
                        {  
                            flagpos =  new Vector3(x0,y0,(float)bilinear);  
                        }  
     
                        }  
                    }  
                }  
            } 
    can anyone see what im doing wrong?
  • 02/07/2009 15:36 In reply to

    Re: spot the mistake... please

    ignore the y and z co-ordinates being backwards, i spotted that and fixed it but its still not working
  • 02/07/2009 19:26 In reply to

    Re: spot the mistake... please

  • 03/07/2009 19:31 In reply to

    Re: spot the mistake... please

    well its supposed to move from the camera look at position, towards the camera, and everytime it crosses the terrain y value, return the position as a vector 3, so that you get the exact position that the camera is looking at on the terrain, and then draw an object at that position, which will of course act as a targetting aid. but its not doing it.
  • 04/07/2009 8:38 In reply to

    Re: spot the mistake... please

    From a quick look I think you have your coordinate space all messed up, and it is very inefficent code.

    For a start look at the Ray class, or even just use the Vector3 class to do your walking.

    stuff like

       Vector3 step = (current-target)/steps;  
       for (int i=0; i<steps; i++)  
       {  
            CheckCollide(current);  
            current+=step;  
       } 

    Will make the code easier to read and maintain.

    For a better solution have a look at http://creators.xna.com/en-GB/sample/collision3dheightmapnormals

    Information is not knowledge, knowledge is not wisdom, wisdom is not truth, truth is not beauty, beauty is not love, love is not music, music is the best! Wisdom is the domain of the Wis (which is extinct).
  • 04/07/2009 13:22 In reply to

    Re: spot the mistake... please

    Well with regards to my co-ordinate space. I use bilinear interpolation in my code to check the dude model itself is on the gound and that works fine, i tried using the ray class, to check where the camera was looking but it takes far too long, what i want is a real-time way of checking.

    I should explain a bit more about what i have, and what im trying to achieve before i go on.

    I have a character, in a third person view, offset to the left a little so as not to obscure the camera's view of whats in front.
    in the dead center of the screen i have a targetting reticle, camera look at is set to the dude model's velocity *250 i.e directly ahead of him at a fair distance away.

    what i want to be able to do is draw a small targetting flag model, where the camera is looking.
    When its looking at the sky i.e no terrain in the way, it draws ok. But i want to check the camera look at line, and IF it collides with the terrain, draw the targetting flag at that position rather then at the camera look at position, therefore indicating where on the terrain, a projectile would land, if it were to travel along the camera look at line.
  • 05/07/2009 10:07 In reply to

    Re: spot the mistake... please

    Well a couple of things spring to mind.

    Firstly all the bilinear code is based on x and y, so there is no need to have it inside the z loop.

    I'm not sure why you use -y instead of y...

    Secondly the z loop can be removed completely and replaced by a bounds check

    However thinking about it conceptually, this code can return a false value all the time. Consider the case when the ray from the dude hits the terrain 50% of the way to the target.

    The code will return the end of the ray, as it sets flagpos every step from 50% to 100%
    Information is not knowledge, knowledge is not wisdom, wisdom is not truth, truth is not beauty, beauty is not love, love is not music, music is the best! Wisdom is the domain of the Wis (which is extinct).
  • 05/07/2009 12:18 In reply to

    Re: spot the mistake... please

    Aye the plan was to have the check going from the final camera look at position and move towards the camera, thus returning the nearest collision with the terrain as the flagpos value. as for the z loop, i think i may have been having a brain fart, ironically im still having that brain fart as i cant remember why i got round to putting that in.


    the -y value, Bearing in mind that (apart from the code snippet where i got the back to front) y corresponds to the z value on the terrain, as its the y value of the terrain that were looking for, all the z co-ordinates are represented in negative values as thats the way the terrain is oriented from the 0,0 point.
  • 05/07/2009 21:47 In reply to

    Re: spot the mistake... please

    it would be better to start at the camera and walk towards the end point, then the first time you get a collision, you can stop processing.

    have a look at this, may save you a lot of time.

    http://www.nuclex.org/news?page=5

    Information is not knowledge, knowledge is not wisdom, wisdom is not truth, truth is not beauty, beauty is not love, love is not music, music is the best! Wisdom is the domain of the Wis (which is extinct).
  • 06/07/2009 1:00 In reply to

    Re: spot the mistake... please

    Thanks for the link. i had a wee lookie at it and will probably use it in future, in the instance of this project though, it would require a radical restructure of my code to implement it. I have made progress however in my raytest() method, which i will list below. My only problem now is that my Camera's up down rotation, doesnt seem to be linked to the camera look at position in a linear way. which is something i will look into and see if i can solve it. anyway my current method is this -->
    public void raytest()  
            {  
                VertexMultitextured[] terrainVertices = SetUpTerrainVertices();  
                Vector3 farSource = (cameraLookAt);  
                Vector3 nearSource = (dudepos);  
                testvelocity = dudevelocity / 2;  
                testvelocity.Y = (cameraLookAt.Y - (dudepos.Y + 1) / 5);  
     
                tesposition = dudepos;  
                tesposition.Y = cameraPosition.Y + 1;  
                for (int i = 0; i < 100; i++)  
                {  
                    if (tesposition.X > terrainLength - 10)  
                    {  
                        tesposition.X = terrainLength - 10;  
                    }  
                    if (tesposition.Z < -terrainWidth - 10)  
                    {  
                        tesposition.Z = -terrainWidth - 10;  
                    }  
                    if (tesposition.X < 10)  
                    {  
                        tesposition.X = 10;  
                    }  
                    if (tesposition.Z > -10)  
                    {  
                        tesposition.Z = -10;  
                    }  
                    int x0 = (int)tesposition.X;  
                    int y0 = -(int)tesposition.Z;  
                    double dx = tesposition.X - x0;  
                    double dy = -tesposition.Z - y0;  
                    double omdx = 1 - dx;  
                    double omdy = 1 - dy;  
                    double bilinear = omdx * omdy * heightData[x0, y0] +  
                    omdx * dy * heightData[x0, y0 + 1] +  
                    dx * omdy * heightData[x0 + 1, y0] +  
                    dx * dy * heightData[x0 + 1, y0 + 1];  
                    tesposition += testvelocity;  
                    if (tesposition.Y < (float)bilinear)  
                    {  
                        i = 1000;  
                        tesposition.Y = (float)bilinear;  
     
                    }  
                }  
                  
            } 
  • 06/07/2009 1:23 In reply to

    Re: spot the mistake... please

    ok i have got it working. its not pixel perfect accuracy, however its a start, dont ask me why im dividing my up down velocity by 47, i havent got a clue WHY it works like that, it just does. its not fast enough to run constantly, so i have it set on a mouse click, sort of as an indicator that if you were to click the mouse, that would be where the projectile would hit. anyway heres the code

    public void raytest()  
            {  
                VertexMultitextured[] terrainVertices = SetUpTerrainVertices();  
                Vector3 farSource = (cameraLookAt);  
                Vector3 nearSource = (dudepos);  
                testvelocity = dudevelocity;  
                testvelocity.Y = (((cameraLookAt.Y) - (cameraPosition.Y + 0.5f)) / 47);  
                found = false;  
                tesposition = cameraPosition;  
                tesposition.Y = cameraPosition.Y + 0.5f;  
                for (int i = 0; i < 100; i++)  
                {  
                    if (tesposition.X > terrainLength - 10)  
                    {  
                        tesposition.X = terrainLength - 10;  
                    }  
                    if (tesposition.Z < -terrainWidth - 10)  
                    {  
                        tesposition.Z = -terrainWidth - 10;  
                    }  
                    if (tesposition.X < 10)  
                    {  
                        tesposition.X = 10;  
                    }  
                    if (tesposition.Z > -10)  
                    {  
                        tesposition.Z = -10;  
                    }  
                    int x0 = (int)tesposition.X;  
                    int y0 = -(int)tesposition.Z;  
                    double dx = tesposition.X - x0;  
                    double dy = -tesposition.Z - y0;  
                    double omdx = 1 - dx;  
                    double omdy = 1 - dy;  
                    double bilinear = omdx * omdy * heightData[x0, y0] +  
                    omdx * dy * heightData[x0, y0 + 1] +  
                    dx * omdy * heightData[x0 + 1, y0] +  
                    dx * dy * heightData[x0 + 1, y0 + 1];  
                    tesposition += testvelocity;  
                    if (tesposition.Y < (float)bilinear)  
                    {  
                        i = 1000;  
                        tesposition.Y = (float)bilinear;  
                        found = true;  
     
                    }  
                }  
                if (found == false)  
                {  
                    tesposition = cameraLookAt;  
                }  
            } 
Page 1 of 1 (11 items) Previous Next
var gDomain='m.webtrends.com'; var gDcsId='dcschd84w10000w4lw9hcqmsz_8n3x'; var gTrackEvents=1; var gFpc='WT_FPC'; /*<\/scr"+"ipt>");} /*]]>*/
DCSIMG