Game Development Community

Drawing simple lines

by Nicolas Stohler · in Torque Game Builder · 06/20/2006 (5:21 am) · 18 replies

Hello

I just wondered if its possible to draw a simple line in TGB. I want to connect 2 points with a "1 pixel" (clearly visible) line of color x with blending y. Is this directly supported by the engine?

--
Nicolas

#1
06/22/2006 (9:22 am)
Bump...
is this really not possible? or am I posting to the wrong forum?

--
Nicolas
#2
06/22/2006 (10:10 am)
I was wondering a bit of the same thing.. any way to do vector graphics (a la Tempest) with TGB ?
#3
06/22/2006 (10:16 am)
I was also wondering how to draw a simple line... I had considered making 2 images with diagonal lines ( / & \ ) and using a similar method to this: http://tdn.garagegames.com/wiki/Torque_2D/GenreTutorials/StrategyMouseSelections to resize the image between two points.
#4
06/22/2006 (11:11 am)
My understanding from reading through the TGB reference doc is that this is NOT possible as I've not seen any function designed to accomplish this. The work around seems to be to use a sprite and dynamically resize it as described in the strategy tutorial. You could also probably also use a one pixel sprite and dynamically create and position a new instance of it as the user drags the mouse. Not optimal but it would work up to a point.

I would love to see this added as well but I assume there are some challenges in getting it implemented or it would probably already be in TGB.
#5
06/22/2006 (11:30 am)
There is a shape vector class in the engine. We haven't documented it or really talked about it because it's not as polished as we would like it to be. Also because of that, it's not exposed to the level builder. If you want to use it though, create a t2dShapeVector object like so:
$shape = new t2dShapeVector();
Then pop open the console by pressing '~' and type $shape.dump(); That will give you a list of the supported functions and usage should be self explanitory from there.

And yes, this is something we want to have full support for in the future.
#6
06/22/2006 (11:57 am)
Is there a way to do a button which makes me ridiculously rich when I press it?

I'm just asking because so far everything I'm looking for *IS* in TGB ;-) Can't fault a guy for trying...

Thanks guys!
#7
06/22/2006 (12:04 pm)
Do keep in mind that one of the reasons it's not yet polished is that Torque is a raster based rendering system, and vector based graphics were actually put together originally due to being extremely fast in the past against raster based systems--net result being that currently, it's not very optimized at all.

I can't guarantee it will get any faster, but that is one of the reasons why it didn't make it officially into the current release.
#8
06/22/2006 (12:11 pm)
Nice! Thanks for the inside tip. Even if it's not completely optimized I would imagine that it'll still be useful for smaller tasks.
#9
06/26/2006 (8:12 am)
So i'm trying to figure out how to use this, and i'll have to admit i could use alittle help...

here is what i currently have:

where %firstCountry and %secondCountry are both t2dstaticsprites, and get position difference just gets the difference between the X or Y of two t2dstaticsprites


%link = new t2dshapevector()
     {
          scenegraph = SceneWindow2D.getSceneGraph();
     };
     %link.setPosition(%firstCountry.getPosition());
     %link.setLinearVelocityX(getPositionDifference(%firstCountry,%secondCountry,0));
     %link.setLinearVelocityY(getPositionDifference(%firstCountry,%secondCountry,1));
     %link.setLayer($countryLayer);
     %link.setGraphGroup($countryGroup);
#10
06/27/2006 (7:14 am)
Bump.

SetPosition looks like it sets the first point, how do i set the second?
#11
06/27/2006 (8:19 am)
Hey Paul, is that getPositionDifference your own code, or is that built in?
#12
06/27/2006 (10:33 am)
It's mine
function getPositionDifference(%first,%second,%getWordVal)
{
    return getDifference(%first.getPosition(),%second.getPosition());
}

function getDifference(%first, %second, %getWordVal)
{
    return( getWord(%first,%getWordVal) - getWord(%second,%getWordVal) );
}
#13
06/27/2006 (11:19 am)
It would be more efficient to use the native vector functions. For example:

%difference = t2dVectorSub(%pos1,%pos2);
#14
06/27/2006 (12:19 pm)
Will that draw my vector? or just calculate the difference?
My original example doesn't draw a line...
#15
06/27/2006 (12:24 pm)
The object dump didn't make it clear to me (but it's great to know that this method exists, I didnt know that before). I had to take a look at the source code to figure this out.

So, here is a very simple sample that just draws a green (rotating) line. You can create a new project with TGB and paste the following code at the end of the startGame function (in your gameScripts/game.cs file). then just run it to see the line in action.

$shape = new t2dshapevector()
{
  scenegraph = sceneWindow2D.getSceneGraph();
};

$shape.setPosition( "0 0" );                        // start of polygon, rotation will be around this point!
$shape.setLineColor( "0.0 1.0 0.0 1.0" );    // red line

$shape.setSize( "50 50" );                          // overall size of polygon

// horizontal line
$shape.setpolycustom( 2, "0 0 1.0 0.0" );     

// 3 vertex poly:
//$shape.setpolycustom( 3, "0.0 0.0" SPC "0.3 0.4" SPC "1.0 0.0"  );

// 4 vertex poly:
//$shape.setpolycustom( 4, "0.0 0.0" SPC "0.1 0.5" SPC "0.6 0.4" SPC "1.0 0.0"  );

$shape.setRotation( 0 );
$shape.setAutoRotation( 30 );

you can also uncomment the 3/4 vertex polygon samples to take a look at those. I dont know if there's a small bug in there, it looks like its not possible (yet) to draw a concave polygon using this method...

have fun
--
Nicolas
#16
06/28/2006 (8:50 am)
This is for in 3 months (or years) when someone finds this thread its complete. Someone should probalby publish this whole thread as a t2d resource, (Not It).

This code needs to be cleaned up.. it just doesn't seem right that tan != sin = cos


This example is for a risk game, so the country's passed in are t2dstaticsprites, but you could just as simply pass in two quordinates and remove all hte calls to .getPosition()
(the size must be 2x the length of the line BECAUSE, the size is mesured from left to right, not from the center on out
function DrawLineBetween(%firstCountry, %secondCountry)
{
     %link = new t2dshapevector()
     {
          scenegraph = SceneWindow2D.getSceneGraph();
     };
     %link.setPosition(%firstCountry.getPosition());
     %link.setLineColor( "0.0 1.0 1.0 1.0" );    // blue line
     %link.setSize(2 * t2dVectorDistance(%firstCountry.getPosition(),%secondCountry.getPosition()),2 *VectorDist(%firstCountry.getPosition(),%secondCountry.getPosition())  );
     %link.setLayer($countryLayer);
     %link.setGraphGroup($countryGroup);
     %link.setpolycustom( 2, "0 0 1.0 0.0" );
     %link.setRotation(getAngleBetween(%firstCountry.getPosition(), %secondCountry.getPosition() )  );
}

function getAngleBetween(%first,%second)
{
    %hyp = t2dVectorDistance(%first,%second);
    %x1 = getword(%first,0);
    %x2 = getword(%second,0);
    %y1 = getword(%first, 1);
    %y2 = getword(%second,1);
    if(%x1 > %x2){
        %adj = %x1 - %x2;
    }else if(%x1 < %x2){
        %adj = %x2 - %x1;
    }else{
        %adj = 0;
    }
    if(%y1 > %y2){
        %opp = %y1 - %y2;
    }else if(%y1 < %y2){
        %opp = %y2 - %y1;
    }else{
        %opp = 0;
    }
        %sinval = mRadtoDeg(mAsin(%adj/%hyp)); //cos
        %cosval = mRadtoDeg(mAcos(%opp/%hyp)); //sin
        %tanval = mRadtoDeg(mAtan(%opp,%adj)); //tan
    
    if(%x1 > %x2 && %y1 > %y2){
        %degrees = %tanval + 180;
    }else if(%x1 > %x2 && %y1 < %y2){
        %degrees = %sinval + 90;
    }else if(%x1 < %x2 && %y1 < %y2){
        %degrees = %tanval + 0;
    }else if(%x1 < %x2 && %y1 > %y2){
        %degrees = %cosval + 270;
    }
        error(%sinval SPC %cosval SPC %tanval SPC %degrees);
    return %degrees;
}

freaking win...
#17
06/28/2006 (5:21 pm)
Minor modification:
Right before:
%sinval = mRadtoDeg(mAsin(%adj/%hyp)); //cos
        %cosval = mRadtoDeg(mAcos(%opp/%hyp)); //sin
        %tanval = mRadtoDeg(mAtan(%opp,%adj)); //tan

put in:
if(%adj == 0 || %opp == 0){
        if(%adj == 0 && %y1 > %y2){
            return 270;
        }else if(%adj == 0 && %y1 < %y2){
            return 90;
        }else if(%opp == 0 && %x1 > %x2){
            return 180;
        }else if(%opp == 0 && %x1 < %x2){
            return 0;
        }
    }

also %cosval & %sinval have the same value, so you could delete one of them, and use it in place of the other.
#18
07/01/2006 (4:06 pm)
I've been using t2dShapeVectors and so far, so good. Overall, it seems to be a fairly minimal hit even with a lot of dynamic scaling for simple shapes/lines. The only question I have for either GG or any others out there is what the most efficient method is for making a circle.

Currently I'm using this: $Shape.setPolyPrimitive( 50 ) to get a nice, smooth circle. But I'm wondering if there's any built-in way to draw a vector circle that doesn't use as many polys and/or is more efficient. Right now, I notice that the framerate dips by about 20-30 fps when I resize this circle dynamically. Is this an example of the unoptimized performance issue that was mentioned or am I just creating a circe in the wrong way?

Even with this minor issue, t2dSchapeVector has been a huge life saver. Thanks again for calling it out.