void RandomizeFigter(Poser fighter)
    {
        int pantsIndex = Random.Range(0, pants.Length + 1);

        if (pantsIndex < pants.Length)
        {
            fighter.pantsSprites = pants[pantsIndex];
            fighter.pantsSpriteRenderer.color = clothesColors[Random.Range(0, clothesColors.Length)];
        }

        int topIndex = Random.Range(0, tops.Length + 1);

        if (topIndex < tops.Length)
        {
            fighter.shirtSprites = tops[topIndex];
            fighter.shirtSpriteRenderer.color = clothesColors[Random.Range(0, clothesColors.Length)];
        }

        int hairIndex = Random.Range(0, hair.Length + 1);

        if (hairIndex < hair.Length)
        {
            fighter.hairSprites = hair[hairIndex];
            fighter.hairSpriteRenderer.color = hairColors[Random.Range(0, hairColors.Length)];
        }

        fighter.manSpriteRenderer.color = skinColors[Random.Range(0, skinColors.Length)];
    }
Exemple #2
0
    IEnumerator Record()
    {
        records         = new List <Pose> (recordCount);
        isRecording     = true;
        recordBeginTime = Time.time;
        Poser poser = currentShelf.CurrentPoser();

        UpdateInfoText(INFO_TEXT_NOW_RECORDING);

        for (int i = 0; i < recordCount; i++)
        {
            if (isRecording == false || records == null)
            {
                recordBeginTime = 0;
                yield break;
            }
            records.Add(poser.GetCurrentPose());
            yield return(new WaitForSeconds(recordInterval));
        }

        isRecording = false;

        poser.DisconnectFromRigidbody();
        poser.Highlighted = Highlightable.HighlightDegree.Pale;
        poser.EditEnabled = false;

        UpdateInfoText(INFO_TEXT_RECORDING_DONE);
        EnqueueCommentText(COMMENT_TEXT_RECORDING_DONE_BY_TIMER);
    }
Exemple #3
0
    IEnumerator OnSaveButtonPicked()
    {
        if (state != State.Edit)
        {
            yield break;
        }

        UpdateInfoText(INFO_TEXT_RECORDING_DONE);
        EnqueueCommentText(COMMENT_TEXT_RECORDING_DONE_BY_BUTTON);

        isRecording = false;

        saveEditingButton.SwellAndDisable();
        cancelEditingButton.enabled = false;
        doneEditingButton.enabled   = true;

        Poser poser = currentShelf.CurrentPoser();

        poser.Highlighted = Highlightable.HighlightDegree.Pale;
        poser.EditEnabled = false;

        yield return(StartCoroutine(FadeOutVignette()));

        state = State.TypeTextInfo;
        yield return(StartCoroutine(FadeInTitleAuthorTextField()));
    }
Exemple #4
0
    IEnumerator OnEditButtonPicked()
    {
        if (state != State.Show)
        {
            yield break;
        }

        state = State.Edit;

        UpdateInfoText(INFO_TEXT_NEW_RECORDING);
        EnqueueCommentText(COMMENT_TEXT_ENCOURAGE_PICK_A_PART);

        editButton.SwellAndDisable();
        cancelEditingButton.enabled = true;

        StartCoroutine(FadeInVignette());
        yield return(new WaitForSeconds(0.5f));

        Poser poser = currentShelf.CurrentPoser();

        poser.EditEnabled = true;
        poser.Highlighted = Highlightable.HighlightDegree.Full;

        yield return(new WaitForSeconds(.25f));

        poser.Highlighted = Highlightable.HighlightDegree.None;

        isWaitingFirstPick = true;
        pickedAnyPart      = false;
        StartCoroutine(WaitFirstPickAndRecord());
    }
Exemple #5
0
    IEnumerator OnCancelButtonPicked()
    {
        if (state != State.Edit)
        {
            yield break;
        }

        pickedAnyPart      = false;
        isWaitingFirstPick = false;
        isRecording        = false;
        records            = null;

        cancelEditingButton.SwellAndDisable();
        editButton.enabled        = true;
        saveEditingButton.enabled = false;

        yield return(StartCoroutine(FadeOutVignette()));

        state = State.Show;

        Poser poser = currentShelf.CurrentPoser();

        poser.ApplyPose(Pose.DefaultPose(), 1);
        poser.Highlighted = Highlightable.HighlightDegree.Pale;
        poser.EditEnabled = false;

        UpdateGalleryInfoAndComment(skipComment: true);
    }
Exemple #6
0
    public void InsertPresetBeforeLast(Preset preset)
    {
        presets.InsertBeforeLast(preset);

        Poser lastSlot = slots [(SlotsNum / 2) + 1];

        lastSlot.ApplyPreset(presets.Get(presets.Count - 1));
    }
Exemple #7
0
 void CreateSlots()
 {
     for (int i = 0; i < SlotsNum; i++)
     {
         Transform puppet = (Transform)Instantiate(puppetPrefab, GetSlotPosition(i), Quaternion.identity);
         Poser     poser  = puppet.gameObject.GetComponent <Poser>();
         slots.Add(poser);
     }
 }
Exemple #8
0
        private void DoGenerate(MmdModel model, MmdMotion motion, string savePath, float frameStepLength, float timeAfterMotionFinish, float physicsStepLength)
        {
            try
            {
                _status = GenerateStatus.Preparing;
                if (physicsStepLength > frameStepLength)
                {
                    physicsStepLength = frameStepLength;
                }
                var poser          = new Poser(model);
                var motionPlayer   = new MotionPlayer(motion, poser);
                var physicsReactor = new BulletPyhsicsReactor();

                var totalTimeLength = motion.Length / 30.0 + timeAfterMotionFinish;
                var totalStepCount  = (int)(totalTimeLength / frameStepLength) + 1;
                var playPos         = 0.0;
                var maxSubSteps     = (int)(frameStepLength / physicsStepLength) + 1;

                using (var fileStream = new FileStream(savePath, FileMode.Create))
                {
                    using (var bufferedStream = new BufferedStream(fileStream))
                    {
                        using (var binaryWriter = new BinaryWriter(bufferedStream))
                        {
                            WriteHeader(binaryWriter, model, totalStepCount + 1, frameStepLength);
                            _status           = GenerateStatus.CalculatingFrames;
                            _totalFrames      = totalStepCount + 1;
                            _calculatedFrames = 0;
                            physicsReactor.AddPoser(poser);
                            motionPlayer.SeekFrame(0);
                            poser.PrePhysicsPosing();
                            physicsReactor.Reset();
                            poser.PostPhysicsPosing();
                            WritePose(binaryWriter, poser);
                            _calculatedFrames = 1;
                            for (var i = 0; i < totalStepCount; ++i)
                            {
                                playPos += frameStepLength;
                                motionPlayer.SeekTime(playPos);
                                poser.PrePhysicsPosing();
                                physicsReactor.React(frameStepLength, maxSubSteps, physicsStepLength);
                                poser.PostPhysicsPosing();
                                WritePose(binaryWriter, poser);
                                _calculatedFrames = i + 2;
                            }
                        }
                    }
                }
                _status = GenerateStatus.Finished;
            }
            catch (Exception e)
            {
                _status = GenerateStatus.Failed;
                Debug.LogException(e);
            }
        }
        private static void WritePose(BinaryWriter writer, Poser poser)
        {
            var bonePoseImages = BonePosePreCalculator.GetBonePoseImage(poser);

            foreach (var bonePose in bonePoseImages)
            {
                WriteVector3(writer, bonePose.Position);
                WriteVector3(writer, bonePose.Rotation.eulerAngles);
            }
        }
    public ActorBehavior(ControllerManager controllerManager, ActorModel model, InverterParameters inverterParameters)
    {
        this.model         = model;
        poser              = new Poser(model.MainDefinition);
        ikAnimator         = new InverseKinematicsAnimator(controllerManager, model.MainDefinition, inverterParameters);
        proceduralAnimator = new StandardProceduralAnimator(model.MainDefinition, model.Behavior);
        dragHandle         = new DragHandle(controllerManager, InitialSettings.InitialTransform);

        model.PoseReset += ikAnimator.Reset;
    }
Exemple #11
0
 void ApplyPresetsToSlots()
 {
     for (int i = 0; i < SlotsNum; i++)
     {
         Poser  poser = slots[i];
         int    indexRelativeToDataSource = i - (SlotsNum / 2) + index;
         Preset preset = presets.Get(indexRelativeToDataSource);
         poser.ApplyPreset(preset);
     }
 }
        public PoserMotionState(Poser poser, MmdRigidBody body, Matrix bodyTransform)
        {
            _poser            = poser;
            _passive          = body.Type == MmdRigidBody.RigidBodyType.RigidTypeKinematic;
            _strict           = body.Type == MmdRigidBody.RigidBodyType.RigidTypePhysicsStrict;
            _ghost            = body.Type == MmdRigidBody.RigidBodyType.RigidTypePhysicsGhost;
            _target           = GetPoserBoneImage(poser, body.AssociatedBoneIndex);
            _bodyTransform    = bodyTransform;
            _bodyTransformInv = Matrix.Invert(bodyTransform);

            Reset();
        }
        private void DoLoadModel(string filePath)
        {
            Debug.LogFormat("start load model {0}", filePath);
            _model = ModelReader.LoadMmdModel(filePath, _modelReadConfig);
            Release();
            var directoryInfo = new FileInfo(filePath).Directory;

            if (directoryInfo == null)
            {
                throw new MmdFileParseException(filePath + " does not belong to any directory.");
            }
            var relativePath = directoryInfo.FullName;

            _materialLoader = new MaterialLoader(new TextureLoader(relativePath, DefaultMaxTextureSize));
            var vertCount = _model.Vertices.Length;

            if (vertCount <= 65535)
            {
                var mesh = new Mesh
                {
                    vertices = new Vector3[vertCount],
                    normals  = new Vector3[vertCount]
                };
                var triangleCount = _model.TriangleIndexes.Length / 3;
                var triangles     = _model.TriangleIndexes;
                FillSubMesh(mesh, triangleCount, triangles);
                var uv    = ExtratUv(_model.Vertices);
                var uvVec = new Vector2[vertCount];
                Utils.MmdUvToUnityUv(uv, uvVec);
                mesh.uv          = uvVec;
                mesh.boneWeights = _model.Vertices.Select(x => ConvertBoneWeight(x.SkinningOperator)).ToArray();
                ReleasePreviousMeshes();
                Mesh = mesh;
                mesh.RecalculateBounds();
                _partIndexes = null;
            }
            else
            {
                var triangleCount = _model.TriangleIndexes.Length / 3;
                var triangles     = _model.TriangleIndexes;
                var uv            = ExtratUv(_model.Vertices);
                ;
                var uvVec = new Vector2[vertCount];
                Utils.MmdUvToUnityUv(uv, uvVec);
                FillPartMeshes(triangleCount, triangles, uv);
            }
            _poser          = new Poser(_model);
            _physicsReactor = new BulletPyhsicsReactor();
            _physicsReactor.AddPoser(_poser);
            InitMesh();
            Debug.LogFormat("load model finished {0}", filePath);
        }
Exemple #14
0
    void BeginPlayCenterSlotIfAnimated()
    {
        Preset centerPreset = currentShelf.CurrentPreset();

        if (centerPreset.Type == Preset.PresetType.Animated)
        {
            Poser       centerPoser = currentShelf.CurrentPoser();
            List <Pose> motion      = centerPreset.Motion;
            StartCoroutine(centerPoser.BeginMotion(motion, recordInterval / PLAYBACK_SPEED));
            isPlaying     = true;
            playBeginTime = Time.time;
        }
    }
Exemple #15
0
    void OnDoneButtonPicked()
    {
        if (state != State.TypeTextInfo)
        {
            return;
        }

        state = State.Show;

        if (displayingTitle.Equals(TITLE_PLACEHOLDER))
        {
            displayingTitle = "무제";
        }
        if (displayingAuthor.Equals(AUTHOR_PLACEHOLDER))
        {
            displayingAuthor = "익명";
        }
        titleStyle.normal.background  = null;
        authorStyle.normal.background = null;

        doneEditingButton.SwellAndDisable();

        Poser poser = currentShelf.CurrentPoser();

        poser.EditEnabled = true;
        poser.Highlighted = Highlightable.HighlightDegree.None;
        poser.EditEnabled = false;

        Preset lastPreset      = currentShelf.LastPreset();
        int    fileIndexToSave = 0;

        if (lastPreset != null)
        {
            fileIndexToSave = lastPreset.FileIndex + 1;
        }
        List <Pose> motion = records;

        records = null;
        Preset preset = new Preset(motion, displayingTitle, displayingAuthor, fileIndexToSave);

        currentShelf.InsertPresetBeforeLast(preset);

        BeginPlayCenterSlotIfAnimated();

        UpdateGalleryInfoAndComment(skipComment: true);

        StartCoroutine(SavePresetAsFile(preset, fileIndexToSave));

        audio.PlayOneShot(audioSaveSuccess);
    }
Exemple #16
0
        private static void SeedFavoritesJson(string outputDirectory)
        {
            var poser = new Poser("Favorites", String.Empty);
            poser.AddPack(new PoserPack("Favorites"));

            var outputFile = outputDirectory + Resources.FavoritesJsonName;

            // only write if a favorites file is not present
            if (!File.Exists(outputFile))
            {
                Program.Log.Write("Creating new " + outputFile);
                File.WriteAllText(outputFile, poser.ToPapyrusUtilJson());
            }
        }
Exemple #17
0
        private void SetPoseToPoser(MmdPose pose, Poser poser)
        {
            var nameToIndex = BuildBoneNameToIndexDictionary(poser.Model);

            foreach (var entry in pose.BonePoses)
            {
                var name     = entry.Key;
                var bonePose = entry.Value;
                int index;
                if (!nameToIndex.TryGetValue(name, out index))
                {
                    continue;
                }
                poser.SetBonePose(index, bonePose);
            }
        }
Exemple #18
0
        public BonePosePreCalculator(MmdPose pose, Poser poser, BulletPyhsicsReactor physicsReactor, double stepLength, double startTimePos, int frameCacheSize, bool autoStepLength)
        {
            _poseMode            = true;
            _poser               = poser;
            _physicsReactor      = physicsReactor;
            _stepLength          = stepLength;
            _bonePoseImagesStore = new BlockingQueue <BonePoseFrame>(frameCacheSize);
            _timePos             = startTimePos;
            _autoStepLength      = autoStepLength;

            poser.ResetPosing();
            SetPoseToPoser(pose, _poser);
            _poser.PrePhysicsPosing();
            _physicsReactor.Reset();
            _poser.PostPhysicsPosing();
            var image = GetBonePoseImage(_poser);

            _bonePoseImagesStore.Enqueue(new BonePoseFrame(startTimePos, image));
        }
Exemple #19
0
        public BonePosePreCalculator(Poser poser, BulletPyhsicsReactor physicsReactor, MotionPlayer motionPlayer, double stepLength, double startTimePos, int frameCacheSize, bool autoStepLength)
        {
            _poseMode            = false;
            _poser               = poser;
            _physicsReactor      = physicsReactor;
            _motionPlayer        = motionPlayer;
            _stepLength          = stepLength;
            _bonePoseImagesStore = new BlockingQueue <BonePoseFrame>(frameCacheSize);
            _timePos             = startTimePos;
            _autoStepLength      = autoStepLength;

            _motionPlayer.SeekTime(startTimePos);
            _poser.PrePhysicsPosing();
            _physicsReactor.Reset();
            _poser.PostPhysicsPosing();
            var image = GetBonePoseImage(_poser);

            _bonePoseImagesStore.Enqueue(new BonePoseFrame(startTimePos, image));
        }
Exemple #20
0
        public BonePosePreCalculator(BonePoseCalculatorWorker worker, MmdPose pose, Poser poser, BulletPyhsicsReactor physicsReactor, float stepLength, float startTimePos, int frameCacheSize, bool autoStepLength)
        {
            _poseMode            = true;
            _poser               = poser;
            _physicsReactor      = physicsReactor;
            _stepLength          = stepLength;
            _bonePoseImagesStore = new SynchronizedQueue <BonePoseFrame>();
            _timePos             = startTimePos;
            _autoStepLength      = autoStepLength;
            _frameCacheSize      = frameCacheSize;
            poser.ResetPosing();
            SetPoseToPoser(pose, _poser);
            _poser.PrePhysicsPosing();
            _physicsReactor.Reset();
            _poser.PostPhysicsPosing();
            var image = GetBonePoseImage(_poser);

            _bonePoseImagesStore.Enqueue(new BonePoseFrame(startTimePos, image));
            _worker = worker;
        }
Exemple #21
0
        public static BonePoseImage[] GetBonePoseImage(Poser poser)
        {
            var boneCount       = poser.BoneImages.Length;
            var ret             = new BonePoseImage[boneCount];
            var model           = poser.Model;
            var poserBoneImages = poser.BoneImages;

            for (var i = 0; i < boneCount; ++i)
            {
                var poserBoneImage = poserBoneImages[i];
                var position       = poserBoneImage.SkinningMatrix.MultiplyPoint3x4(model.Bones[i].Position);
                var rotation       = poserBoneImage.SkinningMatrix.ExtractRotation();
                ret[i] = new BonePoseImage
                {
                    Position = position,
                    Rotation = rotation
                };
            }
            return(ret);
        }
        void Start()
        {
            // Find some components.
            ik             = GetComponent <FullBodyBipedIK>();
            poserLeftHand  = ik.references.leftHand.GetComponent <Poser>();
            poserRightHand = ik.references.rightHand.GetComponent <Poser>();

            ik.solver.OnPostUpdate += AfterFBBIK;
            lastWeight              = weight;

            SetHandedness(handedness);

            // Remember some default positions
            defaultWeaponsAnchorLocalPosition = weaponsAnchor.localPosition;
            weaponsPivotLocalPosition         = weaponsPivot.localPosition;
            pivotRelativePosition             = pivotMotionTarget.InverseTransformPoint(weaponsPivot.position);

            cameraPosition        = TargetsCameraPosition();
            lastCharacterPosition = characterController.position;
        }
Exemple #23
0
        public override void RemovePoser(Poser poser)
        {
            if (!_rigidBodies.ContainsKey(poser))
            {
                return;
            }

            var constraints = _constraints[poser];
            var rigidBodies = _rigidBodies[poser];

            foreach (var constraint in constraints)
            {
                _world.RemoveConstraint(constraint);
            }
            foreach (var rigidBody in rigidBodies)
            {
                _world.RemoveRigidBody(rigidBody);
            }
            _constraints.Remove(poser);
            _rigidBodies.Remove(poser);
            _motionStates.Remove(poser);
        }
Exemple #24
0
        private void FavoritesToFnisListToolStripMenuItemClick(object sender, EventArgs e)
        {
            // warn to scare curious users
            var dialogResult = MessageBox.Show(
                Resources.CommonString_ScareMessage,
                Resources.CommonString_Warning,
                MessageBoxButtons.YesNo);
            if (dialogResult == DialogResult.No)
            {
                return;
            }

            // start logging
            Program.Log.Write("\nGenerate FNIS List from Favorites: " + DateTime.Now.ToString("u"));

            // locate favorites
            var favoritesJsonFilePath = this.skyrimDirectory + Resources.PoserHotkeysDataPath + Resources.FavoritesJsonName;
            if (!File.Exists(favoritesJsonFilePath))
            {
                var errorMessage = "Unable to locate favorites at " + favoritesJsonFilePath;
                MessageBox.Show(errorMessage, Resources.CommonString_Error, MessageBoxButtons.OK);
                Program.Log.Write(errorMessage);
                return;
            }

            // deserialize favorites
            var favoritesJsonData = File.ReadAllText(favoritesJsonFilePath);
            var favorites = JsonUtilFavorites.Deserialize(favoritesJsonData);

            // setup output paths
            var fnisOutputDirectory = this.skyrimDirectory + Resources.AnimationsDataPath + "PoserHotkeys\\";
            var fnisOutputFilePath = fnisOutputDirectory + "FNIS_PoserHotkeys_List.txt";
            var jsonOutputDirectory = this.skyrimDirectory + Resources.PoserHotkeysDataPath;

            // ensure output directory exists
            if (!Directory.Exists(fnisOutputDirectory))
            {
                Program.Log.Write("Creating directory: " + fnisOutputDirectory);
                Directory.CreateDirectory(fnisOutputDirectory);
            }

            // generate data
            var fnisLines = new ConcurrentBag<string>();
            using (var pleaseWaitMessage = new FormPleaseWaitMessage())
            {
                pleaseWaitMessage.Show(this);
                pleaseWaitMessage.Update();
                try
                {
                    // read fnis animation defintions
                    var availablePosers = this.checkedListBoxPosers.Items.OfType<Poser>();
                    var posersList = availablePosers as IList<Poser> ?? availablePosers.ToList();
                    Parallel.ForEach(
                        posersList,
                        poser =>
                            {
                                poser.PopulateAnimationEventDictionary();
                            });

                    Program.Log.Write("FNIS AnimationEvent dictionaries populated.");
                    Program.Log.Write("Attempting to match " + favorites.stringList.favorites.Count + " favorites.");

                    // compile line matches
                    Parallel.ForEach(
                        favorites.stringList.favorites,
                        favorite =>
                            {
                                Parallel.ForEach(
                                    this.posers,
                                    poser =>
                                        {
                                            if (poser.FnisLines.ContainsKey(favorite))
                                            {
                                                fnisLines.Add(poser.FnisLines[favorite]);
                                            }
                                        });
                            });

                    Program.Log.Write("Successfully matched " + fnisLines.Count + " favorites.");

                    // write results to file
                    Program.Log.Write("Overwritting " + fnisOutputFilePath);
                    File.WriteAllLines(fnisOutputFilePath, fnisLines);

                    // generate json for favorites
                    var favoritesPoser = new Poser(Resources.FavoritesPoserName, fnisOutputDirectory);
                    favoritesPoser.PopulatePacks(false);
                    WriteJson(new List<Poser> { favoritesPoser }, jsonOutputDirectory);
                }
                catch (Exception exception)
                {
                    Program.Log.Write("Fatal Error: " + exception.Message);
                    throw;
                }
                pleaseWaitMessage.Close();
            }

            // show summary
            var summaryMessage =
                String.Format(
                    $"Generated {fnisLines.Count} animation events."
                    + $"\n\nWrote FNIS data to:\n{fnisOutputFilePath}"
                    + $"\n\nWrote json data to:\n{jsonOutputDirectory + Resources.FavoritesPoserName}.json"
                    + "\n\nYou may now run FNIS Generator for Modders.");
            MessageBox.Show(summaryMessage, Resources.CommonString_Summary, MessageBoxButtons.OK);
            this.buttonQuit.Select();
        }
Exemple #25
0
    public bool Flip(bool toLeft = true, float speedMultiplier = 1)
    {
        int desiredIndex = (toLeft? index + 1 : index - 1);

        if (0 > desiredIndex || desiredIndex >= presets.Count)
        {
            return(false);
        }

        Poser  currentPoser  = CurrentPoser();
        Preset currentPreset = CurrentPreset();

        if (currentPreset.Pose != null)
        {
            currentPoser.StopMotion();
            currentPoser.ApplyPose(currentPreset.Pose, FLIP_DURATION / speedMultiplier / 2);
        }

        index = desiredIndex;

        int tweenSlotBeginIndex = 0;
        int tweenSlotEndIndex   = 0;
        int lastSlotIndex       = SlotsNum - 1;

        if (toLeft)
        {
            tweenSlotBeginIndex = 1;
            tweenSlotEndIndex   = lastSlotIndex;
        }
        else
        {
            tweenSlotBeginIndex = 0;
            tweenSlotEndIndex   = lastSlotIndex - 1;
        }

        for (int i = tweenSlotBeginIndex; i <= tweenSlotEndIndex; i++)
        {
            int     newIndex    = i + (toLeft? -1 : +1);
            Vector3 newPosition = GetSlotPosition(newIndex);
            LTDescr tween       = LeanTween.moveLocal(slots[i].gameObject, newPosition, FLIP_DURATION / speedMultiplier).setEase(LeanTweenType.easeInOutCubic);
            if (i == CenterSlot)
            {
                tween.setOnComplete(OnCenterSlotFlipComplete);
            }
        }

        int   poppingSlotIndex = (toLeft? 0 : lastSlotIndex);
        Poser reusedSlot       = slots[poppingSlotIndex];

        slots.RemoveAt(poppingSlotIndex);

        int halfSlotsNum        = SlotsNum / 2;
        int endPointPresetIndex = index + (toLeft? halfSlotsNum : -halfSlotsNum);

        reusedSlot.ApplyPreset(presets.Get(endPointPresetIndex));

        int pushingSlotIndex = (toLeft? lastSlotIndex : 0);

        slots.Insert(pushingSlotIndex, reusedSlot);

        reusedSlot.transform.localPosition = GetSlotPosition(pushingSlotIndex);

        return(true);
    }
Exemple #26
0
        public override void AddPoser(Poser poser)
        {
            var model = poser.Model;

            if (_rigidBodies.ContainsKey(poser))
            {
                return;
            }
            poser.ResetPosing();
            var motionStates = new List <PoserMotionState>();

            _motionStates.Add(poser, motionStates);
            var rigidBodies = new List <RigidBody>();

            _rigidBodies.Add(poser, rigidBodies);
            var constraints = new List <Generic6DofSpringConstraint>();

            _constraints.Add(poser, constraints);

            foreach (var body in model.Rigidbodies)
            {
                var bodyDimension = body.Dimemsions;

                CollisionShape btShape = null;

                var btMass         = 0.0f;
                var btLocalInertia = new Vector3(0.0f, 0.0f, 0.0f);

                switch (body.Shape)
                {
                case MmdRigidBody.RigidBodyShape.RigidShapeSphere:
                    btShape = new SphereShape(bodyDimension.x);
                    break;

                case MmdRigidBody.RigidBodyShape.RigidShapeBox:
                    btShape = new BoxShape(new Vector3(bodyDimension.x, bodyDimension.y,
                                                       bodyDimension.z));
                    break;

                case MmdRigidBody.RigidBodyShape.RigidShapeCapsule:
                    btShape = new CapsuleShape(bodyDimension.x, bodyDimension.y);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                if (body.Type != MmdRigidBody.RigidBodyType.RigidTypeKinematic)
                {
                    btMass = body.Mass;
                    btShape.CalculateLocalInertia(btMass, out btLocalInertia);
                }

                var bodyTransform = MathUtil.QuaternionToMatrix4X4(MathUtil.YxzToQuaternion(body.Rotation));
                MathUtil.SetTransToMatrix4X4(body.Position, ref bodyTransform);
                var btBodyTransform = new Matrix();
                MathUtil.UnityMatrixToBulletMatrix(bodyTransform, ref btBodyTransform);

                var btMotionState = new PoserMotionState(poser, body, btBodyTransform);
                var btInfo        =
                    new RigidBodyConstructionInfo(btMass, btMotionState, btShape, btLocalInertia)
                {
                    LinearDamping  = body.TranslateDamp,
                    AngularDamping = body.RotateDamp,
                    Restitution    = body.Restitution,
                    Friction       = body.Friction
                };

                var btRigidBody = new RigidBody(btInfo)
                {
                    ActivationState = ActivationState.DisableDeactivation
                };

                if (body.Type == MmdRigidBody.RigidBodyType.RigidTypeKinematic)
                {
                    btRigidBody.CollisionFlags = btRigidBody.CollisionFlags | CollisionFlags.KinematicObject;
                }
                _world.AddRigidBody(btRigidBody, (short)(1 << body.CollisionGroup), (short)body.CollisionMask);
#if MMD_PHYSICS_DEBUG
                CreateUnityCollisionObjectProxy(btRigidBody, body.Name);
#endif
                motionStates.Add(btMotionState);
                rigidBodies.Add(btRigidBody);
            }

            foreach (var constraint in model.Constraints)
            {
                var btBody1 = rigidBodies[constraint.AssociatedRigidBodyIndex[0]];
                var btBody2 = rigidBodies[constraint.AssociatedRigidBodyIndex[1]];

                var positionLowLimit = constraint.PositionLowLimit;
                var positionHiLimit  = constraint.PositionHiLimit;
                var rotationLoLimit  = constraint.RotationLowLimit;
                var rotationHiLimit  = constraint.RotationHiLimit;

                var constraintTransform = MathUtil.QuaternionToMatrix4X4(MathUtil.YxzToQuaternion(constraint.Rotation));
                MathUtil.SetTransToMatrix4X4(constraint.Position, ref constraintTransform);

                var btConstraintTransform = new Matrix();
                MathUtil.UnityMatrixToBulletMatrix(constraintTransform, ref btConstraintTransform);

                var btLocalizationTransform1 = btConstraintTransform * Matrix.Invert(btBody1.WorldTransform);  //TODO 验证这个和mmdlib里算出来的是否一样
                var btLocalizationTransform2 = btConstraintTransform * Matrix.Invert(btBody2.WorldTransform);

                var btConstraint = new Generic6DofSpringConstraint(btBody1, btBody2, btLocalizationTransform1,
                                                                   btLocalizationTransform2, true)
                {
                    LinearLowerLimit =
                        new Vector3(positionLowLimit.x, positionLowLimit.y, positionLowLimit.z),
                    LinearUpperLimit =
                        new Vector3(positionHiLimit.x, positionHiLimit.y, positionHiLimit.z),
                    AngularLowerLimit =
                        new Vector3(rotationLoLimit.x, rotationLoLimit.y, rotationLoLimit.z),
                    AngularUpperLimit =
                        new Vector3(rotationHiLimit.x, rotationHiLimit.y, rotationHiLimit.z)
                };

                for (var j = 0; j < 3; ++j)
                {
                    btConstraint.SetStiffness(j, constraint.SpringTranslate[j]);
                    btConstraint.EnableSpring(j, true);
                    btConstraint.SetStiffness(j + 3, constraint.SpringRotate[j]);
                    btConstraint.EnableSpring(j + 3, true);
                }

                _world.AddConstraint(btConstraint);
                constraints.Add(btConstraint);
            }
        }
Exemple #27
0
 public static BoneImage GetPoserBoneImage(Poser poser, int index)
 {
     return(index >= poser.BoneImages.Length ? NullBoneImage : poser.BoneImages[index]);
 }