Example #1
0
    void Start()
    {
        _oFlexShapeMatching     = GetComponent<uFlex.FlexShapeMatching>();
        _oFlexParticles         = GetComponent<uFlex.FlexParticles>();
        _vecSizeParticles   = new Vector3(_SizeParticles, _SizeParticles, _SizeParticles);
        _vecSizeShapes      = new Vector3(_SizeShapes, _SizeShapes, _SizeShapes);

        //=== Create new nodes to render all particles ===
        _aVisParticles = new CVisualizeParticle[_oFlexParticles.m_particlesCount];
        for (int nParticle = 0; nParticle < _oFlexParticles.m_particlesCount; nParticle++) {
            GameObject oTemplateGO = Resources.Load("Prefabs/CVisualizeParticle", typeof(GameObject)) as GameObject;
            GameObject oParticleGO = Instantiate(oTemplateGO) as GameObject;
            CVisualizeParticle oVisParticle = CUtility.FindOrCreateComponent(oParticleGO, typeof(CVisualizeParticle)) as CVisualizeParticle;
            _aVisParticles[nParticle] = oVisParticle;
            oVisParticle.Initialize(this, nParticle);
        }

        //=== Create new nodes to render all shapes ===
        _aVisShapes = new CVisualizeShape[_oFlexShapeMatching.m_shapesCount];
        for (int nShape = 0; nShape < _oFlexShapeMatching.m_shapesCount; nShape++){
            GameObject oTemplateGO = Resources.Load("Prefabs/CVisualizeShape", typeof(GameObject)) as GameObject;
            GameObject oParticleGO = Instantiate(oTemplateGO) as GameObject;
            CVisualizeShape oVisShape = CUtility.FindOrCreateComponent(oParticleGO, typeof(CVisualizeShape)) as CVisualizeShape;
            _aVisShapes[nShape] = oVisShape;
            oVisShape.Initialize(this, nShape);
        }

        GetComponent<MeshRenderer>().enabled = false;           // Hide the soft body renderer out of convenience so we see inside ###IMPROVE: Set transparent?
    }
Example #2
0
    uFlex.FlexSprings _oFlexSprings; // Reference to spring component we're modifying to make pinning possible

    #endregion Fields

    #region Methods

    public void Initialize(ref List<ushort> aMapPinnedParticles, CBSkinBaked oMeshSoftBodyPinnedParticles)
    {
        //=== Obtain reference to the objects we'll need at every game frame ===
        _aMapPinnedParticles = aMapPinnedParticles;
        _nNumMappingsSkinToSim = _aMapPinnedParticles.Count / 2;         // Each mapping takes two slots in _aMapPinnedParticles
        _oMeshSoftBodyPinnedParticles = oMeshSoftBodyPinnedParticles;
        _oFlexParticles = CUtility.FindOrCreateComponent(gameObject, typeof(uFlex.FlexParticles)) as uFlex.FlexParticles;     // Find or create these necessary compoenent from our parent
        _oFlexSprings   = CUtility.FindOrCreateComponent(gameObject, typeof(uFlex.FlexSprings))   as uFlex.FlexSprings;

        //=== Create extra particles and springs for our parent's Flex objects ===
        ushort nStartOfExtraParticles = (ushort)_oFlexParticles.m_particlesCount;             // Remeber the split point between our parent's Flex particles/springs and the new ones we're adding
        ushort nStartOfExtraSprings = (ushort)_oFlexSprings.m_springsCount;
        _oFlexParticles.m_particlesCount    += _nNumMappingsSkinToSim;          // Add just the number of particles and springs we need (have a 1:1 relationship)
        _oFlexSprings.  m_springsCount      += _nNumMappingsSkinToSim;
        Array.Resize<uFlex.Particle>    (ref _oFlexParticles.m_particles,           _oFlexParticles.m_particlesCount);
        Array.Resize<bool>              (ref _oFlexParticles.m_particlesActivity,   _oFlexParticles.m_particlesCount);
        Array.Resize<Vector3>           (ref _oFlexParticles.m_velocities,          _oFlexParticles.m_particlesCount);
        Array.Resize<float>             (ref _oFlexParticles.m_densities,           _oFlexParticles.m_particlesCount);
        Array.Resize<Color>             (ref _oFlexParticles.m_colours,             _oFlexParticles.m_particlesCount);
        Array.Resize<int>               (ref _oFlexSprings.m_springIndices,         _oFlexSprings.m_springsCount * 2);
        Array.Resize<float>             (ref _oFlexSprings.m_springRestLengths,     _oFlexSprings.m_springsCount);
        Array.Resize<float>             (ref _oFlexSprings.m_springCoefficients,    _oFlexSprings.m_springsCount);

        //=== Define the extra particles and springs between the skinned portion and the simulated portion ===
        ushort nNextPinnedParticle = nStartOfExtraParticles;
        ushort nNextSpring         = nStartOfExtraSprings;
        for (ushort nMapping = 0; nMapping < _nNumMappingsSkinToSim; nMapping++) {     //###F ###BUG??? Assumes all skinned particles are used?  ###CHECK!
            ushort nMappingX2 = (ushort)(nMapping * 2);
            //ushort nParticleSkinned             = _aMapPinnedParticles[nMappingX2 + 0];              // The index of the skinned particle in this mapping (sparsely populated)
            ushort nParticleSimulatedMoving     = _aMapPinnedParticles[nMappingX2 + 1];              // The index of the simulated particle in this mapping (moves as usual but has a spring to nParticleSimulatedPinned pinned particle)
            ushort nParticleSimulatedPinned     = nNextPinnedParticle++;                            // The ordinal of the (new) pinned Flex-simulated particle is the next ordinal.
            ushort nSpring                      = nNextSpring++;
            _aMapPinnedParticles[nMappingX2 + 1] = nParticleSimulatedPinned;                     // We never need to address the moving particle after this loop... so re-use the map to point to the pinned particle we'll need to move everyframe instead.
            _oFlexParticles.m_particles[nParticleSimulatedPinned].invMass = 0;        // The extra particle is always the skinned one which we drive so it gets infinite mass to not be simulated
            _oFlexParticles.m_particles[nParticleSimulatedPinned].pos = _oFlexParticles.m_particles[nParticleSimulatedMoving].pos;
            _oFlexParticles.m_colours[nParticleSimulatedPinned] = Color.gray;        //###TODO: Standardize Flex colors!
            _oFlexParticles.m_particlesActivity[nParticleSimulatedPinned] = true;
            _oFlexSprings.m_springRestLengths [nSpring] = 0.0f;      // Springs between (master) skinned particle and (slave) simulated one is always zero... (we want simulated particle to stick as close to where it should be!)
            _oFlexSprings.m_springCoefficients[nSpring] = 1.0f;      //###TUNE: Make as stiff as possible for a given Flex iteration count.        ###IMPROVE: Enable game-time setting of this! ###F
            _oFlexSprings.m_springIndices[nSpring * 2 + 0] = nParticleSimulatedPinned;          // Create the link between the two simulated particles (pinned and moving)
            _oFlexSprings.m_springIndices[nSpring * 2 + 1] = nParticleSimulatedMoving;
        }
    }
Example #3
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);
    }
Example #4
0
 void FlexObjects_Destroy()
 {
     //=== Destroy all configure-time Flex objects for performance.  They will have to be re-created upon re-entry into configure mode ===
     GameObject.DestroyImmediate(_oMeshMorphResult.gameObject.GetComponent<uFlex.FlexParticlesRenderer>());      //###LEARN: DestroyImmediate is needed to avoid CUDA errors with regular Destroy()!
     GameObject.DestroyImmediate(_oMeshMorphResult.gameObject.GetComponent<uFlex.FlexProcessor>());
     GameObject.DestroyImmediate(_oFlexParticles);
     _oFlexParticles = null;
 }
Example #5
0
 void FlexObjects_Create()
 {
     //=== Define Flex particles from Blender mesh made for Flex ===
     int nParticles = _aVertsFlexCollider.Count;
     _oFlexParticles = CUtility.CreateFlexObjects(_oMeshMorphResult.gameObject, this, nParticles, uFlex.FlexInteractionType.SelfCollideFiltered, Color.green);		//###TODO#14: Flex Colors!
     for (int nParticle = 0; nParticle < nParticles; nParticle++) {
         int nVertWholeMesh = _aVertsFlexCollider[nParticle];				// Lookup the vert index in the full mesh from the Blender-supplied array that isolates which verts participate in the Flex collider
         //_oFlexParticles.m_particles[nParticle].pos = _oMeshMorphResult._memVerts.L[nVertWholeMesh];		// Don't position here to insure only one place positions to avoid bugs / confusion. (in PreContainerUpdate())
         _oFlexParticles.m_particles[nParticle].invMass = 0;					// We're a static collider with every particle moved by this code at every morph... (e.g. All particles are not Flex simulated)
         _oFlexParticles.m_colours[nParticle] = _oFlexParticles.m_colour;
         _oFlexParticles.m_particlesActivity[nParticle] = true;
     }
     _bParticlePositionsUpdated = true;                          // Flag Flex to perform an update of its particle positions.
 }