@@ -1697,10 +1697,11 @@ private class Display3D : struct
1697
1697
1698
1698
bool PickPrimitives (Mesh mesh, PrimitiveSingle primitive, Vector3D rayDiff, Vector3D rayIntersect)
1699
1699
{
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 );
1701
1702
}
1702
1703
1703
- bool PickPrimitivesEx (Mesh mesh, PrimitiveSingle primitive, Vector3D rayDiff, Vector3D rayIntersect,
1704
+ bool PickPrimitivesEx (Mesh mesh, float * vertices, PrimitiveSingle primitive, Vector3D rayDiff, Vector3D rayIntersect,
1704
1705
int groupIx, uint64 * id)
1705
1706
{
1706
1707
Plane * planes = localPickingPlanes;
@@ -1720,7 +1721,7 @@ private class Display3D : struct
1720
1721
Array<MeshPart> parts = mesh.parts ;
1721
1722
int pi ;
1722
1723
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);
1724
1725
int vStride = mesh.flags .interleaved ? 8 : 3 ;
1725
1726
1726
1727
if (!vertices || (!indices32 && !indices16)) return false ; // Need vertices and indices here...
@@ -2000,11 +2001,83 @@ private class Display3D : struct
2000
2001
return PickMeshEx (object, rayIntersect, null );
2001
2002
}
2002
2003
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
+
2003
2012
bool PickMeshEx (Object object, Vector3D rayIntersect, uint64 * id)
2004
2013
{
2005
2014
Mesh mesh = object.mesh ;
2006
2015
bool result = false ;
2007
2016
Vector3D rayDiff { MAXFLOAT, MAXFLOAT, MAXFLOAT };
2017
+ Vector3Df * vertices = mesh.vertices ;
2018
+ Vector3Df * tmpVertices = null ;
2019
+
2020
+ #ifdef GPU_SKIN
2021
+ // We need to apply bone weights for picking
2022
+ MeshSkin skin = mesh.skin ;
2023
+ if (skin)
2024
+ {
2025
+ Vector3Df * oVertices = mesh.vertices ;
2026
+ int nVertices = skin.skinVerts .count ;
2027
+ Array<Matrixf> matBones = mesh.matBones ;
2028
+ int i;
2029
+
2030
+ // Lock({ vertices = true });
2031
+ vertices = tmpVertices = new Vector3Df[mesh.nVertices ];
2032
+
2033
+ for (i = 0 ; i < nVertices; i++)
2034
+ {
2035
+ Vector3Df * vert = &vertices[i];
2036
+ SkinVert * sv = &skin.skinVerts [i];
2037
+ int j;
2038
+ float tw = 0 ;
2039
+ Vector3Df vt { };
2040
+ for (j = 0 ; j < MAX_BONES; j++)
2041
+ {
2042
+ int b = sv->bones [j];
2043
+ if (b != NO_BONE)
2044
+ {
2045
+ float w = sv->weights [j] / 255 .0f ;
2046
+ Vector3Df v;
2047
+ inlineMultMatrix (v, oVertices[i], matBones[b]);
2048
+ tw += w;
2049
+ vt.x += w * v.x ;
2050
+ vt.y += w * v.y ;
2051
+ vt.z += w * v.z ;
2052
+ }
2053
+ else
2054
+ break ;
2055
+ }
2056
+
2057
+ if (tw)
2058
+ {
2059
+ tw = 1 .0f / tw;
2060
+ vert->x = vt.x * tw;
2061
+ vert->y = vt.y * tw;
2062
+ vert->z = vt.z * tw;
2063
+ }
2064
+ else
2065
+ *vert = oVertices[i];
2066
+ }
2067
+
2068
+ if (mesh.dupVerts )
2069
+ {
2070
+ int * dv = mesh.dupVerts .array - nVertices;
2071
+ int count = nVertices + mesh.dupVerts .count ;
2072
+ for (i = nVertices; i < count; i++)
2073
+ {
2074
+ int ix = dv[i];
2075
+ vertices[i] = vertices[ix];
2076
+ }
2077
+ }
2078
+ }
2079
+ #endif
2080
+
2008
2081
if (rayIntersect != null )
2009
2082
rayIntersect = { MAXFLOAT, MAXFLOAT, MAXFLOAT };
2010
2083
@@ -2015,7 +2088,7 @@ private class Display3D : struct
2015
2088
2016
2089
for (group = mesh.groups .first ; group; group = group.next )
2017
2090
{
2018
- if (!group.type .hide && PickPrimitivesEx (mesh, (PrimitiveSingle *)&group.type , rayDiff, rayIntersect, groupIX, id))
2091
+ if (!group.type .hide && PickPrimitivesEx (mesh, (float *) vertices, ( PrimitiveSingle *)&group.type , rayDiff, rayIntersect, groupIX, id))
2019
2092
{
2020
2093
result = true ;
2021
2094
if (!intersecting)
@@ -2030,14 +2103,16 @@ private class Display3D : struct
2030
2103
int c;
2031
2104
for (c = 0 ; c < mesh.nPrimitives ; c++)
2032
2105
{
2033
- if (PickPrimitives (mesh, mesh.primitives [c], rayDiff, rayIntersect))
2106
+ if (PickPrimitivesEx (mesh, ( float *) vertices, mesh.primitives [c], rayDiff, rayIntersect, 0 , null ))
2034
2107
{
2035
2108
result = true ;
2036
2109
if (!intersecting)
2037
2110
break ;
2038
2111
}
2039
2112
}
2040
2113
}
2114
+ delete tmpVertices;
2115
+
2041
2116
return result;
2042
2117
}
2043
2118
};
0 commit comments