Jump to content
Sign in to follow this  
VirtualLink

Help! Cells On A Texture

Recommended Posts

Sorry moved!

Trying to take a texture that has 8 rows and 8 columns and when I state a cell number it sets that row and column on command. So far I have it pulling from the center of the texture and well I want to start at the top go across in order. 

R1 C1 C2 C3

R2 C1 C2 C3

R3 C1 C2 C3 etc

 

ShowNumber(integer num, integer face)
{

    integer Row = num * 8;

    integer Col = num * 8;

    llOffsetTexture(0.0620 + 0.125 * Col, 0.0620 + 0.125 * Row, face);

}

default
{

    state_entry()
    {
        ShowNumber(12, ALL_SIDES);
    }
}

Edited by VirtualLink

Share this post


Link to post
Share on other sites

Trying to take a texture that has 8 rows and 8 columns and when I state a cell number it sets that row and column on command. So far I have it pulling from the center of the texture and well I want to start at the top go across in order. 

R1 C1 C2 C3

R2 C1 C2 C3

R3 C1 C2 C3 etc

 

ShowNumber(integer num, integer face)
{

    integer Row = num * 8;

    integer Col = num * 8;

    llOffsetTexture(0.0620 + 0.125 * Col, 0.0620 + 0.125 * Row, face);

}

default
{

    state_entry()
    {
        ShowNumber(12, ALL_SIDES);
    }
}

Share this post


Link to post
Share on other sites

I've not used the function you're showing in your snippet, I've always used llSetPrimitiveParams, but the principle is the same. The offset figures you need are the ones that you would put into the build floater to get the required portion of the texture showing as you want it on the face, assuming that you are using default repeat and rotation values. If you need non-default values then llStPrimitiveParams is what you will have to use.

Columns will start from a negative number, through zero at the centre, to a positive number at the right (-1.0 to 1.0), Rows will start from a positive number at the top, moving through zero at the centre and then to a negative number at the bottom, (1.0 to -1.0).

The easiest way is to make up a pair of lists containing floats, one for the columns and one for the rows, with the offsets in them, just extract the floats from the two lists. To set a cell of row n and column m, index into the lists rowOffsets(n) and colOffsets(m) to get a pair of floats.

However, for your method of setting them by cell number, you are going to need a third list containing pairs of integers, such that cell n gives you integers for the appropriate column and row lists:  cell 0 = (row 0 offset) (col 0 offset), cell 1 = row 0 col 1, and so on. To access this list, you will need to multiply the cell number by 2, the row index is extracted from the list at this value, the column index at the next value. These two indexes then get you the float offsets from the two lists of row and column values.

(( The forum won't let me insert code tonight for some reason ))

list rowOffs = [0.5, 0.25, -0.25, -0.5];

list colOffs = [-0.5, -.25, 0.25, 0.5];

list cells = [0, 0, 0, 1, 0, 2, 0, 3, 1, 0, 1, 1, 1, 2, 1, 3 ....];

// to access cell 2, multiply by 2, element 4 of cells = 0, element 5 = 2,

// rowOffs [0] = 0.5, colOffs [2] = 0.25

// resulting texture offsets are 0.5, 0.25

 

 

Edited by Profaitchikenz Haiku

Share this post


Link to post
Share on other sites

that's what I would do my self but I recall some one stating using to many lists would cause lag and I'm all ready running 5 lists total in my 3 scripts. I found the idea from a script that would take a texture 1 - 99 and place a number on the face. Thing is theirs was 10 across and 10 down. For some odd reason when I would mod just their snippet is fails but works on there's on side numbering

 

// :CATEGORY:Building
// :NAME:Side_Numbering
// :AUTHOR:Xylor Baysklef
// :CREATED:2010-01-10 05:20:56.000
// :EDITED:2013-09-18 15:39:02
// :ID:751
// :NUM:1034
// :REV:1.0
// :WORLD:Second Life
// :DESCRIPTION:
// Side Numbering.lsl
// :CODE:


////////////////////////////////////////////

// Side Numbering Script

//

// Written by Xylor Baysklef

////////////////////////////////////////////



/////////////// CONSTANTS ///////////////////

key NUMBERS_TEXTURE = "fc8df679-ca1b-3ec9-c4ce-b1c832b5b5ce";

///////////// END CONSTANTS /////////////////



///////////// GLOBAL VARIABLES ///////////////

/////////// END GLOBAL VARIABLES /////////////



ShowNumber(integer num, integer face) {

    integer Row = num / 10;

    integer Col = num % 10;

    llOffsetTexture(-0.45 + 0.1 * Col, 0.45 - 0.1 * Row, face);

}



default {

    state_entry() {

        // Reset rotation, alpha, color and turn off animations.

        llRotateTexture(0.0, ALL_SIDES);

        llSetAlpha(1.0, ALL_SIDES);

        llSetColor(<1, 1, 1>, ALL_SIDES);

        llSetTextureAnim(FALSE, 0, 0, 0, 0, 0, 0);

        

        // Show the numbers texture.

        llSetTexture(NUMBERS_TEXTURE, ALL_SIDES);

        llScaleTexture(0.1, 0.1, ALL_SIDES);



        // Go through each side and show a number.

        integer i;

        for (i = 0; i < llGetNumberOfSides(); i++) {

            ShowNumber(i, i);

        }

    }

}

 

Share this post


Link to post
Share on other sites

look at how Xylor calculates row and column and compare to how you coded it. In the 8 case then following Xylor's lead:

integer row = num / 8;
integer col = num % 8;

results
num  row    col
0    0/8=0  0%8=0
1    1/8=0  1%8=1
2    2/8=0  2%8=2
7    7/8=0  2%8=7
8    8/8=1  8%8=0
9    9/8=1  8%8=1
10  10/8=1 10%8=2
17  17/8=2 17%8=1
38  38/8=4 36%8=6
40  40/8=5 40%8=0
62  62/8=7 62%8=6
63  63/8=7 63%8=7

 

Share this post


Link to post
Share on other sites

Lists don't produce lag. But making a list for such a simple calculation? And more lists for different grid sizes? Really?

I'm willing to throw in one on my little helper functions:

// input:
//		num = tile # starting at top left with # 0
//		x,y = grid size
//		face #
//		link #
//		texture uuid or name
set_link_texture_grid(integer num, integer x, integer y, integer face, integer link, string texture) {
	float	step_x = 1.0 / (float)x;
	float	step_y = 1.0 / (float)y;
	integer	part_x = num % x;
	integer	part_y = num / x;
	float	pos_y = -0.5+step_y/2.0 + step_y*(float)(y-part_y-1);
	float	pos_x = -0.5+step_x/2.0 + step_x*(float)part_x;
	llSetLinkPrimitiveParamsFast(link,[PRIM_TEXTURE,face,texture,<step_x,step_y,0>,<pos_x,pos_y,0>,0.0]);
}

 

Share this post


Link to post
Share on other sites

I agree that for small numbers of cells calculations might be simpler, it's a trade-off between that and pre-calculated lookups which might be quicker for a busy script doing lots of updates such as a message board.

Share this post


Link to post
Share on other sites

You can simplify things for repeating tasks by taking out the calculations that only need to be done once.

But how do you know that list operations are faster than a little math? I seriously doubt it but I'm way to lazy to make a test scenario for that.

And if you really think about performance - which is irrelevant in this case by my opinion - don't forget the memory consumption of lists.

Share this post


Link to post
Share on other sites

I don't know for certain in LSL, but in other languages floating point calculations are always slower than integer-based addressing, which is what the two situations are here: either do sixteen FP calculations once and retrieve the results by two sets of lookups based on integers, or calculate whenever you want to access a cell. The implementation I am basing my judgement on is a 64 by 16 screen for a retro-computer display in SL, the volume of calculations would have been 1024 each time the display changed. The lists required to run the screen fitted easily into the script memory. Once memory has been grabbed for chunks such as the lists there is no further performance overhead. But since I'm as lazy as you and can't be bothered to make a test harness we're never going to know.

 

Share this post


Link to post
Share on other sites

I have not personally used this method of doing what you are describing but it might be worth giving it a try.

Consider treating your texture atlas as an animation and use llSetTextureAnim to display the cell/frame you want.

You could rewrite your ShowNumber() function as follows:

Quote

 

ShowNumber(integer num, integer face)
{

    llSetTextureAnimation( ANIM_ON, face, 8, 8, num, 1, 0.1 );

}

Note, that this turns the animation on for the indicated face, divides the texture into an 8x8 grid. It then starts a single frame non-looping animation and should display your number.  

Your mileage may vary. 

Share this post


Link to post
Share on other sites

Cool Idea and it seems to work. I'll give it a try and see if it makes a difference.

I made a little test since I finally wanted to check performance.
The results for loops under 1000 are erratic. The script execution is obviouly not much influenced by the script but more of the sim and script scheduler and whatever. I wonder if llGetTime is even working properly.

However - with a loop of 100000 and above you get repeatable results. It's pretty clear that list operations are slow compared to simple math. test 3 just shows the overhead of the loop and a single integer operation since there is nothing to do in the loop.

integer maxloop = 100000;
integer face = 1;
integer x = 8;
integer y = 8;
list	lookup;

default {
  touch_end(integer number) {

	// ********** TEST 1 **********
	// math
  	llResetTime();
  	llSay(0,"START 1");
  	
	// TEST 1 preparation - one time operations
	integer maxnum = x * y; 
	float	step_x = 1.0 / (float)x;
	float	step_y = 1.0 / (float)y;
	//llScaleTexture(step_x,step_y,face);
	
	// TEST 1 working loop
	integer i = maxloop;
	while (--i>0) {
		integer num = i % maxnum;
		integer	part_x = num % x;
		integer	part_y = num / x;
		float	pos_y = -0.5+step_y/2.0 + step_y*(float)(y-part_y-1);
		float	pos_x = -0.5+step_x/2.0 + step_x*(float)part_x;
		//llOffsetTexture(pos_x,pos_y,face);
	}
	  	
  	llSay(0,"END 1 : "+(string)llGetTime());
  	
  	
	// ********** TEST 2 **********
	// lookup table
  	llResetTime();
  	llSay(0,"START 2");

	// TEST 2 preparation - one time operations
	maxnum = x * y; 
	step_x = 1.0 / (float)x;
	step_y = 1.0 / (float)y;
	lookup = [];
	i = x * y;
	while (--i>0) {
		integer num = i % maxnum;
		integer	part_x = num % x;
		integer	part_y = num / x;
		float	pos_y = -0.5+step_y/2.0 + step_y*(float)(y-part_y-1);
		float	pos_x = -0.5+step_x/2.0 + step_x*(float)part_x;
		lookup += [pos_x,pos_y];
	}
	//llScaleTexture(step_x,step_y,face);
	
	// TEST 2 working loop
	i = maxloop;
	while (--i>0) {
		integer num = i % maxnum;
		float	pos_y = llList2Float(lookup,num*2+1);
		float	pos_x = llList2Float(lookup,num*2);
		//llOffsetTexture(pos_x,pos_y,face);
	}
	  	
  	llSay(0,"END 2 : "+(string)llGetTime());

	// ********** TEST 3 **********
	// texture animation
  	llResetTime();
  	llSay(0,"START 3");

	// TEST 3 preparation - one time operations
	maxnum = x * y; 
  	
	// TEST 3 working loop
	i = maxloop;
	while (--i>0) {
		integer num = i % maxnum;
		//llSetTextureAnim(ANIM_ON,face,x,y,num,1,0.1);
	}
	  	
  	llSay(0,"END 3 : "+(string)llGetTime());
  	llSay(0,"LOOP : "+(string)maxloop+" -------------------------------------------------");
  	llResetScript();
  }
}

some results:

[06:29] Object: START 1
[06:29] Object: END 1 : 2.007409
[06:29] Object: START 2
[06:29] Object: END 2 : 5.034373
[06:29] Object: START 3
[06:29] Object: END 3 : 1.248286
[06:29] Object: LOOP : 100000 -------------------------------------------------

 

Edited by Nova Convair
  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...