Example #1
0
    public void AsyncLoadingScript(GameObject myReturnValue)
    {
        #region 读取模型
        transform.position += StartPointOffSet;
        InstanceMesh        = Instantiate(myReturnValue) as GameObject;
        InstanceMesh.transform.SetParent(this.transform);
        InstanceMesh.transform.localPosition    = Vector3.zero;
        InstanceMesh.transform.localEulerAngles = Vector3.zero;
        #endregion

                #if UNITY_EDITOR && UNITY_ANDROID
        foreach (MeshRenderer meshRenderer in InstanceMesh.GetComponentsInChildren <MeshRenderer>())
        {
            meshRenderer.sharedMaterial.shader = Shader.Find("Standard");
        }
                #endif

        #region 设置网络状态
        if (_InstanceNetType != InstanceNetType.GarageTank && !isBot(_InstanceNetType) && _InstanceNetType != InstanceNetType.GameNetWorkOffline)
        {
        }
        #endregion


        //模块加载
        dontDestroyManager = new VehicleDontDestroyManagerModule();

        referenceManager = InstanceMesh.GetComponent <VehicleComponentsReferenceManager>();


        #region 加载完毕游戏资源加载脚本
        TankPrefabs     = gameObject;
        TurretTransform = InstanceMesh.transform.Find("TurretTransform").gameObject;
        MainHitBox      = InstanceMesh.transform.Find("MainHitBox").gameObject;
        TankTransform   = InstanceMesh.transform.Find("TankTransform").gameObject;
        GunTransform    = TurretTransform.transform.Find("GunTransform").gameObject;
        FFPoint         = GunTransform.transform.Find("FFPoint").gameObject;
        EffectStart     = GunTransform.transform.Find("EffectStart").gameObject;
        TurretHitBox    = TurretTransform.transform.Find("TurretHitBox").gameObject;



        GameObject       TankScript = null, TankCrossHair = null, MainCamera = null;
        Rigidbody        TankPhysic = null;
        TurretController mt         = null;
//		SyncGroundVehicle _syncGroundVehicle = null;
        PlayerTracksController PTC = null;
        PlayerState            PS  = null;
        PTC = InstanceMesh.AddComponent <PlayerTracksController> ();

        #region 物理效果
        TankPhysic             = GetComponentInChildren <Rigidbody> ();
        TankPhysic.mass        = PTCParameter.Mass;
        TankPhysic.drag        = 0.1f; //PTCParameter.Drag;
        TankPhysic.angularDrag = 2.5f; //PTCParameter.AirDrag;
        TankPhysic.useGravity  = false;
        BoxCollider[] collisions = PTC.GetComponentsInChildren <BoxCollider> ();
        foreach (Collider collision in collisions)
        {
            if (collision.isTrigger != true)
            {
                collision.material = StaticResourcesReferences.Instance.VehiclePhysicMaterial;
            }
        }

        #endregion
        if (_InstanceNetType != InstanceNetType.GarageTank)
        {
            if (isLocalPlayer(_InstanceNetType))
            {
                TankCrossHair = Instantiate((GameObject)Resources.Load("TankCrossHair"), Vector3.zero, Quaternion.identity) as GameObject;
                MainCamera    = Instantiate((GameObject)Resources.Load("MainCamera"), Vector3.zero, Quaternion.identity) as GameObject;
                TankCrossHair.transform.parent = TankPrefabs.transform;
                MainCamera.transform.parent    = InstanceMesh.transform;
                MainCamera.transform.name      = "MainCamera";
            }
            TankScript = Instantiate((GameObject)Resources.Load("TankScript"), Vector3.zero, Quaternion.identity) as GameObject;

            TankScript.transform.name   = "TankScript";
            TankScript.transform.parent = TankPrefabs.transform;
            TankPhysic.useGravity       = true;

            #region PlayerState 脚本设置
            if (!isBot(_InstanceNetType))
            {
                PS = InstanceMesh.AddComponent <PlayerState>();
                PS.tankInitSystem = this;

                foreach (HitBox HB in GetComponentsInChildren <HitBox>())
                {
                    HB.SetTarget(PS);
                }
                PS.playerStateParameter = PSParameter;

                PS.netType            = _InstanceNetType;
                PS.Turret             = TurretTransform;
                PS.TankScript         = TankScript;
                PS.DiedDestoryObjects = new Object[] { MainHitBox, TurretHitBox };
                PS.TankName           = VehicleName;
                PS.Health             = PSParameter.Health;
                PS.engineType         = PSParameter.engineType;

                PS.IsMobile = isMobile;
            }
            #endregion
            if (isBot(_InstanceNetType))
            {
                EnemyAiState enemyState = InstanceMesh.AddComponent <EnemyAiState>();
                foreach (HitBox HB in GetComponentsInChildren <HitBox>())
                {
                    HB.SetTarget(enemyState);
                }
                enemyState.TankScript = TankScript;
                enemyState.Health     = PSParameter.Health;
                enemyState.TankName   = VehicleName;
                enemyState.MyTeam     = ownerTeam;
            }

            #region TankScript 脚本设置
            mt = TankScript.GetComponent <TurretController>();
            if (isLocalPlayer(_InstanceNetType))
            {
                mt.target = MainCamera.transform.Find("CameraTarget");
            }
            mt.gun                    = GunTransform.transform;
            mt.Turret                 = TurretTransform.transform;
            mt.DownMaxDegree          = MTParameter.DownMaxDegree;
            mt.UpMaxDegree            = MTParameter.UpMaxDegree;
            mt.maxTurretAngle         = MTParameter.maxTurretAngle;
            mt.gunDegreesPerSecond    = MTParameter.gunDegreesPerSecond;
            mt.turretDegreesPerSecond = MTParameter.turretDegreesPerSecond;
            mt.isMobile               = isMobile;
            #endregion
            #region 主摄像机设置
            if (isLocalPlayer(_InstanceNetType))
            {
                MainCamera.GetComponent <VehicleCamera>().target = referenceManager.MainCameraFollowTarget.transform;
                MainCamera.GetComponent <VehicleCamera>().mainCameraFollowTarget = referenceManager.MainCameraFollowTarget.transform;
                MainCamera.GetComponent <VehicleCamera>().mainCameraGunner       = referenceManager.MachineGunFFPoint.transform;
                referenceManager.MachineGunFFPoint.transform.position            = referenceManager.FFPoint.transform.position;
                MainCamera.GetComponent <VehicleCamera>().IsMobile = isMobile;
                if (PSParameter.vehicleType == VehicleType.SPG)
                {
                    MainCamera.GetComponent <VehicleCamera>().isVehicleSPG = true;
                }
            }

            #endregion
            #region 瞄准射线
            if (isLocalPlayer(_InstanceNetType))
            {
                RayManager rayManager = TankScript.AddComponent <RayManager>();
                rayManager.Init(FFPoint.transform);
            }
            #endregion
            #region 瞄准镜设置
            if (isLocalPlayer(_InstanceNetType))
            {
                TankCrossHair.GetComponent <CrossHair>().MainCamera = MainCamera.GetComponent <Camera>();
                TankCrossHair.GetComponent <CrossHair>().tankCamera = MainCamera.GetComponent <VehicleCamera>();
                TankCrossHair.GetComponent <CrossHair>().FFPoint    = EffectStart.transform;
            }
            #endregion
            #region 坦克发射器脚本设置
            TankFire tf = TankScript.GetComponent <TankFire>();
            tf.tankFireParameter = TFParameter;
            tf.tankInitSystem    = this;
            tf.MachineGunFFPoint = referenceManager.MachineGunFFPoint.transform;
            tf.FFPoint           = referenceManager.FFPoint.transform;
            tf.FireRecoilPoint   = referenceManager.FireForceFeedbackPoint.transform;
            tf.FireEffectPoint   = referenceManager.EffectStart.transform;
            tf.BulletCountList   = BulletCountList;
            tf.GunDym            = GunTransform.transform.Find("GunDym").GetComponent <Animator>();
            tf.MainBody          = InstanceMesh.transform;
            tf.netType           = _InstanceNetType;


            if (PSParameter.vehicleType == VehicleType.SPG)
            {
                tf.isAutoCaclulateGravity = true;
            }
            #endregion

            #region 引擎音效控制
            EngineSoundModule engineSoundModule = InstanceMesh.AddComponent <EngineSoundModule>();
            engineSoundModule.tankInitSystem = this;
            engineSoundModule.engineData     = PTCParameter.vehicleEngineSoundData;
            engineSoundModule.Init(referenceManager.EngineSound.transform);
            #endregion
            GameObject EngineSmoke = Instantiate <GameObject>(Resources.Load <GameObject>("EngineSmoke"));
            EngineSmoke.transform.SetParent(referenceManager.EngineSmoke.transform);
            EngineSmoke.transform.localPosition    = Vector3.zero;
            EngineSmoke.transform.localEulerAngles = Vector3.zero;

            //GameObject grounddust = Instantiate(Resources.Load<GameObject>("TrackEffect"));
            //grounddust.transform.SetParent(InstanceMesh..transform);
            //grounddust.transform.localPosition = Vector3.zero;
            //grounddust.transform.localEulerAngles = Vector3.zero;

            VehicleState vehicleState = InstanceMesh.AddComponent <VehicleState>();
            vehicleState.engineSoundModule    = engineSoundModule;
            vehicleState.tankTracksController = PTC;
        }

        #region 坦克控制器设置
        PTC.tankInitSystem = this;

        PTC.rightTrackUpperWheels = GetAllChilds(TankTransform.transform.Find("RightUpperWheel"));
        PTC.leftTrackUpperWheels  = GetAllChilds(TankTransform.transform.Find("LeftUpperWheel"));
        PTC.rightTrackWheels      = GetAllChilds(TankTransform.transform.Find("RightWheel"));
        PTC.leftTrackWheels       = GetAllChilds(TankTransform.transform.Find("LeftWheel"));
        PTC.leftTrack             = referenceManager.LeftTrack;
        PTC.rightTrack            = referenceManager.RightTrack;

        //PTC.leftTrackBones = CreateTrack (true, TankTransform.transform, ref PTC);
        //PTC.rightTrackBones = CreateTrack (false, TankTransform.transform, ref PTC);
        PTC.tankTransform = TankTransform.transform;



        PTC.maxAngularVelocity = PTCParameter.MaxAngularVelocity;
        PTC.MaxSpeed           = PTCParameter.MaxSpeed;
        PTC.MinSpeed           = PTCParameter.MinSpeed;
        PTC.COM       = PTCParameter.CenterOfGravity;
        PTC.PushSpeed = PTCParameter.PushSpeed;
        PTC.BackSpeed = PTCParameter.BackSpeed;

        PTC.sidewaysFrictionAsymptoteFactor = PTCParameter.SideWaysFrictionAsymptoteFactor;
        PTC.sidewaysFrictionExtremumFactor  = PTCParameter.SideWaysFrictionExtremumFactor;
        PTC.wheelCollider = PTCParameter.TankWheelCollider;

        PTC.wheelsAndBonesAxisSettings = new PlayerTracksController.WheelsAxisSettings();
        PTC.wheelsAndBonesAxisSettings.bonesPositionAxis  = TankTracksController.Axis.Z;
        PTC.wheelsAndBonesAxisSettings.wheelsPositionAxis = TankTracksController.Axis.Z;
        PTC.wheelsAndBonesAxisSettings.wheelsRotationAxis = TankTracksController.Axis.X;

        PTC.accelerationConfiguration           = PTCParameter.VAconfigSetting;
        PTC.rotationOnAccelerationConfiguration = PTCParameter.HAconfigSetting;
        PTC.rotationOnStayConfiguration         = PTCParameter.HAconfigSetting;


        #endregion

        #region 车库状态
        if (_InstanceNetType == InstanceNetType.GarageTank)
        {
            PTC.enabled            = false;
            TankPhysic.isKinematic = true;

            if (ShowHitBoxInspecter)
            {
                foreach (HitBox HB in GetComponentsInChildren <HitBox>())
                {
                    HB.StartCoroutine(HB.ShowArmorInfo());
                }
            }

            foreach (MeshCollider MC in transform.root.GetComponentsInChildren <MeshCollider>())
            {
                if (MC.GetComponent <HitBox> () == null)
                {
                    MC.enabled = false;
                }
            }
            //EventManager.StartListening ("TankInitSystem.InitTankShader", GarageInitTankShaderPreView);
            return;
        }
        #endregion

        if (ExtraTF && !isBot(_InstanceNetType))
        {
            for (int i = 0; i < multiTurrets.Length; i++)
            {
                GameObject TankScriptExtra = Instantiate((GameObject)Resources.Load("TankScript"), Vector3.zero, Quaternion.identity) as GameObject;
                TankScriptExtra.transform.name   = "TankScriptExtra";
                TankScriptExtra.transform.parent = TankPrefabs.transform;
                TurretController mouseTurretExtra = TankScriptExtra.GetComponent <TurretController> ();
                if (isLocalPlayer(_InstanceNetType))
                {
                    mouseTurretExtra.target = MainCamera.transform.Find("CameraTarget");
                }
                Transform ExtraTurret = InstanceMesh.transform.Find(multiTurrets [i].ObjectPath);

                Transform ExtraGun = ExtraTurret.transform.Find("GunTransform");

                mouseTurretExtra.gun                    = ExtraGun;
                mouseTurretExtra.Turret                 = ExtraTurret;
                mouseTurretExtra.DownMaxDegree          = multiTurrets [i].MTParameter.DownMaxDegree;
                mouseTurretExtra.UpMaxDegree            = multiTurrets [i].MTParameter.UpMaxDegree;
                mouseTurretExtra.maxTurretAngle         = multiTurrets [i].MTParameter.maxTurretAngle;
                mouseTurretExtra.gunDegreesPerSecond    = multiTurrets [i].MTParameter.gunDegreesPerSecond;
                mouseTurretExtra.turretDegreesPerSecond = multiTurrets [i].MTParameter.turretDegreesPerSecond;
                mouseTurretExtra.isMobile               = isMobile;

                TankFire  tfExtra         = TankScriptExtra.GetComponent <TankFire> ();
                Transform ExtraFFPoint    = ExtraGun.Find("FFPoint");
                Transform ExtraFireEffect = ExtraGun.Find("FireEffect");

                tfExtra.FFPoint         = ExtraFFPoint;
                tfExtra.FireRecoilPoint = FFPoint.transform;
                tfExtra.FireEffectPoint = ExtraFireEffect;
                tfExtra.MainBody        = InstanceMesh.transform;
                //tfExtra.FireRecoil = multiTurrets [i].tankFireParameter.FireRecoil;
                //tfExtra.ReloadTime = multiTurrets [i].tankFireParameter.ReloadTime;
                //tfExtra.AmmoCount = multiTurrets [i].tankFireParameter.AmmoCount;
                //tfExtra.HasMahineGun = multiTurrets [i].tankFireParameter.HasMachineGun;
                //tfExtra.muzzleFire = multiTurrets [i].tankFireParameter.MuzzleFire;
                //tfExtra.advanceFireClass = multiTurrets [i].tankFireParameter.advanceFireClass;
                //tfExtra.fireState = multiTurrets [i].tankFireParameter.FireState;
                //tfExtra.netType = InstanceNetType;
            }
        }
        #endregion

        InstanceMesh.AddComponent <Identity> ();
        if (isLocalPlayer(_InstanceNetType))
        {
            GameEvent.InitPlayer(InstanceMesh.GetComponent <Identity>());
        }
        #region 初始化玩家网络
        if (!GameDataManager.OfflineMode)
        {
            if (_InstanceNetType == InstanceNetType.GameNetworkOthers)
            {
                PTC.enableUserInput = false;
                //PTC.AdvanceTrackSystem = false;
                PTC.OnlyReceiveControlActions = true;
            }
            if (_InstanceNetType == InstanceNetType.GameNetworkMaster)
            {
                PTC.enableUserInput = false;
            }

            if (_InstanceNetType == InstanceNetType.GameNetworkClient)
            {
                PTC.enableUserInput           = true;
                PTC.OnlyReceiveControlActions = true;
            }
            if (isBot(_InstanceNetType))
            {
                PTC.enableUserInput = false;
                if (_InstanceNetType == InstanceNetType.GameNetWorkBotClient)
                {
                    PTC.OnlyReceiveControlActions = true;
                }
                else
                {
                    PTC.OnlyReceiveControlActions = false;
                }
            }

            //_syncGroundVehicle = InstanceMesh.AddComponent<SyncGroundVehicle> ();
            //_syncGroundVehicle.tankInitSystem = this;
            //_syncGroundVehicle.Init (PTC, mt, _InstanceNetType);
        }
        #region 设置离线标识
        if (GameDataManager.OfflineMode)
        {
            if (_InstanceNetType == InstanceNetType.GameNetWorkOffline)
            {
                Identity MyIdentity = InstanceMesh.GetComponent <Identity> ();
                MyIdentity.Init(ownerTeam, InstanceNetType.GameNetWorkOffline);
                MyIdentity.SetOwnerInfo("LocalPlayer", VehicleName, 0);
            }
        }
        #endregion
        #endregion
        if (!isBot(_InstanceNetType))
        {
            StartCoroutine(PS.Init());
        }

        if (GameEventManager.onNewVehicleSpawned != null)
        {
            GameEventManager.onNewVehicleSpawned(this);
        }

        if (onVehicleLoaded != null)
        {
            onVehicleLoaded();
        }
    }
Example #2
0
        /// <summary>
        /// <param name="node">The "<node>" element to be converted.</param>
        /// </summary>
        private Bone ReadNode(Bone parent, Document.Node node)
        {
            Bone bone = new Bone(this, parent, node.id, node.name, node.type);

            if (node.instances != null)
            {
                foreach (Document.Instance instance in node.instances)
                {
                    if (instance is Document.InstanceGeometry)
                    {
                        // resolve bindings
                        Dictionary<string, string> materialBinding = ResolveMaterialBinding((Document.InstanceWithMaterialBind)instance);

                        Document.Geometry geo = (Document.Geometry)doc.dic[instance.url.Fragment];
                        CMesh modelMesh;
                        if (meshes.TryGetValue(geo.id, out modelMesh))
                        {
                            InstanceMesh instanceMesh = new InstanceMesh(modelMesh,
                                                                         bone,
                                                                         materialBinding);
                            instanceMeshes.Add(instanceMesh);
                        }
                        else
                            COLLADAUtil.Log(COLLADALogType.Error, "mesh with id " + geo.id + " not found in internal mesh list");
                    }
                    else if (instance is Document.InstanceCamera)
                    {
                        Document.InstanceCamera instanceCamera = (Document.InstanceCamera)instance;
                        Document.Camera docCam = (Document.Camera)doc.dic[instanceCamera.url.Fragment];
                        if (docCam != null)
                        {
                            Camera camera;
                            if (cameras.TryGetValue(docCam.id, out camera))
                            {
                                InstanceCamera c = new InstanceCamera(camera, bone);
                                instanceCameras.Add(c);
                            }
                            else
                                COLLADAUtil.Log(COLLADALogType.Error, "Camera " + docCam.id + " not found in internal camera list.");
                        }
                        else
                            COLLADAUtil.Log(COLLADALogType.Error, "Camera " + instanceCamera.url.Fragment + " not found.");
                    }
                    else if (instance is Document.InstanceLight)
                    {
                        // TODO: light
                    }
                    else if (instance is Document.InstanceController)
                    {
                        Document.InstanceController instanceController = (Document.InstanceController)instance;
                        Document.ISkinOrMorph skinOrMorph = ((Document.Controller)doc.dic[instanceController.url.Fragment]).controller;
                        if (skinOrMorph is Document.Skin)
                        {
                            // resolve bindings
                            Dictionary<string, string> materialBinding = ResolveMaterialBinding((Document.InstanceWithMaterialBind)instance);
                            Document.Skin skin = (Document.Skin)skinOrMorph;
                            Document.Geometry geo = ((Document.Geometry)doc.dic[skin.source.Fragment]);

                            // make sure mesh is in loaded mesh list
                            CMesh mesh;
                            if (meshes.TryGetValue(geo.id, out mesh))
                            {
                                // mesh was loaded once successfully, try to look for it in the list of skinned
                                // meshes (skinned meshes have different vertex declarations)...
                                CSkinnedMesh skinnedMesh;
                                if (!skinnedMeshes.TryGetValue(geo.id, out skinnedMesh))
                                {
                                    // mesh wasn't found, create it once
                                    skinnedMesh = new CSkinnedMesh(this, geo, skin);
                                    skinnedMeshes.Add(geo.id, skinnedMesh);
                                }

                                var skeletonRootNodes = instanceController.Skeleton.Select(s => (Document.Node)doc.dic[s.Fragment]).ToArray();
                                SkinnedInstanceMesh skinnedInstanceMesh = new SkinnedInstanceMesh(
                                    skinnedMesh,
                                    bone,
                                    materialBinding,
                                    skeletonRootNodes);
                                instanceMeshes.Add(skinnedInstanceMesh);
                            }
                            else
                                COLLADAUtil.Log(COLLADALogType.Error, "mesh with id " + geo.id + " not found in internal mesh list");

                        }
                        else if (skinOrMorph is Document.Morph)
                        {
                            // TODO: morph
                        }
                        else
                            throw new Exception("Unknowned type of controller:" + skinOrMorph.GetType().ToString());
                    }
                    else if (instance is Document.InstanceNode)
                    {
                        Document.Node instanceNode = ((Document.Node)doc.dic[instance.url.Fragment]);
                        bone.Children.Add(ReadNode(bone, instanceNode));

                    }
                    else
                        throw new Exception("Unkowned type of INode in scene :" + instance.GetType().ToString());
                }
            }

            // read transforms
            if (node.transforms != null)
            {
                foreach (Document.TransformNode transformNode in node.transforms)
                {
                    if (transformNode is Document.Translate)
                        bone.Transforms.Add(transformNode.sid, new TranslateTransform(new Vector3(transformNode[0], transformNode[1], transformNode[2])));
                    else if (transformNode is Document.Rotate)
                        bone.Transforms.Add(transformNode.sid, new RotateTransform(new Vector3(transformNode[0], transformNode[1], transformNode[2]), transformNode[3]));
                    else if (transformNode is Document.Lookat)
                        bone.Transforms.Add(transformNode.sid, new Transform(Matrix.LookAtLH(new Vector3(transformNode[0], transformNode[1], transformNode[2]), new Vector3(transformNode[3], transformNode[4], transformNode[5]), new Vector3(transformNode[6], transformNode[7], transformNode[8]))));
                    else if (transformNode is Document.Matrix)
                    {
                        Matrix m = Matrix.Identity;
                        m.M11 = transformNode[0];
                        m.M21 = transformNode[01];
                        m.M31 = transformNode[02];
                        m.M41 = transformNode[03];
                        m.M12 = transformNode[04];
                        m.M22 = transformNode[05];
                        m.M32 = transformNode[06];
                        m.M42 = transformNode[07];
                        m.M13 = transformNode[08];
                        m.M23 = transformNode[09];
                        m.M33 = transformNode[10];
                        m.M43 = transformNode[11];
                        m.M14 = transformNode[12];
                        m.M24 = transformNode[13];
                        m.M34 = transformNode[14];
                        m.M44 = transformNode[15];
                        bone.Transforms.Add(transformNode.sid, new Transform(m));
                    }
                    else if (transformNode is Document.Scale)
                    {
                        bone.Transforms.Add(transformNode.sid, new ScaleTransform(new Vector3(transformNode[0], transformNode[1], transformNode[2])));
                    }
                    else if (transformNode is Document.Skew)
                    {
                        // Convert Skew to a matrix
                        float angle = transformNode[0] * (float)DegToRad;
                        Vector3 a = new Vector3(transformNode[1], transformNode[2], transformNode[3]);
                        Vector3 b = new Vector3(transformNode[4], transformNode[5], transformNode[6]);
                        Vector3 n2 = Vector3.Normalize(b);
                        Vector3 a1 = n2 * Vector3.Dot(a, n2);
                        Vector3 a2 = a - a1;
                        Vector3 n1 = Vector3.Normalize(a2);
                        float an1 = Vector3.Dot(a, n1);
                        float an2 = Vector3.Dot(a, n2);
                        double rx = an1 * Math.Cos(angle) - an2 * Math.Sin(angle);
                        double ry = an1 * Math.Sin(angle) + an2 * Math.Cos(angle);
                        float alpha = 0.0f;
                        Matrix m = Matrix.Identity;

                        if (rx <= 0.0) throw new Exception("Skew: angle too large");
                        if (an1 != 0) alpha = (float)(ry / rx - an2 / an1);

                        m.M11 = n1.X * n2.X * alpha + 1.0f;
                        m.M12 = n1.Y * n2.X * alpha;
                        m.M13 = n1.Z * n2.X * alpha;

                        m.M21 = n1.X * n2.Y * alpha;
                        m.M22 = n1.Y * n2.Y * alpha + 1.0f;
                        m.M23 = n1.Z * n2.Y * alpha;

                        m.M31 = n1.X * n2.Z * alpha;
                        m.M32 = n1.Y * n2.Z * alpha;
                        m.M33 = n1.Z * n2.Z * alpha + 1.0f;

                        bone.Transforms.Add(transformNode.sid, new Transform(m));
                    }
                }
            }

            if (node.children != null)
            {
                foreach (Document.Node child in node.children)
                {
                    bone.Children.Add(ReadNode(bone, child));
                }
            }

            return bone;
        }