@@ -1697,10 +1697,11 @@ private class Display3D : struct
16971697
16981698 bool PickPrimitives (Mesh mesh, PrimitiveSingle primitive, Vector3D rayDiff, Vector3D rayIntersect)
16991699 {
1700- return PickPrimitivesEx (mesh, primitive, rayDiff, rayIntersect, 0 , null );
1700+ float * vertices = (float *)(mesh.skin && mesh.skin .vertices ? mesh.skin .vertices : mesh.vertices );
1701+ return PickPrimitivesEx (mesh, vertices, primitive, rayDiff, rayIntersect, 0 , null );
17011702 }
17021703
1703- bool PickPrimitivesEx (Mesh mesh, PrimitiveSingle primitive, Vector3D rayDiff, Vector3D rayIntersect,
1704+ bool PickPrimitivesEx (Mesh mesh, float * vertices, PrimitiveSingle primitive, Vector3D rayDiff, Vector3D rayIntersect,
17041705 int groupIx, uint64 * id)
17051706 {
17061707 Plane * planes = localPickingPlanes;
@@ -1720,7 +1721,7 @@ private class Display3D : struct
17201721 Array<MeshPart> parts = mesh.parts ;
17211722 int pi;
17221723 int firstPart = 0 , lastPart = 0 ;
1723- float * vertices = (float *)(mesh.skin && mesh.skin .vertices ? mesh.skin .vertices : mesh.vertices );
1724+ // float * vertices = (float *)(mesh.skin && mesh.skin.vertices ? mesh.skin.vertices : mesh.vertices);
17241725 int vStride = mesh.flags .interleaved ? 8 : 3 ;
17251726
17261727 if (!vertices || (!indices32 && !indices16)) return false ; // Need vertices and indices here...
@@ -2000,11 +2001,85 @@ private class Display3D : struct
20002001 return PickMeshEx (object, rayIntersect, null );
20012002 }
20022003
2004+ #define GPU_SKIN
2005+ static inline void ::inlineMultMatrix (Vector3Df dest, const Vector3Df source, const Matrixf matrix)
2006+ {
2007+ dest.x = (float )(source.x * matrix.m [0 ][0 ] + source.y * matrix.m [1 ][0 ] + source.z * matrix.m [2 ][0 ] + matrix.m [3 ][0 ]);
2008+ dest.y = (float )(source.x * matrix.m [0 ][1 ] + source.y * matrix.m [1 ][1 ] + source.z * matrix.m [2 ][1 ] + matrix.m [3 ][1 ]);
2009+ dest.z = (float )(source.x * matrix.m [0 ][2 ] + source.y * matrix.m [1 ][2 ] + source.z * matrix.m [2 ][2 ] + matrix.m [3 ][2 ]);
2010+ }
2011+
20032012 bool PickMeshEx (Object object, Vector3D rayIntersect, uint64 * id)
20042013 {
20052014 Mesh mesh = object.mesh ;
20062015 bool result = false ;
20072016 Vector3D rayDiff { MAXFLOAT, MAXFLOAT, MAXFLOAT };
2017+ Vector3Df * vertices = mesh.vertices ;
2018+ Vector3Df * tmpVertices = null ;
2019+ // We need to apply bone weights for picking
2020+ MeshSkin skin = mesh.skin ;
2021+ if (skin)
2022+ {
2023+ #ifdef GPU_SKIN
2024+ Vector3Df * oVertices = mesh.vertices ;
2025+ int nVertices = skin.skinVerts .count ;
2026+ Array<Matrixf> matBones = mesh.matBones ;
2027+ int i;
2028+
2029+ // Lock({ vertices = true });
2030+ vertices = tmpVertices = new Vector3Df[mesh.nVertices ];
2031+
2032+ for (i = 0 ; i < nVertices; i++)
2033+ {
2034+ Vector3Df * vert = &vertices[i];
2035+ SkinVert * sv = &skin.skinVerts [i];
2036+ int j;
2037+ float tw = 0 ;
2038+ Vector3Df vt { };
2039+ for (j = 0 ; j < MAX_BONES; j++)
2040+ {
2041+ int b = sv->bones [j];
2042+ if (b != NO_BONE)
2043+ {
2044+ float w = sv->weights [j] / 255 .0f ;
2045+ Vector3Df v;
2046+ inlineMultMatrix (v, oVertices[i], matBones[b]);
2047+ tw += w;
2048+ vt.x += w * v.x ;
2049+ vt.y += w * v.y ;
2050+ vt.z += w * v.z ;
2051+ }
2052+ else
2053+ break ;
2054+ }
2055+
2056+ if (tw)
2057+ {
2058+ tw = 1 .0f / tw;
2059+ vert->x = vt.x * tw;
2060+ vert->y = vt.y * tw;
2061+ vert->z = vt.z * tw;
2062+ }
2063+ else
2064+ *vert = oVertices[i];
2065+ }
2066+
2067+ if (mesh.dupVerts )
2068+ {
2069+ int * dv = mesh.dupVerts .array - nVertices;
2070+ int count = nVertices + mesh.dupVerts .count ;
2071+ for (i = nVertices; i < count; i++)
2072+ {
2073+ int ix = dv[i];
2074+ vertices[i] = vertices[ix];
2075+ }
2076+ }
2077+ }
2078+ #else
2079+ if (skin.vertices )
2080+ vertices = skin.vertices ;
2081+ #endif
2082+
20082083 if (rayIntersect != null )
20092084 rayIntersect = { MAXFLOAT, MAXFLOAT, MAXFLOAT };
20102085
@@ -2015,7 +2090,7 @@ private class Display3D : struct
20152090
20162091 for (group = mesh.groups .first ; group; group = group.next )
20172092 {
2018- if (!group.type .hide && PickPrimitivesEx (mesh, (PrimitiveSingle *)&group.type , rayDiff, rayIntersect, groupIX, id))
2093+ if (!group.type .hide && PickPrimitivesEx (mesh, (float *) vertices, ( PrimitiveSingle *)&group.type , rayDiff, rayIntersect, groupIX, id))
20192094 {
20202095 result = true ;
20212096 if (!intersecting)
@@ -2030,14 +2105,16 @@ private class Display3D : struct
20302105 int c;
20312106 for (c = 0 ; c < mesh.nPrimitives ; c++)
20322107 {
2033- if (PickPrimitives (mesh, mesh.primitives [c], rayDiff, rayIntersect))
2108+ if (PickPrimitivesEx (mesh, ( float *) vertices, mesh.primitives [c], rayDiff, rayIntersect, 0 , null ))
20342109 {
20352110 result = true ;
20362111 if (!intersecting)
20372112 break ;
20382113 }
20392114 }
20402115 }
2116+ delete tmpVertices;
2117+
20412118 return result;
20422119 }
20432120};
0 commit comments