Start a new topic

Vega Prime Light Point Back Color

So, I'm looking at the vertex record definition and can't find the tag for this.  I know it gets saved at the vertex level, because i can save and reload a file with different values on vertices within a single string.


Am i missing something obvious?


Great question! I didn't know off hand so after a little bit of searching, it looks like the back color for a light is stored on the U component of a vertex.


Ah, and it looks as if it goes in as an 8-bit integer and the U component is coded to be a double precision float, so 127 = -1.70517 e38


If you could please let me know exactly how the value is stored and how the field is displayed, i can figure out how to properly extract it.

 

“Of all the lousy ways to save a buck!”

“Sir, that is low. If I had a rubber hose I’d beat you with it”


I'm guessing this dates back to when you tried to make memory use as efficient as possibly, and of course vertices have the most records in any OpenFlight file except maybe an empty master file with a single texture reference and single polygon.

 

Yep I believe you are correct. The lengths we had to go to to minimize space.


I started going down the rabbit hole of deciphering the math involved with extracting the color from the u component when I stumbled upon these functions. :)

mgGetVtxBackColorRGB
mgSetVtxBackColorRGB

 


1 person likes this
I'm trying to help a colleague updating their own open flight loader outside the API. Legacy reasons. Any way to find out how those are packed, and if the vertex has an indexed color how it automatically finds the rgb on get, and sets the index on set?

I stripped out the some code to give you an example of how the BackColor is accessed from the U of the vertex. This code is not complete so will not compile. The main missing element is the function to get a color from index and db. We maintain a color table of pure intensities. When we want to convert from index and intensity to rgb, we get the pure rgb from the table with the index, then multiply the intensity to the r g and b components. When we want to convert from rgb to index and intensity, we use another table to look up the color that is closest to the rgb requested. Floating point error makes it critical to look up the closest value.


 

static int Colorstart = 0;
#define MAXDBLCOLOR  0x1ffff

int FLC_iris2dbl(int iriscol)
/* returns dbl color from Iris color */
{
	if ((iriscol & 0x00fc0000) || (iriscol & 0x00ffffff) > MAXDBLCOLOR + Colorstart)
		return (-1);
	else
		return ((iriscol & 0xff000000) | ((iriscol & 0x00ffffff) - Colorstart));
}

unsigned int FLC_dbl2pal ( int dblIndex )
/* Removes the intensity from the dbl index. 
 * The result should be the palette index of the full intensity color.
 */
{
	unsigned int paletteIndex = dblIndex >> IHW_getshadebits();
	return (paletteIndex);
}

unsigned int IHW_getshademask ( void )
{
	int IHW_shademask = 0;
	for (int count = 0; count != 7; count++)
		IHW_shademask = IHW_shademask << 1 | 1;
	return IHW_shademask;
}

unsigned int FLC_dbl2intensity ( int dblIndex )
/* Extracts the intensity from the dbl index.   */
{
	unsigned int intensity = dblIndex & IHW_getshademask();
	return (intensity);
}

static void DblColorIndex2Api ( int dblColorIndex, unsigned int* apiColorIndex, float* apiIntensity )
	/* converts a dbl color index to an api color index/intensity pair */
{
	if ( apiColorIndex )
		*apiColorIndex = FLC_dbl2pal (dblColorIndex);
	if ( apiIntensity )
		*apiIntensity = (float) FLC_dbl2intensity (dblColorIndex) / (float) IHW_getshademask();
}

static mgbool Index2rgb ( mgrec *db, unsigned int index, float intensity, short* r, short* g, short* b )
	/* takes a palette color index and intensity (0.0 to 1.0) and returns RGB */
{
	if ( !db || LB1_RecIsDb (db) ) 
   {
		if ( (index < NOCOLOR) && (intensity >= 0.0f) && (intensity <= 1.0f) ) {
			ibead* topib;
			if (db)
				topib = mgRec2Bead (db);
			else
				topib = MG_NULL;

			packedcolorpt colvaluept = FLC_GetColor (topib, index);

			if ( colvaluept ) {
				if ( r ) *r = (short) ( (float)colvaluept->value.red   * intensity );
				if ( g ) *g = (short) ( (float)colvaluept->value.green * intensity );
				if ( b ) *b = (short) ( (float)colvaluept->value.blue  * intensity );
			}
			else {
				if ( r ) *r = 0;
				if ( g ) *g = 0;
				if ( b ) *b = 0;
			}
			return (MG_TRUE);
		}
	}
	return (MG_FALSE);
}

static mgbool GetVtxBackColorRGB ( mgrec* db, mgrec* vtxrec, short* red, short* green, short* blue )
{
	ivertex *ib = mgRec2Vtx (vtxrec);

	if ( (ib!=NULL) &&
		( (red!=NULL) || (green!=NULL) || (blue!=NULL)) )
	{
		unsigned int *intptr = (unsigned int *)&(ib->u);

		if ( ib->flags.rgbmode ) {
			packedcolor rgba;
			rgba.packed = *intptr;
			if(red)   *red	  = rgba.value.red;
			if(green) *green = rgba.value.green;
			if(blue)  *blue  = rgba.value.blue;
			return (MG_TRUE);
		}
		else if ( LB1_ValidRec (db) ) {
			int dblIndex = FLC_iris2dbl (*intptr);
			if ( !( dblIndex & 0x00fc0000 ) ) {
				unsigned int apiIndex;
				float intensity;
				dblIndex = dblIndex & 0x00ffffff;
				DblColorIndex2Api ((unsigned int) dblIndex, &apiIndex, &intensity);
				return (Index2rgb (db, apiIndex, intensity, red, green, blue));
			}
		}
	}
	return (MG_FALSE);
}

 

Login to post a comment