Inheritance: MonoBehaviour
Exemple #1
0
    public Quaternion GetLastRotationForChannel(string channelName)
    {
        Quaternion previousRotation = Quaternion.identity;

        if (this.previousClip != null)
        {
            IAnimationChannel previousChannel = this.previousClip.GetAnimationChannel(channelName);

            if (previousChannel != null && previousChannel is RotationChannel)
            {
                RotationChannel previousRotationChannel = previousChannel as RotationChannel;
                previousRotation = previousRotationChannel.GetPreviousRotation();
            }
        }
        else
        {
            //If we dont have a previous clip to extract a rotation from we use the initial transform for this channel.
            if (this.animationTransforms.ContainsKey(channelName))
            {
                BoneTransform boneTransform = this.animationTransforms[channelName] as BoneTransform;
                previousRotation = boneTransform.GetInitialRotation();
            }
        }

        return(previousRotation);
    }
Exemple #2
0
        void Start()
        {
            var rigged = Node.GetComponent <Animator>();

            if (rigged)
            {
                head = rigged.BoneController.GetBone("頭");
                head.FollowAnimation = false;
            }
            //create head ray collision object
            headBox = new SphereShape(0.35f);
            var rbInfo = new RigidBodyConstructionInfo(0, new DefaultMotionState(Matrix4.Identity.Convert()), headBox, BulletSharp.Math.Vector3.Zero);

            headBody = new RigidBody(rbInfo);
            CoreEngine.pEngine.World.AddRigidBody(headBody, (int)CollisionFilleters.Look, (int)CollisionFilleters.Look);
            //headBody.CollisionFlags |= CollisionFlags.KinematicObject;
            headBody.UserObject = new Action <SceneNode>(triggerSwitch);
            headBody.UserIndex  = 1;
            targetAngle         = new Vector2(thetaDef, phiDef);
            angle    = targetAngle;
            angSpeed = Vector2.Zero;
            audio    = Node.AddComponent <AudioSource>();

            PrepareExpressions(rigged);
            PrepareSpeech();
        }
Exemple #3
0
    void CreateBaseChannels()
    {
        this.baseChannels = new List <IAnimationChannel>();

        for (int i = 0; i < this.transformLookup.Count; i++)
        {
            TransformBase transform = this.transformLookup[i];

            if (transform is MorphTransform)
            {
                //A small list of keyframes, used to sample values.
                List <float> keys = new List <float>(5)
                {
                    0.0f, 0.0f, 0.0f, 0.0f, 0.0f
                };
                MorphChannel morphChannel = new MorphChannel(transform.GetName(), keys, false, false, false, false, FRAMERATE);

                this.baseChannels.Add(morphChannel);
            }
            else if (transform is BoneTransform)
            {
                BoneTransform boneTransform = transform as BoneTransform;

                //Sample initial rotation value.
                Vector3        angle = boneTransform.GetInitialRotation().eulerAngles;
                List <Vector3> keys  = new List <Vector3>(5)
                {
                    angle, angle, angle, angle, angle
                };
                RotationChannel rotationChannel = new RotationChannel(boneTransform.GetName(), keys, false, false, false, false, FRAMERATE);

                this.baseChannels.Add(rotationChannel);
            }
        }
    }
Exemple #4
0
        private void LoadPoseOld(List <string> lines)
        {
            Armature armature = selectedItem.Model.Armature;
            DataSet  dataSet  = dataSetDict[selectedItem];

            if (lines.Count != armature.Bones.Length)
            {
                MessageBox.Show(this, "Incompatible armatures (bones do not match).", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            int boneID = 0;

            foreach (string line in lines)
            {
                string[] tokens = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                if (tokens.Length == 3)
                {
                    BoneTransform boneTransform = dataSet.boneTransforms[boneID];
                    boneTransform.rotX  = int.Parse(tokens[0]);
                    boneTransform.rotY  = int.Parse(tokens[1]);
                    boneTransform.rotZ  = int.Parse(tokens[2]);
                    boneTransform.moveX = 0;
                    boneTransform.moveY = 0;
                    boneTransform.moveZ = 0;
                }
                boneID++;
            }
            foreach (Armature.Bone bone in armature.Bones)
            {
                BoneTransform boneRotation = dataSet.boneTransforms[bone.id];
                ApplyTransformToBone(bone, boneRotation);
            }
        }
Exemple #5
0
    void FindBoneTransforms()
    {
        string[] optionalBones =
        {
            "Mid_Head_Jnt_03",
            "L_LowEyelid_Jnt_00",
            "R_LowEyelid_Jnt_00",
            "L_UpEyelid_Jnt_00",
            "R_UpEyelid_Jnt_00",
            "L_Eyeball_Jnt_00",
            "R_Eyeball_Jnt_00"
        };

        Dictionary <string, Transform> mappedTransforms = new Dictionary <string, Transform>();

        TransformHelp.FindChildrenRecursive(this.transform, optionalBones, mappedTransforms);

        //Avoid using enumerators when iterating
        foreach (KeyValuePair <string, Transform> pair in mappedTransforms)
        {
            BoneTransform boneTransform = new BoneTransform(pair.Key, pair.Value, pair.Value.localRotation);

            if (!this.animationTransforms.ContainsKey(pair.Key))
            {
                this.animationTransforms.Add(pair.Key, boneTransform);
            }
        }
    }
Exemple #6
0
        private void LoadPoseNew(List <string> lines)
        {
            Armature armature = selectedItem.Model.Armature;
            Dictionary <string, BoneTransform> boneTransforms = new Dictionary <string, BoneTransform>();

            foreach (string line in lines)
            {
                string[] tokens1 = line.Split(':');
                if (tokens1.Length == 2)
                {
                    string        boneName = tokens1[0].Trim();
                    Armature.Bone bone     = armature.GetBone(boneName);
                    if (bone != null)
                    {
                        string[] tokens2 = tokens1[1].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        if (tokens2.Length == 3 || tokens2.Length == 6)
                        {
                            BoneTransform boneTransform = new BoneTransform();
                            boneTransform.rotX = float.Parse(tokens2[0]);
                            boneTransform.rotY = float.Parse(tokens2[1]);
                            boneTransform.rotZ = float.Parse(tokens2[2]);
                            if (tokens2.Length == 6)
                            {
                                boneTransform.moveX = float.Parse(tokens2[3]);
                                boneTransform.moveY = float.Parse(tokens2[4]);
                                boneTransform.moveZ = float.Parse(tokens2[5]);
                            }
                            else
                            {
                                boneTransform.moveX = 0;
                                boneTransform.moveY = 0;
                                boneTransform.moveZ = 0;
                            }
                            boneTransforms[boneName] = boneTransform;
                        }
                    }
                }
            }

            ICollection <string> boneNames = boneTransforms.Keys;
            PoseFilterDialog     dialog    = new PoseFilterDialog(game, "Load pose", "Select bones to load:", boneNames, true);

            if (dialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }
            DataSet dataSet = dataSetDict[selectedItem];

            foreach (string boneName in boneNames)
            {
                if (dialog.IsBoneSelected(boneName))
                {
                    Armature.Bone bone          = armature.GetBone(boneName);
                    BoneTransform boneTransform = boneTransforms[boneName];
                    dataSet.boneTransforms[bone.id] = boneTransform;
                    ApplyTransformToBone(bone, boneTransform);
                }
            }
        }
 /// <summary>
 /// Prepare  references
 /// </summary>
 void InitialSetup()
 {
     eyesBone = anim.BoneController.GetBone("両目");
     eyesBone.FollowAnimation = false;
     morphes           = mesh.Morphes;
     EyeLocationX      = 0;
     EyeLocationY      = 0;
     DefaultExpression = new NPCExpression("Def");
 }
Exemple #8
0
        public static void DrawAvatarBone(BoneTransform bone, Vector3 direction)
        {
            if (bone.transform == null)
            {
                return;
            }

            Debug.DrawRay(bone.transform.position, bone.targetRotation * direction * bone.length, Color.cyan);
        }
    public static void Main()
    {
        const int  N             = 10000;
        const long SecondInTicks = 10000000;

        var vertices   = new Vertex[N];
        var influences = new Influence[N];

        for (int i = 0; i < N; i++)
        {
            vertices[i] = new Vertex {
                Position = new CalVector4(1, 2, 3),
                Normal   = new CalVector4(0, 0, 1)
            };

            influences[i] = new Influence {
                BoneId = 0,
                Weight = 1.0f,
                LastInfluenceForThisVertex = true
            };
        }

        var boneTransforms = new BoneTransform[] {
            new BoneTransform()
        };

        var output = new CalVector4[N * 2];

        for (int i = 0; i < 100; i++)
        {
            long verticesSkinned = 0;
            long started         = DateTime.UtcNow.Ticks;

            while (DateTime.UtcNow.Ticks < (started + SecondInTicks))
            {
                CalculateVerticesAndNormals(
                    boneTransforms, N, vertices, influences, output
                    );

                verticesSkinned += N;
            }

            long elapsed = DateTime.UtcNow.Ticks - started;

            Console.WriteLine(
                "Skinned vertices per second: {0}",
                (verticesSkinned * SecondInTicks) / elapsed
                );
        }
    }
 public void PopulateChildren()
 {
     if (!RootNode)
     {
         return;
     }
     _preRootNode        = RootNode;
     _childNodes         = RootNode.GetComponentsInChildren <Transform>();
     _previousTransforms = new BoneTransform[_childNodes.Length];
     for (var i = 0; i < _childNodes.Length; i++)
     {
         var childNode = _childNodes[i];
         _previousTransforms[i] = new BoneTransform(childNode, childNode.localPosition);
     }
 }
    public void AddScaled(ref BoneTransform mutate, float s)
    {
        mutate.RowX.X += RowX.X * s;
        mutate.RowX.Y += RowX.Y * s;
        mutate.RowX.Z += RowX.Z * s;
        mutate.RowX.W += RowX.W * s;

        mutate.RowY.X += RowY.X * s;
        mutate.RowY.Y += RowY.Y * s;
        mutate.RowY.Z += RowY.Z * s;
        mutate.RowY.W += RowY.W * s;

        mutate.RowZ.X += RowZ.X * s;
        mutate.RowZ.Y += RowZ.Y * s;
        mutate.RowZ.Z += RowZ.Z * s;
        mutate.RowZ.W += RowZ.W * s;
    }
    public void Scale(out BoneTransform result, float s)
    {
        result.RowX.X = RowX.X * s;
        result.RowX.Y = RowX.Y * s;
        result.RowX.Z = RowX.Z * s;
        result.RowX.W = RowX.W * s;

        result.RowY.X = RowY.X * s;
        result.RowY.Y = RowY.Y * s;
        result.RowY.Z = RowY.Z * s;
        result.RowY.W = RowY.W * s;

        result.RowZ.X = RowZ.X * s;
        result.RowZ.Y = RowZ.Y * s;
        result.RowZ.Z = RowZ.Z * s;
        result.RowZ.W = RowZ.W * s;
    }
    public void Scale(out BoneTransform result, float s)
    {
        result.RowX.X = RowX.X * s;
        result.RowX.Y = RowX.Y * s;
        result.RowX.Z = RowX.Z * s;
        result.RowX.W = RowX.W * s;

        result.RowY.X = RowY.X * s;
        result.RowY.Y = RowY.Y * s;
        result.RowY.Z = RowY.Z * s;
        result.RowY.W = RowY.W * s;

        result.RowZ.X = RowZ.X * s;
        result.RowZ.Y = RowZ.Y * s;
        result.RowZ.Z = RowZ.Z * s;
        result.RowZ.W = RowZ.W * s;
    }
    public void AddScaled(ref BoneTransform mutate, float s)
    {
        mutate.RowX.X += RowX.X * s;
        mutate.RowX.Y += RowX.Y * s;
        mutate.RowX.Z += RowX.Z * s;
        mutate.RowX.W += RowX.W * s;

        mutate.RowY.X += RowY.X * s;
        mutate.RowY.Y += RowY.Y * s;
        mutate.RowY.Z += RowY.Z * s;
        mutate.RowY.W += RowY.W * s;

        mutate.RowZ.X += RowZ.X * s;
        mutate.RowZ.Y += RowZ.Y * s;
        mutate.RowZ.Z += RowZ.Z * s;
        mutate.RowZ.W += RowZ.W * s;
    }
        public void ReadFromFile(MemoryStream reader, bool isBigEndian)
        {
            int  numBones = reader.ReadInt32(isBigEndian);
            byte numLods  = reader.ReadByte8();

            //index infos
            boneIndexInfos = new BoneIndexInfo[numLods];
            for (int i = 0; i != boneIndexInfos.Length; i++)
            {
                boneIndexInfos[i].NumIDs       = reader.ReadInt32(isBigEndian);
                boneIndexInfos[i].NumMaterials = reader.ReadInt32(isBigEndian);
            }

            //bounds for all bones together?
            bounds = BoundingBoxExtenders.ReadFromFile(reader, isBigEndian);

            //Bone Transforms
            boneTransforms = new BoneTransform[numBones];
            for (int i = 0; i != boneTransforms.Length; i++)
            {
                boneTransforms[i] = new BoneTransform();
                boneTransforms[i].ReadFromFile(reader, isBigEndian);
            }

            for (int i = 0; i != boneIndexInfos.Length; i++)
            {
                boneIndexInfos[i].BonesPerPool = reader.ReadBytes(8);

                //IDs..
                boneIndexInfos[i].IDs = reader.ReadBytes(boneIndexInfos[i].NumIDs);

                //Material blendings..
                boneIndexInfos[i].MatBlends           = new ushort[boneIndexInfos[i].NumMaterials];
                boneIndexInfos[i].BonesSlot           = new byte[boneIndexInfos[i].NumMaterials];
                boneIndexInfos[i].NumWeightsPerVertex = new int[boneIndexInfos[i].NumMaterials];
                for (int x = 0; x != boneIndexInfos[i].NumMaterials; x++)
                {
                    boneIndexInfos[i].MatBlends[x] = reader.ReadUInt16(isBigEndian);
                    ushort value = boneIndexInfos[i].MatBlends[x];
                    boneIndexInfos[i].BonesSlot[x]           = (byte)(value & 0xFF);
                    boneIndexInfos[i].NumWeightsPerVertex[x] = (value >> 8);
                }
            }
        }
Exemple #16
0
        private void SavePose(string filename)
        {
            Armature      armature  = selectedItem.Model.Armature;
            List <string> boneNames = new List <string>();

            foreach (Armature.Bone bone in armature.Bones)
            {
                if (!bone.name.StartsWith("unused"))
                {
                    boneNames.Add(bone.name);
                }
            }

            PoseFilterDialog dialog = new PoseFilterDialog(game, "Save pose", "Select bones to save:", boneNames, true);

            if (dialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }

            try {
                DataSet      dataSet = dataSetDict[selectedItem];
                StreamWriter file    = new StreamWriter(filename);
                foreach (Armature.Bone bone in armature.Bones)
                {
                    if (!dialog.IsBoneSelected(bone.name))
                    {
                        continue;
                    }
                    BoneTransform boneTransform = dataSet.boneTransforms[bone.id];
                    file.WriteLine("{0}: {1} {2} {3} {4} {5} {6}", bone.name,
                                   boneTransform.rotX, boneTransform.rotY, boneTransform.rotZ,
                                   boneTransform.moveX, boneTransform.moveY, boneTransform.moveZ);
                }
                file.Close();
            }
            catch (Exception ex) {
                MessageBox.Show(this, "Could not save the pose file.\n" + ex.Message,
                                "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }
Exemple #17
0
        private void MirrorPose()
        {
            if (selectedItem == null)
            {
                return;
            }

            Armature armature = selectedItem.Model.Armature;

            List <string> labels = new List <string>();

            foreach (Armature.Bone bone in armature.Bones)
            {
                int    origSide;
                string mirroredName = GetMirroredBoneName(bone.name, out origSide);
                if (mirroredName != null && origSide < 0 && armature.GetBone(mirroredName) != null)
                {
                    labels.Add("L: " + bone.name);
                }
            }
            foreach (Armature.Bone bone in armature.Bones)
            {
                int    origSide;
                string mirroredName = GetMirroredBoneName(bone.name, out origSide);
                if (mirroredName != null && origSide > 0 && armature.GetBone(mirroredName) != null)
                {
                    labels.Add("R: " + bone.name);
                }
            }

            PoseFilterDialog dialog = new PoseFilterDialog(game, "Mirror (copy) pose left/right", "Select bones to mirror pose from:", labels, false);

            if (dialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }

            DataSet dataSet = dataSetDict[selectedItem];

            foreach (string label in labels)
            {
                if (!dialog.IsBoneSelected(label))
                {
                    continue;
                }

                string        boneNameFrom      = label.Substring(3);
                Armature.Bone boneFrom          = armature.GetBone(boneNameFrom);
                BoneTransform boneTransformFrom = dataSet.boneTransforms[boneFrom.id];

                string        boneNameTo      = GetMirroredBoneName(boneNameFrom);
                Armature.Bone boneTo          = armature.GetBone(boneNameTo);
                BoneTransform boneTransformTo = dataSet.boneTransforms[boneTo.id];

                boneTransformTo.moveX = -boneTransformFrom.moveX;
                boneTransformTo.moveY = +boneTransformFrom.moveY;
                boneTransformTo.moveZ = +boneTransformFrom.moveZ;

                boneTransformTo.rotX = +boneTransformFrom.rotX;
                boneTransformTo.rotY = -boneTransformFrom.rotY;
                boneTransformTo.rotZ = -boneTransformFrom.rotZ;

                ApplyTransformToBone(boneTo, boneTransformTo);
            }
        }
Exemple #18
0
        private void FlipPose()
        {
            if (selectedItem == null)
            {
                return;
            }

            Armature armature = selectedItem.Model.Armature;

            List <string> labels = new List <string>();
            Dictionary <string, string> labelsToBoneNames = new Dictionary <string, string>();

            foreach (Armature.Bone bone in armature.Bones)
            {
                int    origSide;
                string flippedName = GetFlippedBoneName(bone.name, out origSide);
                if (flippedName != null && origSide < 0 && armature.GetBone(flippedName) != null)
                {
                    string combinedName = GetCombinedBoneName(bone.name);
                    labels.Add(combinedName);
                    labelsToBoneNames[combinedName] = bone.name;
                }
            }

            PoseFilterDialog dialog = new PoseFilterDialog(game, "Flip (swap) pose left/right", "Select bone pairs whose pose to flip:", labels, false);

            if (dialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }

            DataSet dataSet = dataSetDict[selectedItem];

            foreach (string label in labels)
            {
                if (!dialog.IsBoneSelected(label))
                {
                    continue;
                }

                string        boneName1      = labelsToBoneNames[label];
                Armature.Bone bone1          = armature.GetBone(boneName1);
                BoneTransform boneTransform1 = dataSet.boneTransforms[bone1.id];

                string        boneName2      = GetFlippedBoneName(boneName1);
                Armature.Bone bone2          = armature.GetBone(boneName2);
                BoneTransform boneTransform2 = dataSet.boneTransforms[bone2.id];

                float moveX1 = boneTransform1.moveX;
                float moveY1 = boneTransform1.moveY;
                float moveZ1 = boneTransform1.moveZ;

                float rotX1 = boneTransform1.rotX;
                float rotY1 = boneTransform1.rotY;
                float rotZ1 = boneTransform1.rotZ;

                float moveX2 = boneTransform2.moveX;
                float moveY2 = boneTransform2.moveY;
                float moveZ2 = boneTransform2.moveZ;

                float rotX2 = boneTransform2.rotX;
                float rotY2 = boneTransform2.rotY;
                float rotZ2 = boneTransform2.rotZ;

                boneTransform2.moveX = -moveX1;
                boneTransform2.moveY = +moveY1;
                boneTransform2.moveZ = +moveZ1;

                boneTransform2.rotX = +rotX1;
                boneTransform2.rotY = -rotY1;
                boneTransform2.rotZ = -rotZ1;

                boneTransform1.moveX = -moveX2;
                boneTransform1.moveY = +moveY2;
                boneTransform1.moveZ = +moveZ2;

                boneTransform1.rotX = +rotX2;
                boneTransform1.rotY = -rotY2;
                boneTransform1.rotZ = -rotZ2;

                ApplyTransformToBone(bone1, boneTransform1);
                ApplyTransformToBone(bone2, boneTransform2);
            }
        }
    public static void Main()
    {
        const int N = 10000;
        const long SecondInTicks = 10000000;

        var vertices = new Vertex[N];
        var influences = new Influence[N];

        for (int i = 0; i < N; i++) {
            vertices[i] = new Vertex {
                Position = new CalVector4(1, 2, 3),
                Normal = new CalVector4(0, 0, 1)
            };

            influences[i] = new Influence {
                BoneId = 0,
                Weight = 1.0f,
                LastInfluenceForThisVertex = true
            };
        }

        var boneTransforms = new BoneTransform[] {
            new BoneTransform()
        };

        var output = new CalVector4[N * 2];

        for (int i = 0; i < 100; i++) {
            long verticesSkinned = 0;
            long started = DateTime.UtcNow.Ticks;

            while (DateTime.UtcNow.Ticks < (started + SecondInTicks)) {
                CalculateVerticesAndNormals(
                    boneTransforms, N, vertices, influences, output
                );

                verticesSkinned += N;
            }

            long elapsed = DateTime.UtcNow.Ticks - started;

            Console.WriteLine(
                "Skinned vertices per second: {0}",
                (verticesSkinned * SecondInTicks) / elapsed
            );
        }
    }
Exemple #20
0
        private void SaveScene(string filename)
        {
            BinaryWriter file;

            try {
                file = new BinaryWriter(new FileStream(filename, FileMode.Create));
            }
            catch (Exception) {
                MessageBox.Show(this, "Could not save scene.",
                                "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // file format version
            file.Write((ushort)1);  // major
            file.Write((ushort)11); // minor

            // items
            file.Write(items.Count);
            foreach (Item item in items)
            {
                // type
                file.Write(item.Type.ToString());
                // directory name
                file.Write(item.DirName);
                // visibility
                file.Write(item.Model.IsVisible);
                // scale
                file.Write(item.Model.Armature.WorldScale.X);
                file.Write(item.Model.Armature.WorldScale.Y);
                file.Write(item.Model.Armature.WorldScale.Z);

                // pose
                Armature armature = item.Model.Armature;
                DataSet  dataSet  = dataSetDict[item];
                foreach (Armature.Bone bone in armature.Bones)
                {
                    BoneTransform boneTransform = dataSet.boneTransforms[bone.id];
                    file.Write(boneTransform.rotX);
                    file.Write(boneTransform.rotY);
                    file.Write(boneTransform.rotZ);
                    file.Write(boneTransform.moveX);
                    file.Write(boneTransform.moveY);
                    file.Write(boneTransform.moveZ);
                }

                // position
                Vector3 position = armature.WorldTranslation;
                file.Write(position.X);
                file.Write(position.Y);
                file.Write(position.Z);

                // accessories
                ExportModelParams(file, item.Model);

                // glow colors
                file.Write(item.ColorGlowLeft.X);
                file.Write(item.ColorGlowLeft.Y);
                file.Write(item.ColorGlowLeft.Z);
                file.Write(item.ColorGlowRight.X);
                file.Write(item.ColorGlowRight.Y);
                file.Write(item.ColorGlowRight.Z);
            }

            // camera
            CameraTurnTable camera = game.Camera;

            file.Write(camera.FieldOfViewHorizontal);
            file.Write(camera.Target.X);
            file.Write(camera.Target.Y);
            file.Write(camera.Target.Z);
            file.Write(camera.Distance);
            file.Write(camera.RotationHorizontal);
            file.Write(camera.RotationVertical);

            // light 1
            Vector3 light1Dir = game.Light1Direction;

            file.Write(light1Dir.X);
            file.Write(light1Dir.Y);
            file.Write(light1Dir.Z);
            file.Write(game.Light1Intensity);
            Color light1Color = game.Light1Color;

            file.Write(light1Color.R);
            file.Write(light1Color.G);
            file.Write(light1Color.B);
            file.Write(game.Light1ShadowDepth);

            // light 2
            Vector3 light2Dir = game.Light2Direction;

            file.Write(light2Dir.X);
            file.Write(light2Dir.Y);
            file.Write(light2Dir.Z);
            file.Write(game.Light2Intensity);
            Color light2Color = game.Light2Color;

            file.Write(light2Color.R);
            file.Write(light2Color.G);
            file.Write(light2Color.B);
            file.Write(game.Light2ShadowDepth);

            // light 3
            Vector3 light3Dir = game.Light3Direction;

            file.Write(light3Dir.X);
            file.Write(light3Dir.Y);
            file.Write(light3Dir.Z);
            file.Write(game.Light3Intensity);
            Color light3Color = game.Light3Color;

            file.Write(light3Color.R);
            file.Write(light3Color.G);
            file.Write(light3Color.B);
            file.Write(game.Light3ShadowDepth);

            // post-processing params
            file.Write(game.PostProcessBrightness);
            file.Write(game.PostProcessGamma);
            file.Write(game.PostProcessContrast);
            file.Write(game.PostProcessSaturation);

            // ground texture
            file.Write(game.DisplayGround);
            file.Write("data\\ground.png");

            // background color
            file.Write(game.BackgroundColor.R);
            file.Write(game.BackgroundColor.G);
            file.Write(game.BackgroundColor.B);

            // background image
            file.Write("");

            // skydome
            file.Write(game.DisplaySkyDome);
            file.Write(ItemType.SkyDome_Thailand_Sea.ToString());
            file.Write(game.SkyDomeRotation);
            file.Write(game.SkyDomeElevation);

            // canvas size
            file.Write(game.GameForm.WindowState == FormWindowState.Maximized);
            file.Write(game.GameForm.ClientSize.Width);
            file.Write(game.GameForm.ClientSize.Height);

            file.Close();
        }
Exemple #21
0
        /// <summary>
        /// Формирует измененные позиции вершин (ключ словаря - индекс  в переданном массиве vertices, значение - новая позиция и нормаль этой вершины) на основании переданного массива вершин,
        /// скелета (список костей) к которому эти вершины привязаны а также набора трансформаций с этими костями.
        /// То есть по сути формирует состояние вершин модели при изменении костей (как при скелетной анимации)
        /// </summary>
        public static Dictionary <int, Vertex> BakeBlendShape(Vec3 objectPosition, WowVertex[] vertices, WowBone[] bones, WowVrcFileData.BlendshapeData.BoneData[] blendShapeBoneChanges, float scale)
        {
            var vertexPositions = vertices
                                  .Select(x => new Vec3(x.Position.X + objectPosition.X, x.Position.Y + objectPosition.Y, x.Position.Z + objectPosition.Z))
                                  .ToArray();

            // Создаем оригинальные/трансформированные кости и просчитываем локальные матрицы для них

            var originalBones  = new BoneTransform[bones.Length];
            var blenshapeBones = new BoneTransform[bones.Length];

            for (int boneIdx = 0; boneIdx < bones.Length; boneIdx++)
            {
                if (bones[boneIdx] == null)
                {
                    continue;
                }

                originalBones[boneIdx]  = new BoneTransform();
                blenshapeBones[boneIdx] = new BoneTransform();

                originalBones[boneIdx].SetLocalDataFromWowBone(bones[boneIdx]);

                var blendshapeChange = blendShapeBoneChanges.FirstOrDefault(x => x.Name == bones[boneIdx].GetName());
                if (blendshapeChange != null)
                {
                    blenshapeBones[boneIdx].SetLocalDataFromBlendshapeBone(bones[boneIdx], blendshapeChange, scale);
                }
                else
                {
                    blenshapeBones[boneIdx].SetLocalDataFromWowBone(bones[boneIdx]);
                }
            }

            // Прописываем иерархию для оригинальных/трансформированных костей

            for (int boneIdx = 0; boneIdx < bones.Length; boneIdx++)
            {
                if (bones[boneIdx] == null)
                {
                    continue;
                }

                if (bones[boneIdx].ParentBone != null)
                {
                    originalBones[boneIdx].Parent  = originalBones[bones[boneIdx].ParentBone.Index];
                    blenshapeBones[boneIdx].Parent = blenshapeBones[bones[boneIdx].ParentBone.Index];
                }
            }

            // Считаем глобальные матрицы разницы между оригинальной и blendshape костью для каждой из костей в исходном массиве костей
            // В случае если изменений в кости (с учетом родительской иерархии) не было, матрица изменений кости будет равна (или приблизительно равна) identity

            var blendshapeDifferenceMatricesPerBone = new Mat4[bones.Length];

            for (int boneIdx = 0; boneIdx < bones.Length; boneIdx++)
            {
                if (originalBones[boneIdx] == null)
                {
                    continue;
                }

                blendshapeDifferenceMatricesPerBone[boneIdx] = Mat4.Multiply(blenshapeBones[boneIdx].GetGlobalMatrix(), Mat4.Invert(originalBones[boneIdx].GetGlobalMatrix()));
            }

            // Меняем заданные вершины в соответствии с просчитанными матрицами изменений.
            // Если значение вершины изменилось в результате примененных трансформаций (то есть если на вершину влияла хотя бы одна кость, матрица изменений которой не identity)
            // то добавляем эту вершину в словарь измененных вершин, который далее возвращаем

            var changedVertices = new Dictionary <int, Vertex>();

            for (int vertexIdx = 0; vertexIdx < vertices.Length; vertexIdx++)
            {
                var vertex         = vertices[vertexIdx];
                var vertexPosition = vertexPositions[vertexIdx];

                var changedVertexPos    = new Vec3();
                var changedVertexNormal = new Vec3();

                for (int boneInVertexIdx = 0; boneInVertexIdx < 4; boneInVertexIdx++)
                {
                    var boneIdx = vertex.BoneIndexes[boneInVertexIdx];
                    if (boneIdx < 0 || bones[boneIdx] == null)
                    {
                        continue;
                    }

                    var boneWeight = vertex.BoneWeights[boneInVertexIdx];

                    var positionFromBone = Vec3.TransformMat4(vertexPosition, blendshapeDifferenceMatricesPerBone[boneIdx]);
                    changedVertexPos.X += positionFromBone.X * boneWeight;
                    changedVertexPos.Y += positionFromBone.Y * boneWeight;
                    changedVertexPos.Z += positionFromBone.Z * boneWeight;

                    // Незнаю в чем дело, но если используется scale в нормалях то результат не соответствует скинингу из юнити. При чем непонятно где правильно сделано, как тут или как там
                    var normalFromBone = Vec3.TransformMat4(vertex.Normal, Mat4.Transpose(Mat4.Invert(blendshapeDifferenceMatricesPerBone[boneIdx])));
                    changedVertexNormal.X += normalFromBone.X * boneWeight;
                    changedVertexNormal.Y += normalFromBone.Y * boneWeight;
                    changedVertexNormal.Z += normalFromBone.Z * boneWeight;
                }

                changedVertexNormal = Vec3.Normalize(changedVertexNormal);

                if (!Vec3.AreNearlyEqual(changedVertexPos, vertexPosition))
                {
                    changedVertices.Add(vertexIdx, new Vertex()
                    {
                        Position = new Vec3(changedVertexPos.X - objectPosition.X, changedVertexPos.Y - objectPosition.Y, changedVertexPos.Z - objectPosition.Z), Normal = changedVertexNormal
                    });
                }
            }

            return(changedVertices);
        }
        public static SkeletonFormat Read(List <ChunkTable.ChunkDataEntry> chunkList)
        {
            var genericSkeleton = new SkeletonFormat();

            Header               header         = null;
            List <BoneInfo>      boneInfos      = new List <BoneInfo>();
            List <BoneTransform> boneTransforms = new List <BoneTransform>();
            List <uint>          boneIndices    = new List <uint>();
            List <BoneHash>      boneHashes     = new List <BoneHash>();

            for (int i = 0; i < chunkList.Count; i++)
            {
                if (chunkList[i].ChunkType == ChunkDataType.SkeletonHeader)
                {
                    header = chunkList[i].ReadStruct <Header>();
                }
            }

            for (int i = 0; i < chunkList.Count; i++)
            {
                var chunk = chunkList[i];
                Console.WriteLine($"SKELETON {chunk.ChunkType}");
                switch (chunk.ChunkType)
                {
                case ChunkDataType.SkeletonBoneInfo:
                    boneInfos = chunk.ReadStructs <BoneInfo>(header.BoneCount);
                    break;

                case ChunkDataType.SkeletonBoneTransform:
                    boneTransforms = chunk.ReadStructs <BoneTransform>(header.BoneCount);
                    break;

                case ChunkDataType.SkeletonBoneIndexList:
                    //  boneIndices = chunk.ReadPrimitive<uint>(header.BoneIndexListCount);
                    break;

                case ChunkDataType.SkeletonBoneHashList:
                    boneHashes = chunk.ReadStructs <BoneHash>(header.BoneCount);
                    break;
                }
            }

            for (int i = 0; i < boneInfos.Count; i++)
            {
                var    info      = boneInfos[i];
                var    transform = boneTransforms[i];
                string name      = Hashing.HashNames.ContainsKey(info.Hash) ?
                                   Hashing.HashNames[info.Hash] : info.Hash.ToString();

                if (transform == null)
                {
                    transform = new BoneTransform();
                }

                genericSkeleton.Bones.Add(new STBone(genericSkeleton)
                {
                    Name        = name,
                    ParentIndex = info.ParentIndex,
                    Position    = (new OpenTK.Vector3(
                                       transform.TranslationX,
                                       transform.TranslationY,
                                       transform.TranslationZ) * (info.ParentIndex != -1 ? (32 * ModelWrapper.PreviewScale) : 1)),
                    Rotation = new OpenTK.Quaternion(
                        transform.QuaternionX,
                        transform.QuaternionY,
                        transform.QuaternionZ,
                        transform.QuaternionW) *
                               (info.ParentIndex == -1 ?
                                Quaternion.FromEulerAngles(-1.5708F, 0, 0) :
                                Quaternion.Identity),
                });

                Console.WriteLine($"BONE {transform.ScaleX} {transform.ScaleY} {transform.ScaleZ}");
            }

            for (int i = 0; i < boneHashes.Count; i++)
            {
                genericSkeleton.BoneHashToID.Add(boneHashes[i].Hash, (int)boneHashes[i].Index);
                Console.WriteLine($"BONEINDEXLIST {boneHashes[i].Hash} {boneHashes[i].Index}");
            }

            genericSkeleton.Reset();

            return(genericSkeleton);
        }
Exemple #23
0
        private bool LoadItems(BinaryReader file, ushort versionMajor, ushort versionMinor, bool loadScene)
        {
            // items
            int itemCount = file.ReadInt32();

            for (int itemID = 0; itemID < itemCount; itemID++)
            {
                // create item
                string itemTypeName = file.ReadString();
                string dirName;
                if (versionMajor >= 1 && versionMinor >= 5)
                {
                    dirName = file.ReadString();
                }
                else
                {
                    dirName = itemTypeName.ToLower();
                }
                bool    isVisible = file.ReadBoolean();
                Vector3 itemScale;
                if (versionMajor >= 1 && versionMinor >= 8)
                {
                    float itemScaleX = file.ReadSingle();
                    float itemScaleY = file.ReadSingle();
                    float itemScaleZ = file.ReadSingle();
                    itemScale = new Vector3(itemScaleX, itemScaleY, itemScaleZ);
                }
                else
                {
                    float itemScaleXYZ = file.ReadSingle();
                    itemScale = new Vector3(itemScaleXYZ, itemScaleXYZ, itemScaleXYZ);
                }

                ItemType itemType = ParseItemType(itemTypeName);
                Item     item     = ItemFactory.GetItem(game, itemType);
                if (!dirName.ToLower().StartsWith("data\\"))
                {
                    dirName = "data\\" + dirName;
                }
                if (!item.LoadAndInitModel(itemType, dirName))
                {
                    return(false);
                }
                item.Model.IsVisible = isVisible;

                if (loadScene)
                {
                    AddItem(item);
                }

                // pose
                Armature armature = item.Model.Armature;
                foreach (Armature.Bone bone in armature.Bones)
                {
                    float rotX  = file.ReadSingle();
                    float rotY  = file.ReadSingle();
                    float rotZ  = file.ReadSingle();
                    float moveX = 0;
                    float moveY = 0;
                    float moveZ = 0;
                    if (versionMajor >= 1 && versionMinor >= 3)
                    {
                        moveX = file.ReadSingle();
                        moveY = file.ReadSingle();
                        moveZ = file.ReadSingle();
                    }

                    if (loadScene)
                    {
                        DataSet       dataSet       = dataSetDict[item];
                        BoneTransform boneTransform = dataSet.boneTransforms[bone.id];
                        boneTransform.rotX  = rotX;
                        boneTransform.rotY  = rotY;
                        boneTransform.rotZ  = rotZ;
                        boneTransform.moveX = moveX;
                        boneTransform.moveY = moveY;
                        boneTransform.moveZ = moveZ;
                        ApplyTransformToBone(bone, boneTransform);
                    }
                }

                // position
                Vector3 position = new Vector3();
                position.X = file.ReadSingle();
                position.Y = file.ReadSingle();
                position.Z = file.ReadSingle();

                if (loadScene)
                {
                    armature.WorldScale = itemScale;
                    HandleScaleChangedInGUI(itemScale);
                    armature.WorldTranslation = position;
                    HandleHeightChanged(position.Y);
                }

                // accessories
                ImportModelParams(file, loadScene ? item.Model : null);
                if (loadScene)
                {
                    UpdateAccessoriesCheckboxes(item.Model);
                }

                // glow colors
                if (versionMajor >= 1 && versionMinor >= 11)
                {
                    float r, g, b;
                    r = file.ReadSingle();
                    g = file.ReadSingle();
                    b = file.ReadSingle();
                    item.ColorGlowLeft = new Vector4(r, g, b, 1);
                    r = file.ReadSingle();
                    g = file.ReadSingle();
                    b = file.ReadSingle();
                    item.ColorGlowRight = new Vector4(r, g, b, 1);
                }
            }

            return(true);
        }
    public static void CalculateVerticesAndNormals(
        BoneTransform[] boneTransforms,
        int vertexCount,
        Vertex[] vertices,
        Influence[] influences,
        CalVector4[] output
    )
    {
        Debug.Assert(output.Length == vertices.Length * 2);

        BoneTransform totalTransform;

        for (
            int sourceVertex = 0, sourceInfluence = 0, outputVertex = 0;
            sourceVertex < vertices.Length;
            sourceVertex++, sourceInfluence++, outputVertex += 2
        ) {
            var influence = influences[sourceInfluence];

            boneTransforms[influence.BoneId].Scale(
                out totalTransform, influence.Weight
            );

            while (!influence.LastInfluenceForThisVertex) {
                sourceInfluence += 1;
                influence = influences[sourceInfluence];

                boneTransforms[influence.BoneId].AddScaled(
                    ref totalTransform, influence.Weight
                );
            }

            totalTransform.TransformPoint(
                out output[outputVertex], ref vertices[sourceVertex].Position
            );
            totalTransform.TransformVector(
                out output[outputVertex + 1], ref vertices[sourceVertex].Normal
            );
        }
    }
 public override void Bind(TransformBase animationTransform)
 {
     this.boneTransform = animationTransform as BoneTransform;
 }