public override void SendInitialState(BSONObject bsonObj, INetObjectViewer viewer)
    {
        base.SendInitialState(bsonObj, viewer);

        // if we have trunk pieces, send those
        if (this.trunkPieces.Count > 0)
        {
            BSONArray trunkInfo = BSONArray.New;
            foreach (var trunkPiece in this.trunkPieces)
            {
                trunkInfo.Add(trunkPiece.ToInitialBson());
            }
            bsonObj["trunks"] = trunkInfo;
        }

        if (this.Controller != null && this.Controller is INetObject)
        {
            bsonObj["controller"] = ((INetObject)this.Controller).ID;
        }

        if (this.stumpHealth <= 0f) // trunk pieces have their own grounders
        {
            bsonObj["noGround"] = true;
        }

        bsonObj["mult"] = this.resourceMultiplier;
    }
        /// Transforms a position in world space to Bellows polar coordinates
        public BSONArray WorldToBellowsPosition(Vector3 vec)
        {
            // Transform point to be relative to whatever this Sound Master is attached to
            // (usually the camera)
            vec = transform.InverseTransformPoint(vec);

            // X value in bellows is simply polar direction
            float bellowsX = Mathf.Atan2(vec.z, vec.x) / (Mathf.PI * 2);

            // Y value in bellows is just the height
            float bellowsY = vec.y;

            // Z value in bellows is the distance to the sound, ignoring height
            float bellowsZ = Mathf.Sqrt((vec.x * vec.x) + (vec.z * vec.z));

            BSONArray a = new BSONArray();

            a.Add(bellowsX);
            a.Add(bellowsY);
            a.Add(bellowsZ);

            return(a);
        }
    public override void SendUpdate(BSONObject bsonObj, INetObjectViewer viewer)
    {
        base.SendUpdate(bsonObj, viewer);

        if (this.Fallen && this.Controller != viewer)
        {
            BSONArray trunkInfo = BSONArray.New;
            foreach (var trunkPiece in this.trunkPieces)
            {
                if (trunkPiece.Position == Vector3.Zero)
                {
                    continue;
                }
                if (trunkPiece.LastUpdateTime < viewer.LastSentUpdateTime)
                {
                    continue;
                }

                trunkInfo.Add(trunkPiece.ToUpdateBson());
            }
            bsonObj["trunks"] = trunkInfo;
            bsonObj["time"]   = this.lastKeyframeTime;
        }
    }