コード例 #1
0
ファイル: GhostObject.cs プロジェクト: lanyizi/OpenSAGE
        public void Persist(StatePersister reader)
        {
            reader.PersistVersion(1);

            reader.BeginObject("Base");
            reader.PersistVersion(1);
            reader.EndObject();

            var objectId = _gameObject?.ID ?? 0u;

            reader.PersistObjectID(ref objectId);
            if (reader.Mode == StatePersistMode.Read)
            {
                _gameObject = reader.Game.GameLogic.GetObjectById(objectId);
            }

            reader.PersistEnum(ref _geometryType);

            // Sometimes there's a 0xC, which is probably uninitialized data.
            byte geometryIsSmall = _geometryIsSmall ? (byte)1 : (byte)0;

            reader.PersistByte(ref geometryIsSmall);
            _geometryIsSmall = geometryIsSmall == 1;

            reader.PersistSingle(ref _geometryMajorRadius);
            reader.PersistSingle(ref _geometryMinorRadius);
            reader.PersistSingle(ref _angle);
            reader.PersistVector3(ref _position);

            reader.SkipUnknownBytes(12);

            reader.BeginArray("ModelsPerPlayer");
            for (var i = 0; i < Player.MaxPlayers; i++)
            {
                reader.BeginObject();

                byte numModels = (byte)_modelsPerPlayer[i].Count;
                reader.PersistByte(ref numModels);

                reader.BeginArray("Models");
                for (var j = 0; j < numModels; j++)
                {
                    reader.BeginObject();

                    var modelName = reader.Mode == StatePersistMode.Write
                        ? _modelsPerPlayer[i][j].Model.Name
                        : "";
                    reader.PersistAsciiString(ref modelName);

                    Model         model;
                    ModelInstance modelInstance;
                    if (reader.Mode == StatePersistMode.Read)
                    {
                        model         = reader.AssetStore.Models.GetByName(modelName);
                        modelInstance = model.CreateInstance(reader.AssetStore.LoadContext);

                        _modelsPerPlayer[i].Add(modelInstance);
                    }
                    else
                    {
                        modelInstance = _modelsPerPlayer[i][j];
                        model         = modelInstance.Model;
                    }

                    var scale = 1.0f;
                    reader.PersistSingle(ref scale);
                    if (scale != 1.0f)
                    {
                        throw new InvalidStateException();
                    }

                    reader.PersistColorRgba(ref modelInstance.HouseColor, "HouseColor");

                    reader.PersistVersion(1);

                    var modelTransform = reader.Mode == StatePersistMode.Write
                        ? Matrix4x3.FromMatrix4x4(modelInstance.GetWorldMatrix())
                        : Matrix4x3.Identity;
                    reader.PersistMatrix4x3(ref modelTransform, readVersion: false);

                    if (reader.Mode == StatePersistMode.Read)
                    {
                        modelInstance.SetWorldMatrix(modelTransform.ToMatrix4x4());
                    }

                    var numMeshes = (uint)model.SubObjects.Length;
                    reader.PersistUInt32(ref numMeshes);
                    if (numMeshes > 0 && numMeshes != model.SubObjects.Length)
                    {
                        throw new InvalidStateException();
                    }

                    reader.BeginArray("Meshes");
                    for (var k = 0; k < numMeshes; k++)
                    {
                        reader.BeginObject();

                        var meshName = model.SubObjects[k].FullName;
                        reader.PersistAsciiString(ref meshName);

                        if (meshName != model.SubObjects[k].FullName)
                        {
                            throw new InvalidStateException();
                        }

                        reader.PersistBoolean(ref modelInstance.UnknownBools[k], "UnknownBool");

                        var meshTransform = reader.Mode == StatePersistMode.Write
                            ? Matrix4x3.FromMatrix4x4(modelInstance.RelativeBoneTransforms[model.SubObjects[k].Bone.Index])
                            : Matrix4x3.Identity;
                        reader.PersistMatrix4x3(ref meshTransform, readVersion: false);

                        if (reader.Mode == StatePersistMode.Read)
                        {
                            // TODO: meshTransform is actually absolute, not relative.
                            modelInstance.RelativeBoneTransforms[model.SubObjects[k].Bone.Index] = meshTransform.ToMatrix4x4();
                        }

                        reader.EndObject();
                    }
                    reader.EndArray();

                    reader.EndObject();
                }
                reader.EndArray();

                reader.EndObject();
            }
            reader.EndArray();

            reader.PersistBoolean(ref _hasUnknownThing);
            if (_hasUnknownThing)
            {
                reader.PersistByte(ref _unknownByte);
                reader.PersistUInt32(ref _unknownInt);
            }
        }