Here are the examples of the csharp api KK_PregnancyPlus.PregnancyPlusCharaController.ApplyConditionalSphereCenterOffset(bool, UnityEngine.Vector3, UnityEngine.SkinnedMeshRenderer, UnityEngine.Transform, UnityEngine.SkinnedMeshRenderer) taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
1 Examples
19
View Source File : PPCharaController.MeshInflation.Main.cs
License : GNU General Public License v3.0
Project Creator : thojmr
License : GNU General Public License v3.0
Project Creator : thojmr
internal bool GetInflatedVerticies(SkinnedMeshRenderer smr, float sphereRadius, float waistWidth, bool isClothingMesh,
SkinnedMeshRenderer bodySmr, MeshInflateFlags meshInflateFlags)
{
Vector3 bodySphereCenterOffset = Vector3.zero;//For defaultt KK body mesh custom offset correction
if (smr == null)
{
if (PregnancyPlusPlugin.DebugLog.Value) PregnancyPlusPlugin.Logger.LogWarning($" GetInflatedVerticies smr was null");
return false;
}
//Found out body mesh can be nested under cloth game objects... Make sure to flag it as non-clothing
if (isClothingMesh && BodyNestedUnderCloth(smr, bodySmr))
{
PregnancyPlusPlugin.errorCodeCtrl.LogErrorCode(charaFileName, ErrorCode.PregPlus_BodyMeshDisguisedAsCloth,
$" body mesh {smr.name} was nested under cloth object {smr.transform.parent.name}. This is usually not an issue.");
isClothingMesh = false;
}
var meshRootTf = GetMeshRoot(smr);
if (meshRootTf == null)
{
if (PregnancyPlusPlugin.DebugLog.Value) PregnancyPlusPlugin.Logger.LogWarning($" GetInflatedVerticies meshRootTf was null");
return false;
}
// if (PregnancyPlusPlugin.DebugLog.Value) PregnancyPlusPlugin.Logger.LogInfo($" SMR pos {smr.transform.position} rot {smr.transform.rotation} parent {smr.transform.parent}");
if (!smr.sharedMesh.isReadable) nativeDetour.Apply();
var rendererName = GetMeshKey(smr);
md[rendererName].originalVertices = smr.sharedMesh.vertices;
md[rendererName].inflatedVertices = smr.sharedMesh.vertices;
md[rendererName].alteredVerticieIndexes = new bool[smr.sharedMesh.vertexCount];
//set sphere center and allow for adjusting its position from the UI sliders
Vector3 sphereCenter = GetSphereCenter(meshRootTf);
md[rendererName].yOffset = ApplyConditionalSphereCenterOffset(isClothingMesh, sphereCenter, smr, meshRootTf, bodySmr);
//Create mesh collider to make clothing measurements from skin (if it doesnt already exists)
if (NeedsClothMeasurement(smr, bodySmr, sphereCenter)) CreateMeshCollider(bodySmr);
//Get the cloth offset for each cloth vertex via raycast to skin
// Unfortunately this cant be inside the thread below because Unity Raycast are not thread safe...
var clothOffsets = DoClothMeasurement(smr, bodySmr, sphereCenter);
if (clothOffsets == null) clothOffsets = new float[md[rendererName].originalVertices.Length];
var origVerts = md[rendererName].originalVertices;
var inflatedVerts = md[rendererName].inflatedVertices;
var bellyVertIndex = md[rendererName].bellyVerticieIndexes;
var alteredVerts = md[rendererName].alteredVerticieIndexes;
//Pre compute some values needed by SculptInflatedVerticie, doin it here saves on compute in the big loop
var vertsLength = origVerts.Length;
var sphereCenterLs = meshRootTf.InverseTransformPoint(sphereCenter);
var preMorphSphereCenter = sphereCenter - GetUserMoveTransform(meshRootTf);
var pmSphereCenterLs = meshRootTf.InverseTransformPoint(preMorphSphereCenter);
//calculate the furthest back morph point based on the back bone position, include character rotation
var backExtentPos = new Vector3(preMorphSphereCenter.x, sphereCenter.y, preMorphSphereCenter.z) + meshRootTf.forward * -bellyInfo.ZLimit;
var backExtentPosLs = meshRootTf.InverseTransformPoint(backExtentPos);
//calculate the furthest top morph point based under the breast position, include character animated height differences
var topExtentPos = new Vector3(preMorphSphereCenter.x, preMorphSphereCenter.y, preMorphSphereCenter.z) + meshRootTf.up * bellyInfo.YLimit;
var topExtentPosLs = meshRootTf.InverseTransformPoint(topExtentPos);
var vertNormalCaluRadius = sphereRadius + waistWidth/10;//Only recalculate normals for verts within this radius to prevent shadows under breast at small belly sizes
var yOffsetDir = Vector3.up * md[rendererName].yOffset;//Any offset direction needed to align all meshes to the same local y height
//I dont think transforms are thread safe so get the values we need now
var meshRootTfPos = meshRootTf.position;
var meshRootTfUp = meshRootTf.up;
var mrTfTransPt = meshRootTf.localToWorldMatrix;
var mrTfInvTransPt = mrTfTransPt.inverse;
var smrTfTransPt = smr.transform.localToWorldMatrix;
var smrTfInvTransPt = smrTfTransPt.inverse;
//Lock in current slider values for threaded calculation
var infConfigClone = (PregnancyPlusData)infConfig.Clone();
//Animation curves are not thread safe, so make copies here
var bellySidesAC = new ThreadsafeCurve(BellySidesAC);
var bellyTopAC = new ThreadsafeCurve(BellyTopAC);
var bellyEdgeAC = new ThreadsafeCurve(BellyEdgeAC);
nativeDetour.Undo();
//Heavy compute task below, run in separate thread
WaitCallback threadAction = (System.Object stateInfo) =>
{
var reduceClothFlattenOffset = 0f;
#if DEBUG
var bellyVertsCount = 0;
for (int i = 0; i < bellyVertIndex.Length; i++)
{
if (bellyVertIndex[i]) bellyVertsCount++;
}
if (PregnancyPlusPlugin.DebugCalcs.Value) PregnancyPlusPlugin.Logger.LogInfo($" Mesh affected vert count {bellyVertsCount}");
#endif
//Set each verticies inflated postion, with some constraints (SculptInflatedVerticie) to make it look more natural
for (int i = 0; i < vertsLength; i++)
{
//Only care about inflating belly verticies
if (!bellyVertIndex[i] && !PregnancyPlusPlugin.DebugVerts.Value) continue;
//Convert to worldspace (in a threadsafe way), and apply and mesh offset needed
var origVertWs = smrTfTransPt.MultiplyPoint3x4(origVerts[i] - yOffsetDir);
var vertDistance = Vector3.Distance(origVertWs, sphereCenter);
//Ignore verts outside the sphere radius
if (vertDistance > vertNormalCaluRadius && !PregnancyPlusPlugin.DebugVerts.Value) continue;
Vector3 inflatedVertWs;
Vector3 verticieToSpherePos;
reduceClothFlattenOffset = 0f;
// If the vert is within the calculated normals radius, then consider it as an altered vert that needs normal recalculation when applying inflation
// Hopefully this will reduce breast shadows for smaller bellies
if (vertDistance <= vertNormalCaluRadius) alteredVerts[i] = true;
if (isClothingMesh)
{
//Calculate clothing offset distance
reduceClothFlattenOffset = GetClothesFixOffset(infConfigClone, sphereCenter, sphereRadius, waistWidth, origVertWs, smr.name, clothOffsets[i]);
}
//Shift each belly vertex away from sphere center in a sphere pattern. This is the core of the Preg+ belly shape
verticieToSpherePos = (origVertWs - sphereCenter).normalized * (sphereRadius + reduceClothFlattenOffset) + sphereCenter;
//Make adjustments to the shape to make it smooth, and feed in user slider input
inflatedVertWs = SculptInflatedVerticie(infConfigClone, origVertWs, verticieToSpherePos, sphereCenter, waistWidth,
meshRootTf, mrTfTransPt, mrTfInvTransPt, meshRootTfPos, meshRootTfUp,
preMorphSphereCenter, sphereRadius,
backExtentPos, topExtentPos, sphereCenterLs, pmSphereCenterLs, backExtentPosLs,
topExtentPosLs, bellySidesAC, bellyTopAC, bellyEdgeAC);
//Convert back to local space, and undo any temporary offset
inflatedVerts[i] = smrTfInvTransPt.MultiplyPoint3x4(inflatedVertWs) + yOffsetDir;
}
//When this thread task is complete, execute the below in main thread
Action threadActionResult = () =>
{
//If you need to debug the calculated vert positions visually
if (PregnancyPlusPlugin.DebugLog.Value)
{
// //Clear old spheres (and shows mesh root position)
// if (PregnancyPlusPlugin.DebugLog.Value) DebugTools.DrawSphereAndAttach(smr.transform, 0.01f, Vector3.zero, removeExisting: true);
// for (int i = 0; i < origVerts.Length; i++)
// {
// //Place spheres on each vert to debug the mesh calculated position relative to other meshes
// if (PregnancyPlusPlugin.DebugLog.Value) DebugTools.DrawSphereAndAttach(smr.transform, 0.02f, origVerts[i] - yOffsetDir, removeExisting: false);
// //Original non offset mesh
// // if (PregnancyPlusPlugin.DebugLog.Value) DebugTools.DrawSphereAndAttach(ChaControl.transform, 0.02f, smr.transform.TransformPoint(origVerts[i]), false);
// }
//Some other internally measured points/boundaries
// if (PregnancyPlusPlugin.DebugLog.Value) DebugTools.DrawSphereAndAttach(smr.transform, 0.2f, sphereCenter);
// var topExtentOffset = topExtentPosLs.y/10;
// if (PregnancyPlusPlugin.DebugLog.Value) DebugTools.DrawLineAndAttach(meshRootTf, 5, topExtentPosLs, removeExisting: false);
// if (PregnancyPlusPlugin.DebugLog.Value) DebugTools.DrawLineAndAttach(meshRootTf, 5, topExtentPosLs + meshRootTf.up * -topExtentOffset, removeExisting: false);
// if (PregnancyPlusPlugin.DebugLog.Value) DebugTools.DrawLineAndAttach(meshRootTf, 5, meshRootTf.InverseTransformPoint(sphereCenter));
// if (PregnancyPlusPlugin.DebugLog.Value && isClothingMesh) DebugTools.DrawLineAndAttach(smr.transform, 1, smr.sharedMesh.bounds.center - yOffsetDir);
}
//Apply computed mesh back to body
var appliedMeshChanges = ApplyInflation(smr, rendererName, meshInflateFlags.OverWriteMesh, blendShapeTempTagName, meshInflateFlags.bypreplacedWhen0);
//When inflation is actively happening as clothing changes, make sure the new clothing grows too
if (isDuringInflationScene) AppendToQuickInflateList(smr);
if (appliedMeshChanges) infConfigHistory = infConfigClone;
};
//Append to result queue. Will execute on next Update()
threading.AddResultToThreadQueue(threadActionResult);
};
//Start this threaded task, and will be watched in Update() for completion
threading.Start(threadAction);
return true;
}