private void ProcessBone(LimbDataSkeleton limbDataSkeleton, LimbDataBone bone, Queue <int> pixelsQueue) { var perpendicularVector = Utils.GetPerpendicularVector(bone.GetStartPoint(), bone.GetEndPoint()); BoneConfiguration boneConfiguration = null; if (Configuration.BoneConfigurationsDictionary.ContainsKey(bone.JointTypePair)) { boneConfiguration = Configuration.BoneConfigurationsDictionary[bone.JointTypePair]; } ProcessBoneJoint(limbDataSkeleton, bone, pixelsQueue, perpendicularVector, true, boneConfiguration); }
private static void ProcessBoneWeights(LimbDataBone bone, List <BonePixels> pixelListsToCheck) { if (bone.Points.Count == 0) { return; } var bonePixelData = GetBonePixelsDataFromBoneDictionary(bone.BoneHash); if (bonePixelData == null) { return; } const float distanceLimit = 48f; var indices = bonePixelData.VertexIndices; Parallel.ForEach(indices, vertexIndex => { var thisVertex = GB.LimbDataManager.LimbData.Mesh.Vertices[vertexIndex]; var thisVertex2D = new Vector2(thisVertex.X, thisVertex.Y); var minDistance = float.MaxValue; foreach (var whitelistPixelList in pixelListsToCheck) { if (whitelistPixelList != null) { foreach (var otherVertexIndex in whitelistPixelList.VertexIndices) { var otherVertex = GB.LimbDataManager.LimbData.Mesh.Vertices[otherVertexIndex]; var otherVertex2D = new Vector2(otherVertex.X, otherVertex.Y); var distance = Vector2.Distance(thisVertex2D, otherVertex2D); if (distance < minDistance) { minDistance = distance; } } } } if (minDistance < distanceLimit) { var progress = minDistance / distanceLimit; GB.LimbDataManager.LimbData.Mesh.VertexWeightsDictionary[thisVertex] = Curves.WeightsSmoothingCurve.Evaluate(progress); } }); }
private static void MorphBone(LimbDataBone bone) { if (bone.Points.Count == 0) { return; } var bonePixelData = GetBonePixelsDataFromBoneDictionary(bone.BoneHash); if (bonePixelData == null) { return; } switch (bone.BoneHash) { case 35: // head, shoulder center MorphBoneGrow(bone, bonePixelData, Settings.Instance.HeadSize / 100f - 1f); break; case 152: // arms case 84: case 169: case 101: MorphBoneStretch(bone, bonePixelData, new StretchParameters { Curve = Curves.ArmsCurve, Power = Settings.Instance.ArmScale / 100f - 1f }); break; case 272: // legs case 305: case 220: case 237: MorphBoneStretch(bone, bonePixelData, new StretchParameters { Curve = Curves.LegsCurve, Power = Settings.Instance.LegScale / 100f - 1f }); break; // case 186: // hands, feet // case 118: // case 242: // case 254: // MorphBoneBloat(bone, bonePixel, Settings.Instance.HeadSize / 25f); // break; } }
private static void MorphBoneStretch(LimbDataBone bone, BonePixels bonePixel, StretchParameters stretchParameters) { var boneStartPoint = new Vector2(bone.StartPoint.X, bone.StartPoint.Y); var boneEndPoint = new Vector2(bone.EndPoint.X, bone.EndPoint.Y); var boneLength = Vector2.Distance(boneStartPoint, boneEndPoint); var indices = bonePixel.VertexIndices; foreach (var vertexIndex in indices) { var vertex = GB.LimbDataManager.LimbData.Mesh.Vertices[vertexIndex]; var vertexPoint = new Vector2(vertex.X, vertex.Y); var vertexWeight = GB.LimbDataManager.LimbData.Mesh.GetVertexWeight(vertex); var closestPointOnLine3D = Utils.GetClosestPointOnLine(bone.StartPoint, bone.EndPoint, new Vector3(vertexPoint.X, vertexPoint.Y, 0)); var closestPointOnLine2D = new Vector2(closestPointOnLine3D.X, closestPointOnLine3D.Y); var progressOnLine = Vector2.Distance(closestPointOnLine2D, boneStartPoint) / boneLength; if (progressOnLine < 0 || progressOnLine > 1) { continue; } var distance = Vector2.Distance(vertexPoint, closestPointOnLine2D); var directionVector = Vector2.Normalize(vertexPoint - closestPointOnLine2D); var distanceMultiplier = distance / 2f; var curveScale = 1f + stretchParameters.Power * stretchParameters.Curve.Evaluate(progressOnLine); vertex.X += curveScale * directionVector.X * stretchParameters.Power * distanceMultiplier * vertexWeight; vertex.Y += curveScale * directionVector.Y * stretchParameters.Power * distanceMultiplier * vertexWeight; vertex.Z = bone.BoneHash; GB.LimbDataManager.LimbData.Mesh.Vertices[vertexIndex] = vertex; } }
private static void MorphBoneGrow(LimbDataBone bone, BonePixels bonePixel, float scale) { var boneStartPoint = new Vector2(bone.StartPoint.X, bone.StartPoint.Y); var boneEndPoint = new Vector2(bone.EndPoint.X, bone.EndPoint.Y); var indices = bonePixel.VertexIndices; foreach (var vertexIndex in indices) { var vertex = GB.LimbDataManager.LimbData.Mesh.Vertices[vertexIndex]; var vertexPoint = new Vector2(vertex.X, vertex.Y); var vertexWeight = GB.LimbDataManager.LimbData.Mesh.GetVertexWeight(vertex); var distance = Vector2.Distance(vertexPoint, boneEndPoint); var directionVector = Vector2.Normalize(vertexPoint - boneEndPoint); vertex.X += distance * directionVector.X * scale * vertexWeight / 2f; vertex.Y += distance * directionVector.Y * scale * vertexWeight / 2f; vertex.Z = bone.BoneHash; GB.LimbDataManager.LimbData.Mesh.Vertices[vertexIndex] = vertex; } }
private void ProcessBoneJoint(LimbDataSkeleton limbDataSkeleton, LimbDataBone bone, Queue <int> pixelsQueue, Vector3 perpendicularVector, bool isStart, BoneConfiguration boneConfiguration) { if (bone.Points.Count == 0) { return; } var startIndex = (int)Math.Floor(bone.Points.Count * boneConfiguration.StartOffset) + 1; if (startIndex >= bone.Points.Count) { startIndex = bone.Points.Count - 1; } var endIndex = (int)Math.Ceiling(bone.Points.Count * (1f - boneConfiguration.EndOffset)) - 1; if (endIndex >= bone.Points.Count) { endIndex = bone.Points.Count - 1; } var startWidth = boneConfiguration.StartWidth; var endWidth = boneConfiguration.EndWidth; var length = endIndex - startIndex; for (var k = startIndex; k < endIndex; k += 3) { var point = bone.Points[k]; var isOk = true; var progress = (float)(k - startIndex) / length; var width = Utils.Interpolate(startWidth, endWidth, progress); for (var i = 1; i < width; i++) { if (!isOk) { break; } { var bufferIndex = Utils.CoordinatesToIndex((int)point.X, (int)point.Y); if (bufferIndex > 0 && bufferIndex < LimbData.AllPixels.Length) { var pixel = LimbData.AllPixels[bufferIndex]; pixel.HumanIndex = (sbyte)limbDataSkeleton.Skeleton.TrackingId; pixel.BoneHash = bone.BoneHash; pixel.IsBone = true; LimbData.ActivePixels.Add(bufferIndex); if (k == startIndex) { pixel.IsJoint = true; } pixelsQueue.Enqueue(bufferIndex); } } for (var j = -1; j <= 1; j += 2) { var offsetPoint = point + perpendicularVector * i * j; var x = (int)offsetPoint.X; var y = (int)offsetPoint.Y; if (x < 0 || x >= Configuration.Width || y < 0 || y >= Configuration.Height) { continue; } var colorBufferIndex = (x + y * Configuration.Width) * 4; if (GB.BackgroundRemovedBuffer[colorBufferIndex + 3] < Configuration.AlphaThreshold) { isOk = false; break; } var limbDataPixelIndex = colorBufferIndex / 4; var pixel = LimbData.AllPixels[limbDataPixelIndex]; if (pixel.HumanIndex != -1) { if (pixel.HumanIndex != limbDataSkeleton.Skeleton.TrackingId) { isOk = false; break; } } // test glebii if (GB.DepthBuffer[limbDataPixelIndex].Depth != 0) { var difference = Math.Abs(GB.DepthBuffer[limbDataPixelIndex].Depth - GB.SavedBackgroundDepthBuffer[limbDataPixelIndex] .Depth); if (difference < Configuration.DepthThreshold) { isOk = false; break; } } pixel.HumanIndex = (sbyte)limbDataSkeleton.Skeleton.TrackingId; pixel.BoneHash = bone.BoneHash; pixel.DebugDraw = true; LimbData.ActivePixels.Add(limbDataPixelIndex); pixelsQueue.Enqueue(limbDataPixelIndex); } } } // usun punkty przed indeksem // if (startIndex != 0) // { // bone.points.RemoveRange(0, startIndex); // startIndex = 0; // } for (var i = 0; i < startIndex; i++) { var index = (int)(bone.Points[i].X + bone.Points[i].Y * Configuration.Width); if (index > 0 && index < LimbData.AllPixels.Length) { LimbData.AllPixels[index].Clear(); } } for (var i = endIndex; i < bone.Points.Count; i++) { var index = (int)(bone.Points[i].X + bone.Points[i].Y * Configuration.Width); if (index > 0 && index < LimbData.AllPixels.Length) { LimbData.AllPixels[index].Clear(); } } bone.Points = bone.Points.GetRange(startIndex, endIndex - startIndex); }