diff --git a/libs/picomodel/pm_ase.c b/libs/picomodel/pm_ase.c
index 5f4e6b639c..e1cd0a1326 100644
--- a/libs/picomodel/pm_ase.c
+++ b/libs/picomodel/pm_ase.c
@@ -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
@@ -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 );
@@ -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 )
{
@@ -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 );
}
}
}
@@ -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 );
@@ -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;
}
@@ -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 */
@@ -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 */
@@ -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 */
diff --git a/tools/msvc2015/picomodellib.vcxproj b/tools/msvc2015/picomodellib.vcxproj
index 0ba0b097b5..97ebd6be1d 100644
--- a/tools/msvc2015/picomodellib.vcxproj
+++ b/tools/msvc2015/picomodellib.vcxproj
@@ -90,6 +90,7 @@
Level3
ProgramDatabase
4996;%(DisableSpecificWarnings)
+ Disabled
@@ -103,6 +104,7 @@
Level3
ProgramDatabase
4996;%(DisableSpecificWarnings)
+ Disabled