예제 #1
0
    UpdateSub(SsPartRes res, int frame, bool initialize = false)
    {
        // priority
        if (res.HasAttrFlags(SsKeyAttrFlags.Prio))
        {
            int nowPrio = (int)res.Prio(frame);
            if (_priority != nowPrio)
            {
                _priority         = nowPrio;
                _mgr._prioChanged = true;
            }
        }

        // visibility
        if (res.HasAttrFlags(SsKeyAttrFlags.Hide))
        {
            if (res.IsRoot)
            {
                _visible = !res.Hide(frame);
            }
            else
            if (res.Type == SsPartType.Normal)
            {
                bool nowVisible;
                if (res.IsBeforeFirstKey(frame))
                {
                    nowVisible = false;
                }
                else
                {
                    if (_parent != null &&
                        !_parent._res.IsRoot &&
                        (res.InheritRate(SsKeyAttr.Hide) > 0.5f))
                    {
                        nowVisible = _parent._visible;
                    }
                    else
                    {
                        nowVisible = !res.Hide(frame);
                    }
                }
#if _INHERITS_FORCE_VISIBLE
                if (_forceVisibleAvailable)
                {
                    nowVisible = _forceVisible;
                }
#endif
                if (nowVisible != _visible)
                {
                    Show(nowVisible);
                }
            }
        }

        // vertex color
        if (res.HasAttrFlags(SsKeyAttrFlags.PartsCol))
        {
            SsColorBlendKeyValue  cbk   = res.PartsCol(frame);
            SsColorBlendOperation cbkOp = ColorBlendType;
            if (cbk == null)
            {
                if (_colorBlendKeyValue != null)
                {
                    // set back default color
                    cbkOp = SsColorBlendOperation.Non;
                    for (int i = 0; i < 4; ++i)
                    {
                        _mgr._colors[_vIndex + i] = _vertexColor;
                    }
                    _mgr._colorChanged = true;
                }
            }
            else
            {
                cbkOp = cbk.Operation;
                if (cbk.Target == SsColorBlendTarget.Vertex)
                {
                    // vertex colors
                    for (int i = 0; i < 4; ++i)
                    {
                        _mgr._colors[_vIndex + i] = GetBlendedColor(cbk.Colors[i], cbk.Operation);
                    }
                }
                else
                {
                    // affect a color to overall, so it doesn't inidicate that this is not vertex color.
                    Color c = GetBlendedColor(cbk.Colors[0], cbk.Operation);
                    for (int i = 0; i < 4; ++i)
                    {
                        _mgr._colors[_vIndex + i] = c;
                    }
                }
                _mgr._colorChanged = true;
            }
            _colorBlendKeyValue = cbk;

            if (_mgr._colorChanged)
            {
                if (cbkOp != ColorBlendType)
                {
                    // change other shader
                    ColorBlendType = cbkOp;
                    // place stored alpha is variable with color blend type. where is simply in color.a if blend is none.
                    AlphaValue = AlphaValue;
                }
            }
        }

        // transparency
        if (_hasTransparency)
        {
            float nowAlpha = res.Trans(frame);
            if (_parent != null && res.Inherits(SsKeyAttr.Trans))
            {
                float parentAlpha;
                // if parent is root, it doesn't have material.
                if (_parent._material == null)
                {
                    parentAlpha = _parent._res.Trans(frame);
                }
                else
                {
                    parentAlpha = _parent.AlphaValue;
                }
                // just multiply simply
                nowAlpha = parentAlpha * nowAlpha;
            }
            if (_forceAlphaAvailable)
            {
                nowAlpha = _forceAlpha;
            }
            if (nowAlpha != AlphaValue)
            {
                AlphaValue = nowAlpha;
            }
        }

        // scale
        if (res.HasAttrFlags(SsKeyAttrFlags.Scale))
        {
            var scale = new Vector3(res.ScaleX(frame), res.ScaleY(frame), 1f);
            if (scale != _scale)
            {
                _scale            = scale;
                _mgr._vertChanged = true;
            }
        }

        // rotation (now supports only Z axis)
        if (res.HasAttrFlags(SsKeyAttrFlags.Angle))
        {
            var ang = res.Angle(frame);
            // SpriteStudio demands me to Z axis rotation consistently.
            if (_parent)
            {
                // reverse angle direction if parent part's scale is negative value.
                if (_parent._pivotMatrix.m00 * _parent._pivotMatrix.m11 < 0)
                {
                    ang *= -1;
                }
                if (_mgr.hFlip ^ _mgr.vFlip)
                {
                    ang *= -1;
                }
            }
            Quaternion rot = Quaternion.Euler(0, 0, ang);
            if (rot != _quaternion)
            {
                _quaternion       = rot;
                _mgr._vertChanged = true;
#if _MAKE_ROOT_TO_LOCAL_TRANSFORM
                _rotChanged = true;
#endif
            }
#if _MAKE_ROOT_TO_LOCAL_TRANSFORM
            else
            {
                _rotChanged = false;
            }
#endif
        }

        // translate
        if (res.HasAttrFlags(SsKeyAttrFlags.Pos))
        {
            var pos = new Vector3(res.PosX(frame), -res.PosY(frame));
#if false
            if (_parent != null)
            {
                if (_parent._flipH)
                {
                    pos.x *= -1;
                }
                if (_parent._flipV)
                {
                    pos.y *= -1;
                }
            }
#endif
#if _APPLY_ROOT_POS_AS_PIVOT
            // apply X,Y position as pivot if this is root.
            if (res.IsRoot)
            {
                pos += _rootPivot;
            }
#endif

#if false
            // update vertices when position is changed.
            if (_pos != pos)
#endif
            {
                _pos = pos;
                _mgr._vertChanged = true;
            }
        }

        bool orgVertChanged = false;

        // UV animation
        if (res.HasAttrFlags(SsKeyAttrFlags.ImageOffset))
        {
            int nowImgOfs = res.ImageOffsetX(frame);
            if (nowImgOfs != _imgOfsX)
            {
                _imgOfsX        = nowImgOfs;
                _mgr._uvChanged = true;
            }
            nowImgOfs = res.ImageOffsetY(frame);
            if (nowImgOfs != _imgOfsY)
            {
                _imgOfsY        = nowImgOfs;
                _mgr._uvChanged = true;
            }
            bool sizeChnaged = false;
            nowImgOfs = res.ImageOffsetW(frame);
            if (nowImgOfs != _imgOfsW)
            {
                _imgOfsW        = nowImgOfs;
                _mgr._uvChanged = true;
                sizeChnaged     = true;
            }
            nowImgOfs = res.ImageOffsetH(frame);
            if (nowImgOfs != _imgOfsH)
            {
                _imgOfsH        = nowImgOfs;
                _mgr._uvChanged = true;
                sizeChnaged     = true;
            }
            if (sizeChnaged)
            {
                // modify polygon size
                Vector2 size = res.PicArea.WH();
                size.x        += _imgOfsW;
                size.y        += _imgOfsH;
                _orgVertices   = res.GetVertices(size);
                orgVertChanged = true;
            }
            if (_mgr._uvChanged)
            {
                res.CalcUVs(_imgOfsX, _imgOfsY, _imgOfsW, _imgOfsH);
            }
        }

        // origin animation
        if (res.HasAttrFlags(SsKeyAttrFlags.OriginOffset))
        {
            int nowOrgOfsX = -res.OriginOffsetX(frame);
            if (nowOrgOfsX != _originOffset.x)
            {
                _originOffset.x = nowOrgOfsX;
                orgVertChanged  = true;
            }
            int nowOrgOfsY = res.OriginOffsetY(frame);
            if (nowOrgOfsY != _originOffset.y)
            {
                _originOffset.y = nowOrgOfsY;
                orgVertChanged  = true;
            }
        }

        if (res.HasAttrFlags(SsKeyAttrFlags.Vertex))
        {
            orgVertChanged = true;
        }

        // vertex modification
        if (orgVertChanged &&
            _vertPositions != null)
        {
            for (int i = 0; i < _vertPositions.Length; ++i)
            {
                _vertPositions[i] = _orgVertices[i];
                if (res.HasAttrFlags(SsKeyAttrFlags.Vertex))
                {
                    _vertPositions[i] += res.Vertex(frame).Vertex3(i);
                }
                if (res.HasAttrFlags(SsKeyAttrFlags.OriginOffset))
                {
                    _vertPositions[i] += _originOffset;
                }
            }
            orgVertChanged    = false;
            _mgr._vertChanged = true;
        }

        // flip image only. the setting is given from anime resource.
        bool dontFlipCoord = res.IsRoot ? false : _mgr._animation.hvFlipForImageOnly;

        // flip H
        bool nowFlipH = false;

        if (res.IsRoot)
        {
            nowFlipH = _mgr.hFlip;
        }
        else
        {
            if (dontFlipCoord)
            {
                if (_parent != null && res.Inherits(SsKeyAttr.FlipH))
                {
                    if (!_parent._res.IsRoot)
                    {
                        nowFlipH = _parent._flipH;
                    }
                }
            }
            if (res.FlipH(frame))
            {
                nowFlipH = !nowFlipH;
            }
        }

        if (!dontFlipCoord)
        {
            if ((nowFlipH && _scale.x > 0f) ||
                (!nowFlipH && _scale.x < 0f))
            {
                _scale.x         *= -1;
                _mgr._vertChanged = true;
            }
        }

        // flip V
        bool nowFlipV = false;

        if (res.IsRoot)
        {
            nowFlipV = _mgr.vFlip;
        }
        else
        {
            if (dontFlipCoord)
            {
                if (_parent != null && res.Inherits(SsKeyAttr.FlipV))
                {
                    if (!_parent._res.IsRoot)
                    {
                        nowFlipV = _parent._flipV;                              // 2012.06.27 fixed an issue that nowFlipV refers _parent._flipH
                    }
                }
            }
            if (res.FlipV(frame))
            {
                nowFlipV = !nowFlipV;
            }
        }
        if (!dontFlipCoord)
        {
            if ((nowFlipV && _scale.y > 0f) ||
                (!nowFlipV && _scale.y < 0f))
            {
                _scale.y         *= -1;
                _mgr._vertChanged = true;
            }
        }

        if (nowFlipH != _flipH ||
            nowFlipV != _flipV)
        {
            _flipH = nowFlipH;
            _flipV = nowFlipV;
            if (dontFlipCoord)
            {
                _mgr._uvChanged = true;
            }
        }

        // udpate uv indices
        if (_mgr._uvChanged &&
            res.UVs != null &&          // root part has no UVs
            res.UVs.Length == 4)
        {
            if (dontFlipCoord)
            {
                int index = -1;
                if (nowFlipV)
                {
                    index = 1;
                }
                if (nowFlipH)
                {
                    ++index;
                }
                for (int i = 0; i < 4; ++i)
                {
                    _mgr._uvs[_vIndex + i] = res.UVs[index >= 0 ? _flippedUvIndices[index, i] : i];
                }
            }
            else
            {
                for (int i = 0; i < 4; ++i)
                {
                    _mgr._uvs[_vIndex + i] = res.UVs[i];
                }
            }
        }

        // update vertex buffer
        if (_mgr._vertChanged)
        {
            // udpate matrix
            var p = _pos;
            var s = _scale;
            if (_parent)
            {
                // previously apply compensated value if this doesn't want to inherit parent's value.
                if (!res.Inherits(SsKeyAttr.ScaleX))
                {
                    s.x /= _parent._scale.x;
                    p.x /= _parent._scale.x;
                }
                if (!res.Inherits(SsKeyAttr.ScaleY))
                {
                    s.y /= _parent._scale.y;
                    p.y /= _parent._scale.y;
                }
            }
            _pivotMatrix.SetTRS(p, _quaternion, s);

            // multiply parent's
            if (_parent)
            {
                _pivotMatrix = _parent._pivotMatrix * _pivotMatrix;
            }

            if (_vertPositions != null)
            {
                // apply matrix to vertices
                for (int i = 0; i < _vertPositions.Length; ++i)
                {
                    Vector3 v = _pivotMatrix.MultiplyPoint3x4(_vertPositions[i]);
                    _mgr._vertices[_vIndex + i] = v;
                }
        #if false
                if (_drawPartsRect)
                {
                    // get rectangle from bounding box.
                    Vector3 lt = _vertTransforms[0].position;
                    Vector3 rb = _vertTransforms[2].position;
                    Vector3 rt = lt;
                    rt.x = rb.x;
                    Vector3 lb = lt;
                    lb.y = rb.y;
                    // draw rectangle
                    Debug.DrawLine(lt, rt, Color.red);
                    Debug.DrawLine(rt, rb, Color.red);
                    Debug.DrawLine(rb, lb, Color.red);
                    Debug.DrawLine(lb, lt, Color.red);
                }
        #endif
            }
        }

        if (_transform)
        {
#if _MAKE_ROOT_TO_LOCAL_TRANSFORM
            // update quaternion in root space and my transform
            if (_parent != null && _parent._rotChanged)
            {
                // apply parent's rotation on ahead
                _rootSpaceQuaternion = _quaternion * _parent._quaternion;
                UpdateRootTransform();
            }
            else
#endif
            if (_mgr._vertChanged)
            {
                // update transform in this part's local space.
                _transform.localPosition = _pos;
                _transform.localRotation = _quaternion;
                _transform.localScale    = _scale;
            }
        }

        // ignore when called from initializing.
        if (initialize)
        {
            return;
        }

        // do callback at userdata key
        if (ExistsOnUserDataKey &&
            _res.HasAttrFlags(SsKeyAttrFlags.User))
        {
            _OnEvent(SsKeyAttr.User);
        }

        // do callback at sound key
        if (ExistsOnSoundKey &&
            _res.HasAttrFlags(SsKeyAttrFlags.Sound))
        {
            _OnEvent(SsKeyAttr.Sound);
        }
    }