News:

One Minute Game Review by The Happy Friar: https://ugetube.com/@OneMinteGameReviews
Also on Rumble: https://rumble.com/c/c-1115371

idTech 4 (aka Doom 3 tech) Discord Server! https://discord.gg/9wtCGHa

Main Menu

Eyeball deform

Started by bitterman, September 20, 2017, 08:34:27 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

bitterman

I can't find any detailed info about this type of deform.

As I suspect it is a plane with two separated tris. It must be placed in front of other plane wich eyeball's image. If it placed right then first plane will deform texcoords of second plane with image (make it more convex perhaps).

Am I right? Thanks.

bitterman

#1
Well looks like 'deform eyeball' just scrolls texture to realize 'track to' effect (eyeball moving) when NPC looking at something.

bitterman

Can't check it out because when I set '$char.lookat($player1)' then NPC's head tracks to player, not only eyes. There is no need to move only eyes when whole head do it.

Perhaps this type of deform used only for NPS without separated head...

bitterman

Perhaps this is because differences between head and eyes turn angles.


bitterman

I try to create custom eyeball deform.

Pic. 1: When I split eyes more than one tris I get warning. This part of code is located and it's just return without next deform. But I can still see eyes.

Pic. 2: When I reduce tris to right values then previous warning is dissapearing but eyes dis. too. I go to next deform code but some is wrong.

Pic. 3: When I set r_skipDeforms to 1 then I get eyes back.

/*
=====================
R_EyeballDeform

Each eyeball surface should have an separate upright triangle behind it, long end
pointing out the eye, and another single triangle in front of the eye for the focus point.
=====================
*/
static void R_EyeballDeform( drawSurf_t *surf ) {
int i, j, k;
const srfTriangles_t *tri;
srfTriangles_t *newTri;
eyeIsland_t islands[MAX_EYEBALL_ISLANDS];
int numIslands;
bool triUsed[MAX_EYEBALL_ISLANDS*MAX_EYEBALL_TRIS];

tri = surf->geo;

// separate all the triangles into islands
int numTri = tri->numIndexes / 3;
if ( numTri > MAX_EYEBALL_ISLANDS*MAX_EYEBALL_TRIS ) {
common->Printf( "R_EyeballDeform: too many triangles in surface" );
return;
}
memset( triUsed, 0, sizeof( triUsed ) );

for ( numIslands = 0  ; numIslands < MAX_EYEBALL_ISLANDS ; numIslands++ ) {
islands[numIslands].numTris = 0;
islands[numIslands].bounds.Clear();
for ( i = 0 ; i < numTri ; i++ ) {
if ( !triUsed[i] ) {
AddTriangleToIsland_r( tri, i, triUsed, &islands[numIslands] );
break;
}
}
if ( i == numTri ) {
break;
}
}

// assume we always have two eyes, two origins, and two targets
if ( numIslands != 3 ) {
common->Printf( "R_EyeballDeform: %i triangle islands\n", numIslands );
return;
}

// this srfTriangles_t and all its indexes and caches are in frame
// memory, and will be automatically disposed of

// the surface cannot have more indexes or verts than the original
newTri = (srfTriangles_t *)R_ClearedFrameAlloc( sizeof( *newTri ) );
memset( newTri, 0, sizeof( *newTri ) );
newTri->numVerts = tri->numVerts;
newTri->numIndexes = tri->numIndexes;
newTri->indexes = (glIndex_t *)R_FrameAlloc( tri->numIndexes * sizeof( newTri->indexes[0] ) );
idDrawVert *ac = (idDrawVert *)_alloca16( tri->numVerts * sizeof( idDrawVert ) );

newTri->numIndexes = 0;

// decide which islands are the eyes and points
for ( i = 0 ; i < numIslands ; i++ ) {
islands[i].mid = islands[i].bounds.GetCenter();
}

for ( i = 0 ; i < numIslands ; i++ ) {
eyeIsland_t *island = &islands[i];

if ( island->numTris == 1 ) {
continue;
}

// the closest single triangle point will be the eye origin
// and the next-to-farthest will be the focal point
idVec3 origin, focus;
int originIsland = 0;
float dist[MAX_EYEBALL_ISLANDS];
int sortOrder[MAX_EYEBALL_ISLANDS];

for ( j = 0 ; j < numIslands ; j++ ) {
idVec3 dir = islands[j].mid - island->mid;
dist[j] = dir.Length();
sortOrder[j] = j;
for ( k = j-1 ; k >= 0 ; k-- ) {
if ( dist[k] > dist[k+1] ) {
int temp = sortOrder[k];
sortOrder[k] = sortOrder[k+1];
sortOrder[k+1] = temp;
float ftemp = dist[k];
dist[k] = dist[k+1];
dist[k+1] = ftemp;
}
}
}

originIsland = sortOrder[1];
origin = islands[originIsland].mid;

focus = islands[sortOrder[2]].mid;

// determine the projection directions based on the origin island triangle
idVec3 dir = focus - origin;
dir.Normalize();

const idVec3 &p1 = tri->verts[tri->indexes[islands[originIsland].tris[0]+0]].xyz;
const idVec3 &p2 = tri->verts[tri->indexes[islands[originIsland].tris[0]+1]].xyz;
const idVec3 &p3 = tri->verts[tri->indexes[islands[originIsland].tris[0]+2]].xyz;

idVec3 v1 = p2 - p1;
v1.Normalize();
idVec3 v2 = p3 - p1;
v2.Normalize();

// texVec[0] will be the normal to the origin triangle
idVec3 texVec[2];

texVec[0].Cross( v1, v2 );

texVec[1].Cross( texVec[0], dir );

for ( j = 0 ; j < 2 ; j++ ) {
texVec[j] -= dir * ( texVec[j] * dir );
texVec[j].Normalize();
}

// emit these triangles, generating the projected texcoords

for ( j = 0 ; j < islands[i].numTris ; j++ ) {
for ( k = 0 ; k < 3 ; k++ ) {
int index = islands[i].tris[j] * 3;

index = tri->indexes[index+k];
newTri->indexes[newTri->numIndexes++] = index;

ac[index].xyz = tri->verts[index].xyz;

idVec3 local = tri->verts[index].xyz - origin;

ac[index].st[0] = 0.5 + local * texVec[0];
ac[index].st[1] = 0.5 + local * texVec[1];
}
}
}

R_FinishDeform( surf, newTri, ac );
}   


Why deform works not as expected?

Thanks

bitterman

#5
Looks like there is an unobvious problem with export.

The code above works with each vertex.

I have 13 and it must be 13 but after export md5 model I've got 21. Doubles are removed.

Upd:

Looks like exporter doubled (or even tripled) verts between tris (points 2, 3, 4, 6, 7 on pic. above).
Is there a way to prevent this?

Three separated tris are exported as 9 numverts but for correct engine's work one of three islands must have at least two tris.

bitterman

Quoteconclusion: the old mesh generates 288 extra verts that my script does not
* there are 3 places VERTS are generated; (1) once for each vertex in the blender mesh, (2) once AGAIN for each vertex shared by non-smooth faces because they have diff normals, (3) once AGAIN for each vertex with two separate UV coords for different faces

     https://www.katsbits.com/smforum/index.php?action=printpage;topic=167.0 


bitterman

#7
This type of deform make the eye's surface coplanar to entity which NPC is looking at (with some angle limitations).

Not sure about texcoord deform.


bitterman


The Happy Friar

I think he needs to see a doctor for that one. :)