예제 #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);
        }
    }
예제 #2
0
    SsPart(
        SsSprite manager,
        int index,                              ///< index of parts
        SsPartRes partRes,                      ///< part resource
        SsImageFile imageFile)                  ///< source image path, texture and material.
    {
        _mgr          = manager;
        _index        = index;
        _vIndex       = (index - 1) * 4;
        _subMeshIndex = index - 1;
        _res          = partRes;
        _mesh         = _mgr._mesh;

        if (_res.HasParent)
        {
            _parent = _mgr.Sprite(_res.ParentId);
            if (_parent == null)
            {
                Debug.LogError("##### parent sprite must be created already!!");
                //throw ArgumentNullException;
                Debug.Break();
                return;
            }
        }

        // attach parent's transform to inherit its SRT.
        _pivotMatrix = Matrix4x4.identity;
        switch (_res.Type)
        {
        case SsPartType.Root:
            // root has only position, no vertices
#if _APPLY_ROOT_POS_AS_PIVOT
            _rootPivot = new Vector3(-_res.PosX(0), +_res.PosY(0), 0f);
#endif
            break;

        case SsPartType.Normal:
        case SsPartType.Bound:
            // each vertices are attached to pivot
            _vertPositions = new Vector3[4];
            _orgVertices   = new Vector3[4];
            for (int i = 0; i < _vertPositions.Length; ++i)
            {
                _orgVertices[i] = _vertPositions[i] = _res.OrgVertices[i];
#if _MOVE_BOUND_PART_TO_THE_FRONT
                if (_res.Type == SsPartType.Bound)
                {
                    _vertPositions[i].z = -0.1f;
                    _orgVertices[i].z   = -0.1f;
                }
#endif
            }
            break;

        default:
            // other types don't require vertices.
            break;
        }

        // set startup value
        _visible    = !_res.Hide(0);
        _flipH      = false;
        _flipV      = false;
        _pos        = Vector3.zero;
        _quaternion = Quaternion.identity;
        _scale      = Vector3.one;
#if _MAKE_ROOT_TO_LOCAL_TRANSFORM
        _rotChanged = false;
#endif
        // not any normal types don't require a material, colors, and vertices.
        if (_res.Type != SsPartType.Normal &&
            _res.Type != SsPartType.Bound)
        {
            return;
        }

        // shortcut
#if _USE_UNIFIED_SHADER
        _useUnifiedShader = _res.imageFile.useUnifiedShader;
#endif
        _useCgShader = (SystemInfo.graphicsShaderLevel >= 20);

        if (_res.Type == SsPartType.Bound)
        {
#if !_BOUND_PART_DRAW_AS_INVALID
            // set vertex color to transparent red.
            // this alpha value will be overwritten in AlphaValue property later.
            _vertexColor = new Color(1, 0, 0, 1);
            for (int i = 0; i < 4; ++i)
            {
                // set UVs to a point at left-top.
                _mgr._uvs[_vIndex + i] = Vector2.zero;

                // set vertex colors
                _mgr._colors[_vIndex + i] = _vertexColor;
            }
            // invisible is default.
            _visible = false;
#else
            _visible = _mgr.DrawBoundingParts;
#endif
        }
        else
        {
            // default vertex color
            _vertexColor = new Color(1, 1, 1, 1);
            for (int i = 0; i < 4; ++i)
            {
                // set UVs. use precalculated UVs, it is stored clockwise
                _mgr._uvs[_vIndex + i] = _res.UVs[i];

                // set vertex colors
                _mgr._colors[_vIndex + i] = _vertexColor;
            }
            // set blend type and _shaderType
            ColorBlendType = SsColorBlendOperation.Non;
        }

        // set boolean about having transparency
        if (_res.Type == SsPartType.Bound)
        {
#if _BOUND_PART_DRAW_AS_INVALID
            // become purple that mean invalid.
            _material = null;
#else
            // needs any appropriate material
            _hasTransparency = true;
            AlphaValue       = 0.5f;
#endif
        }
        else
        {
            _hasTransparency = _res.HasTrancparency ||
                               (_parent != null && _res.Inherits(SsKeyAttr.Trans));    // always inherits parent's alpha whether the immediate parent has transparency or not. 2012.12.19 bug fixed
            // set alpha value
            AlphaValue = _res.Trans(0);

            // set appropriate material. _shaderType was set inside ColorBlendType property.
            _material = imageFile.GetMaterial(_shaderType);
        }

        //--------- calculates various info...
        Update(true);

        // set triangle indices. never changed so far.
#if _USE_TRIANGLE_STRIP
        _triIndices = new int[] { _vIndex + 0, _vIndex + 1, _vIndex + 3, _vIndex + 2 };                           // order is LT->RT->LB->RB.
#else
        _triIndices = new int[] { _vIndex + 0, _vIndex + 1, _vIndex + 2, _vIndex + 2, _vIndex + 3, _vIndex + 0 }; // order is LT->RT->RB->RB->LB->LT
#endif

        SetToSubmeshArray(_index - 1);
    }