KK_PregnancyPlus.PregnancyPlusCharaController.ApplyConditionalSphereCenterOffset(bool, UnityEngine.Vector3, UnityEngine.SkinnedMeshRenderer, UnityEngine.Transform, UnityEngine.SkinnedMeshRenderer)

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 7

19 View Source File : PPCharaController.MeshInflation.Main.cs
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;                 
        }