Exemplo n.º 1
0
    public CClothEdit(CBody oBody, string sClothType)
    {
        _oBody			= oBody;
        _sClothType		= sClothType;

        //        CBody.CBody._aBodies[0].CreateCloth("BodySuit", "_ClothSkinnedArea_Top", "Shirt")      ###One of teh body suits?
        string sCmd = _oBody._oBodyBase._sBlenderInstancePath_CBodyBase + ".CreateCloth('BodySuit', '_ClothSkinnedArea_Top', '" + _sClothType + "')";          //###DESIGN: Pass in all args from Unity?  Blender determines?
        CGame.gBL_SendCmd("CBody", sCmd);
        _sBlenderInstancePath_CClothEdit = "aCloths['" + _sClothType + "']";

        _oClothSource = CBMesh.Create(null, _oBody._oBodyBase, _sBlenderInstancePath_CClothEdit + ".oMeshClothSource", typeof(CBMesh));
    }
Exemplo n.º 2
0
    public override void OnDeserializeFromBlender()
    {
        base.OnDeserializeFromBlender();

        _sBlenderInstancePath_CCloth = CBCloth.s_sNameClothSrc_HACK;

        //=== Create the skinned-portion of the cloth.  It will be responsible for driving Flex particles that heavily influence their corresponding particles in fully-simulated cloth mesh ===
        _oBSkinBaked_SkinnedPortion = (CBSkinBaked)CBSkinBaked.Create(null, _oBodyBase, "." + _sBlenderInstancePath_CCloth + ".oMeshClothSkinned", typeof(CBSkinBaked));    //###WEAK#13!!! F*****g dot!!
        _oBSkinBaked_SkinnedPortion.transform.SetParent(transform);
        _oBSkinBaked_SkinnedPortion._oSkinMeshRendNow.enabled = false;          // Skinned portion invisible to the user.  Only used to guide simulated portion

        //=== Receive the aMapPinnedParticles array Blender created to map the skinned verts to their pertinent simulated ones ===
        List<ushort> aMapPinnedParticles = CByteArray.GetArray_USHORT("'CBody'", _oBodyBase._sBlenderInstancePath_CBodyBase + "." + _sBlenderInstancePath_CCloth + ".aMapPinnedParticles.Unity_GetBytes()");

        //=== Create the simulated part of the cloth ===
        MeshFilter oMeshFilter = GetComponent<MeshFilter>();
        MeshRenderer oMeshRend = GetComponent<MeshRenderer>();
        //oMeshRend.sharedMaterial = Resources.Load("Materials/BasicColors/TransWhite25") as Material;        //####SOON? Get mats!  ###F
        oMeshRend.sharedMaterial = Resources.Load("Materials/Test-2Sided") as Material;        //####SOON? Get mats!  ###F
        _oBSkinBaked_SkinnedPortion._oSkinMeshRendNow.sharedMaterial = oMeshRend.sharedMaterial;        // Skinned part has same material
        _oMeshNow = oMeshFilter.sharedMesh;
        _oMeshNow.MarkDynamic();                // Docs say "Call this before assigning vertices to get better performance when continually updating mesh"

        //=== Create the 'cloth at startup' mesh.  It won't get simulated and is used to reset simulated cloth to its startup position ===
        _oBMeshClothAtStartup = CBMesh.Create(null, _oBodyBase, "." + _sBlenderInstancePath_CCloth + ".oMeshClothSimulated", typeof(CBMesh));
        _oBMeshClothAtStartup.transform.SetParent(_oBodyBase.FindBone("chestUpper"));      // Reparent this 'backup' mesh to the chest bone so it rotates and moves with the body
        _oBMeshClothAtStartup.GetComponent<MeshRenderer>().enabled = false;
        //_oBMeshClothAtStartup.gameObject.SetActive(false);      // De activate it so it takes no cycle.  It merely exists for backup purposes

        //=== Create the Flex object for our simulated part ===
        CFlex.CreateFlexObject(gameObject, _oMeshNow, _oMeshNow, uFlex.FlexBodyType.Cloth, uFlex.FlexInteractionType.None, CGame.INSTANCE.nMassCloth, Color.yellow);
        uFlex.FlexProcessor oFlexProc = CUtility.FindOrCreateComponent(gameObject, typeof(uFlex.FlexProcessor)) as uFlex.FlexProcessor;
        oFlexProc._oFlexProcessor = this;
        _oFlexParticles = GetComponent<uFlex.FlexParticles>();
        _oFlexSprings   = GetComponent<uFlex.FlexSprings>();

        //=== Create the managing object and related hotspot ===
        _oObj = new CObject(this, 0, typeof(EFlexCloth), "Cloth " + gameObject.name);        //###IMPROVE: Name of soft body to GUI
        _oObj.PropGroupBegin("", "", true);
        _oObj.PropAdd(EFlexCloth.Tightness,     "Tightness",    1.0f, 0.01f, 2.5f, "");
        _oObj.PropAdd(EFlexCloth.Length,        "Length",       1.0f, 0.50f, 1.10f, "");
        _oObj.PropAdd(EFlexCloth.ClothMass,     "Mass",         1.0f, 0.0001f, 1000.0f, "");
        _oObj.FinishInitialization();
        _oWatchBone = _oBodyBase.FindBone("chestUpper");            //####HACK ####DESIGN: Assumes this cloth is a top!
        _oHotSpot = CHotSpot.CreateHotspot(this, _oWatchBone, "Clothing", false, new Vector3(0, 0.22f, 0.04f));     //###IMPROVE!!! Position offset that makes sense for that piece of clothing (from center of its verts?)

        //=== Backup the startup cloth arrays so we can adjust in a non-destructive way ===
        _aSpringRestLengthsBAK = new float[_oFlexSprings.m_springsCount];
        System.Array.Copy(_oFlexSprings.m_springRestLengths, _aSpringRestLengthsBAK, _oFlexSprings.m_springsCount);

        //=== Create the Flex-to-skinned-mesh component responsible to guide selected Flex particles to skinned-mesh positions ===
        _oPinnedParticles = CUtility.FindOrCreateComponent(gameObject, typeof(CPinnedParticles)) as CPinnedParticles;
        _oPinnedParticles.Initialize(ref aMapPinnedParticles, _oBSkinBaked_SkinnedPortion);
    }
Exemplo n.º 3
0
    CObjectBlender _oObj; // The Blender-implemented Object that exposes RTTI-like information for change Blender shape keys from Unity UI panels

    #endregion Fields

    #region Constructors

    public CBodyBase(int nBodyID, EBodySex eBodySex)
    {
        _nBodyID = nBodyID;
        _eBodySex = eBodySex;
        _sBodyPrefix = "Body" + _nBodyID.ToString();

        //=== Create default values for important body parameters from the sex ===
        if (_eBodySex == EBodySex.Man) {
            _sMeshSource = "ManA";
            _sHumanCharacterName = (_nBodyID == 0) ? "Karl" : "Brent";          //###IMPROVE: Database of names?  From user???
        } else {
            _sMeshSource = "WomanA";
            _sHumanCharacterName = (_nBodyID == 0) ? "Emily" : "Eve";
        }

        switch (_eBodySex) {                                 //###CHECK	####TEMP ####DESIGN: Loaded from file or user top-level selection! ####DESIGN: Public properties?
            case EBodySex.Man:
                _sNameSrcGenitals = "PenisM-Erotic9-A-Big";		//###TODO#11: Cleanup?
                break;
            case EBodySex.Woman:
                _sNameSrcGenitals = "V****a-Erotic9-A";                  //###DESIGN??? Crotch and not v****a???
                break;
            case EBodySex.Shemale:
                _sNameSrcGenitals = "PenisW-Erotic9-A-Big";              //###TODO: Comes from GUI!
                break;
        }

        //=== Instantiate the proper prefab for our body type (Man or Woman), which defines our bones and colliders ===
        GameObject oBodyTemplateGO = Resources.Load("Prefabs/Prefab" + _sMeshSource, typeof(GameObject)) as GameObject;      //###TODO: Different gender / body types enum that matches Blender	//oBody._sMeshSource +
        _oBodyRootGO = GameObject.Instantiate(oBodyTemplateGO) as GameObject;
        _oBodyRootGO.name = _sBodyPrefix;
        _oBodyRootGO.SetActive(true);           // Prefab is stored with top object deactivated to ease development... activate it here...

        //=== Obtain references to needed sub-objects of our prefab ===
        _oBonesT    = CUtility.FindChild(_oBodyRootGO.transform, "Bones");            // Set key nodes of Bones and Base we'll need quick access to over and over.
        _oBaseT     = CUtility.FindChild(_oBodyRootGO.transform, "Base");

        //===== CREATE THE BODY PYTHON INSTANCE IN BLENDER =====
        CGame.gBL_SendCmd("CBody", "CBodyBase_Create(" + _nBodyID.ToString() + ", '" + _sMeshSource + "', '" + eBodySex.ToString() + "','" + _sNameSrcGenitals + "')");       // This new instance is an extension of this Unity CBody instance and contains most instance members
        _sBlenderInstancePath_CBodyBase = "CBodyBase_GetBodyBase(" + _nBodyID.ToString() + ")";                 // Simplify access to Blender CBodyBase instance

        //=== Download our morphing non-skinned body from Blender ===
        GameObject oBodyBaseGO = new GameObject(_sBodyPrefix);        // Create the root Unity node that will keep together all the many subnodes of this body.
        _oMeshMorphResult = CBMesh.Create(oBodyBaseGO, this, ".oMeshMorphResult", typeof(CBMesh), true);     // Get the baked-morph mesh Blender updates for us at every morph update. (And keep Blender share so we can update)
        _oMeshMorphResult.transform.SetParent(_oBodyRootGO.transform);
        _oMeshMorphResult.name = "MorphingBody";

        //=== DEFINE THE FLEX COLLIDER: Read the collection of verts that will from the Flex collider (responsible to repell master Bodysuit from morph-time body) ===
        _aVertsFlexCollider = CByteArray.GetArray_USHORT("'CBody'", _sBlenderInstancePath_CBodyBase + ".aVertsFlexCollider.Unity_GetBytes()");
        FlexObjects_Create();			// Create the Flex objects the first time.They will be destroyed upon going to gametime

        //=== Create the managing object and related hotspot ===
        _oObj = new CObjectBlender(this, _sBlenderInstancePath_CBodyBase + ".oObjectMeshShapeKeys", _nBodyID);
        _oObj.Event_PropertyValueChanged += Event_PropertyChangedValue;
        //_oHotSpot = CHotSpot.CreateHotspot(this, null, "Body Morphing", false, new Vector3(0, 0, 0));
        _oCanvas = CUICanvas.Create(_oMeshMorphResult.transform);
        _oCanvas.transform.position = new Vector3(0.31f, 1.35f, 0.13f);            //###WEAK#11: Hardcoded panel placement in code?  Base on a node in a template instead??  ###IMPROVE: Autorotate?
        CUtility.WndPopup_Create(_oCanvas, EWndPopupType.PropertyEditor, new CObject[] { _oObj }, "Body Morphing");

        //=== Switch to morphing / configure mode ===
        OnChangeBodyMode(EBodyBaseModes.Configure);             // Enter configure mode so we can programmatically apply morphs to customize this body

        //=== Create bodycloth clothing instance.  It will be simulated as the user adjusts morphing sliders so as to set the master cloth to closely match the body's changing shape ===
        _oCloth_BodySuit = CBCloth.Create(this, "MyShirt", "Shirt", "BodySuit", "_ClothSkinnedArea_ShoulderTop");		//###DEV#13

        //=== Change some morphing channels ===		//###TODO#11: Programmatic load & adjustments of sliders from file?
        //_oObj.PropSet(0, 1);				//###IMPROVE#11: Would be of benefit to change properties by string in code? (e.g. not UI?)
        //_oObj.PropSet(1, 1);				//###WEAK#11: Properties appear in non-deterministic order!
    }
Exemplo n.º 4
0
    public override void OnDeserializeFromBlender()
    {
        base.OnDeserializeFromBlender();                    // Call important base class first to serialize rim, pinned particle mesh, etc

        //=== Create the collision mesh from Blender ===
        _oMeshFlexCollider = CBMesh.Create(null, _oBodyBase, _sBlenderInstancePath_CSoftBody + ".oMeshFlexCollider", typeof(CBMesh));       // Also obtain the Unity2Blender mesh call above created.
        _oMeshFlexCollider.GetComponent<MeshRenderer>().enabled = false;      // Collider does not render... only for Flex definition!
        _oMeshFlexCollider.transform.SetParent(transform);

        //=== Construct the Flex solid body to obtain the particles that need further processing Blender for pinning ===
        CFlex.CreateFlexObject(gameObject, _oMeshNow, _oMeshFlexCollider._oMeshNow, uFlex.FlexBodyType.Soft, uFlex.FlexInteractionType.SelfCollideFiltered, CGame.INSTANCE.nMassSoftBody, Color.red);

        //=== Obtain references to the components we'll need at runtime ===
        _oFlexParticles         = GetComponent<uFlex.FlexParticles>();              //###WEAK: Owned by base class, defined here
        _oFlexParticlesRenderer = GetComponent<uFlex.FlexParticlesRenderer>();
        _oFlexShapeMatching     = GetComponent<uFlex.FlexShapeMatching>();
        _oFlexGeneratedSMR      = GetComponent<SkinnedMeshRenderer>();

        //=== Ask Blender to create a 'Unity2Blender' mesh of the right number of verts so we can upload our Tetramesh to Blender for processing there ===
        int nVertTetras = _oFlexParticles.m_particlesCount;
        CGame.gBL_SendCmd("CBody", _sBlenderInstancePath_CSoftBody_FullyQualfied + ".CreateMesh_Unity2Blender(" + nVertTetras.ToString() + ")");        // Our softbody instance will now have its 'oMeshUnity2Blender' member populated with a temporary mesh of exactly nVertTetras verts

        //=== Obtain the Unity2Blender mesh so we can pass particles to Blender for processing there ===
        CBMesh oMesh_Unity2Blender = CBMesh.Create(null, _oBodyBase, _sBlenderInstancePath_CSoftBody + ".oMeshUnity2Blender", typeof(CBMesh), true);       // Also obtain the Unity2Blender mesh call above created.    // Keep link to Blender mesh open so we can upload our verts        //###IMPROVE: When/where to release??
        oMesh_Unity2Blender.transform.SetParent(transform);		//###IMPROVE#13: Set parent in Create() above?

        //=== Upload our particles to Blender so it can select those that are pinned and skin them ===
        for (int nVertTetra = 0; nVertTetra < nVertTetras; nVertTetra++)
            oMesh_Unity2Blender._memVerts.L[nVertTetra] = _oFlexParticles.m_particles[nVertTetra].pos;			//###LEARN: For some reason this is safe to do while still copying back to Blender... why?
        oMesh_Unity2Blender.UpdateVertsToBlenderMesh();                // Blender now has our particles.  It can now find the particles near the rim and skin them

        //=== Create and retrieve the softbody rim mesh responsible to pin softbody to skinned body ===
        float nDistSoftBodyParticlesFromBackmesh = CGame.INSTANCE.particleSpacing * CGame.INSTANCE.nDistSoftBodyParticlesFromBackmeshMult;
        CGame.gBL_SendCmd("CBody", _sBlenderInstancePath_CSoftBody_FullyQualfied + ".FindPinnedFlexParticles(" + nDistSoftBodyParticlesFromBackmesh.ToString() + ")");        // Ask Blender select the particles near the rim and skin them
        Destroy(oMesh_Unity2Blender);       // We're done with Unity2Blender mesh after FindPinnedFlexParticles... delete
        oMesh_Unity2Blender = null;

        //=== Retreive the pinned particles skinned mesh so we can manually set the position of the pinned particles to the appropriate position on the skinned main body (so softbody doesn't float into space) ===
        _oMeshPinnedParticles = (CBSkinBaked)CBMesh.Create(null, _oBodyBase, _sBlenderInstancePath_CSoftBody + ".oMeshPinnedParticles", typeof(CBSkinBaked));           // Retrieve the skinned softbody rim mesh Blender just created so we can pin softbody at runtime
        _oMeshPinnedParticles.transform.SetParent(transform);

        ////=== Obtain the map of pinned particles in skinned mesh to softbody particles in whole softbody mesh ===
        List<ushort> aMapPinnedParticles = CByteArray.GetArray_USHORT("'CBody'", _sBlenderInstancePath_CSoftBody_FullyQualfied + ".aMapPinnedParticles.Unity_GetBytes()");		// Read the particle traversal map from our CSoftBody instance

                //=== Create the Flex-to-skinned-mesh component responsible to guide selected Flex particles to skinned-mesh positions ===
        _oPinnedParticles = CUtility.FindOrCreateComponent(gameObject, typeof(CPinnedParticles)) as CPinnedParticles;
        _oPinnedParticles.Initialize(ref aMapPinnedParticles, _oMeshPinnedParticles);

        //=== Create our baked-recipient mesh ===
        _oFlexGeneratedSMR_BakedMesh = new Mesh();             // The mesh baked at every frame by _oFlexGeneratedSMR
    }