Skip to content

Commit

Permalink
Resolve #2753: Support material-specific shift/scale/rotation keyword…
Browse files Browse the repository at this point in the history
…s in ASE models

UVW_U_OFFSET, UVW_V_OFFSET. UVW_U_TILING, UVW_V_TILING, UVW_ANGLE
  • Loading branch information
codereader committed Jan 30, 2017
1 parent 965cae4 commit 43ab9b8
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 56 deletions.
215 changes: 159 additions & 56 deletions libs/picomodel/pm_ase.c
Expand Up @@ -62,6 +62,11 @@ typedef struct aseSubMaterial_s
int subMtlId;
picoShader_t* shader;

float uOffset; /* UVW_U_OFFSET */
float vOffset; /* UVW_V_OFFSET */
float uScale; /* UVW_U_TILING */
float vScale; /* UVW_V_TILING */
float uvAngle; /* UVW_ANGLE */
} aseSubMaterial_t;

typedef struct aseMaterial_s
Expand Down Expand Up @@ -148,6 +153,13 @@ static aseSubMaterial_t* _ase_add_submaterial( aseMaterial_t **list, int mtlIdPa
aseMaterial_t *parent = _ase_get_material( *list, mtlIdParent );
aseSubMaterial_t *subMtl = _pico_calloc( 1, sizeof ( aseSubMaterial_t ) );

/* Initialise some values */
subMtl->uOffset = 0.0f;
subMtl->vOffset = 0.0f;
subMtl->uScale = 1.0f;
subMtl->vScale = 1.0f;
subMtl->uvAngle = 0.0f;

if ( !parent )
{
parent = _ase_add_material ( list , mtlIdParent );
Expand Down Expand Up @@ -470,16 +482,35 @@ static void _ase_submit_triangles( picoModel_t* model , aseMaterial_t* materials
{
picoVec3_t* xyz[3];
picoVec3_t* normal[3];
picoVec2_t* st[3];
picoVec2_t* stRef[3];
picoVec2_t st[3];
picoColor_t* color[3];
picoIndex_t smooth[3];
double u,v;

double materialSin = sin(subMtl->uvAngle);
double materialCos = cos(subMtl->uvAngle);

int j;
/* we pull the data from the vertex, color and texcoord arrays using the face index data */
for ( j = 0 ; j < 3 ; j ++ )
{
xyz[j] = &vertices[(*i).indices[j]].xyz;
normal[j] = &vertices[(*i).indices[j]].normal;
st[j] = &texcoords[(*i).indices[j + 3]].texcoord;

/* Old code
st[j][0] = texcoords[(*i).indices[j + 3]].texcoord[0];
st[j][1] = texcoords[(*i).indices[j + 3]].texcoord[1];
*/

/* greebo: Apply shift, scale and rotation */
u = texcoords[(*i).indices[j + 3]].texcoord[0] * subMtl->uScale + subMtl->uOffset;
v = texcoords[(*i).indices[j + 3]].texcoord[1] * subMtl->vScale + subMtl->vOffset;

st[j][0] = u * materialCos + v * materialSin;
st[j][1] = u * -materialSin + v * materialCos;

stRef[j] = &st[j];

if( colors != NULL && (*i).indices[j + 6] >= 0 )
{
Expand All @@ -495,7 +526,7 @@ static void _ase_submit_triangles( picoModel_t* model , aseMaterial_t* materials
}

/* submit the triangle to the model */
PicoAddTriangleToModel ( model , xyz , normal , 1 , st , 1 , color , subMtl->shader, smooth );
PicoAddTriangleToModel ( model , xyz , normal , 1 , stRef, 1 , color , subMtl->shader, smooth );
}
}
}
Expand Down Expand Up @@ -925,7 +956,11 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD )
picoColor_t ambientColor, diffuseColor, specularColor;
char *mapname = NULL;
int subMtlId, subMaterialLevel = -1;

float uOffset = 0.0f;
float vOffset = 0.0f;
float uScale = 1.0f;
float vScale = 1.0f;
float uvAngle = 0;

/* get material index */
_pico_parse_int( p,&index );
Expand Down Expand Up @@ -977,6 +1012,14 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD )
PicoSetShaderMapName( shader, mapname );

subMaterial = _ase_add_submaterial( &materials, index, subMtlId, shader );

// Assign offsets
subMaterial->uOffset = uOffset;
subMaterial->vOffset = vOffset;
subMaterial->uScale = uScale;
subMaterial->vScale = vScale;
subMaterial->uvAngle = uvAngle;

subMaterialLevel = -1;
}

Expand Down Expand Up @@ -1120,6 +1163,59 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD )
_pico_parse_skip_rest( p );
continue;
}

if (!_pico_stricmp(p->token, "*uvw_u_offset"))
{
if (!_pico_parse_float(p, &uOffset))
_ase_error_return("Material UVW_U_OFFSET error");

// Negate the u offset value
uOffset = -uOffset;

/* skip rest and continue with next token */
_pico_parse_skip_rest(p);
continue;
}

if (!_pico_stricmp(p->token, "*uvw_v_offset"))
{
if (!_pico_parse_float(p, &vOffset))
_ase_error_return("Material UVW_V_OFFSET error");

/* skip rest and continue with next token */
_pico_parse_skip_rest(p);
continue;
}

if (!_pico_stricmp(p->token, "*uvw_u_tiling"))
{
if (!_pico_parse_float(p, &uScale))
_ase_error_return("Material UVW_U_TILING error");

/* skip rest and continue with next token */
_pico_parse_skip_rest(p);
continue;
}

if (!_pico_stricmp(p->token, "*uvw_v_tiling"))
{
if (!_pico_parse_float(p, &vScale))
_ase_error_return("Material UVW_V_TILING error");

/* skip rest and continue with next token */
_pico_parse_skip_rest(p);
continue;
}

if (!_pico_stricmp(p->token, "*uvw_angle"))
{
if (!_pico_parse_float(p, &uvAngle))
_ase_error_return("Material UVW_ANGLE error");

/* skip rest and continue with next token */
_pico_parse_skip_rest(p);
continue;
}
}
}
/* end map_diffuse block */
Expand All @@ -1137,7 +1233,7 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD )
}

/* set material name */
shadername_convert(materialName);
shadername_convert(materialName);
PicoSetShaderName( shader,materialName );

/* set shader's transparency */
Expand All @@ -1161,58 +1257,65 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD )
/* set material map name */
PicoSetShaderMapName( shader, mapname );

/* extract shadername from bitmap path */
if(mapname != NULL)
{
char* p = mapname;

/* convert to shader-name format */
shadername_convert(mapname);
{
/* remove extension */
char* last_period = strrchr(p, '.');
if(last_period != NULL)
{
*last_period = '\0';
}
}

/* find game root */
for(; *p != '\0'; ++p)
{
if(_pico_strnicmp(p, "quake", 5) == 0 || _pico_strnicmp(p, "doom", 4) == 0)
{
break;
}
}
/* root-relative */
for(; *p != '\0'; ++p)
{
if(*p == '/')
{
++p;
break;
}
}
/* game-relative */
for(; *p != '\0'; ++p)
{
if(*p == '/')
{
++p;
break;
}
}

if(*p != '\0')
{
/* set material name */
PicoSetShaderName( shader,p );
}
}

/* this is just a material with 1 submaterial */
/* extract shadername from bitmap path */
if(mapname != NULL)
{
char* p = mapname;

/* convert to shader-name format */
shadername_convert(mapname);
{
/* remove extension */
char* last_period = strrchr(p, '.');
if (last_period != NULL)
{
*last_period = '\0';
}
}

/* find game root */
for(; *p != '\0'; ++p)
{
if (_pico_strnicmp(p, "quake", 5) == 0 || _pico_strnicmp(p, "doom", 4) == 0)
{
break;
}
}
/* root-relative */
for (; *p != '\0'; ++p)
{
if (*p == '/')
{
++p;
break;
}
}
/* game-relative */
for (; *p != '\0'; ++p)
{
if (*p == '/')
{
++p;
break;
}
}

if (*p != '\0')
{
/* set material name */
PicoSetShaderName(shader, p);
}
}

/* this is just a material with 1 submaterial */
subMaterial = _ase_add_submaterial( &materials, index, 0, shader );

// Assign offsets
subMaterial->uOffset = uOffset;
subMaterial->vOffset = vOffset;
subMaterial->uScale = uScale;
subMaterial->vScale = vScale;
subMaterial->uvAngle = uvAngle;
}

/* ydnar: free mapname */
Expand Down
2 changes: 2 additions & 0 deletions tools/msvc2015/picomodellib.vcxproj
Expand Up @@ -90,6 +90,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<Optimization>Disabled</Optimization>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
Expand All @@ -103,6 +104,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<Optimization>Disabled</Optimization>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
Expand Down

0 comments on commit 43ab9b8

Please sign in to comment.