-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathRenderSprite.cs
More file actions
131 lines (111 loc) · 5.14 KB
/
Copy pathRenderSprite.cs
File metadata and controls
131 lines (111 loc) · 5.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
using System;
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Graphics;
namespace Stride.Rendering.Sprites
{
public enum SpriteSampler
{
[Display("Point (Nearest)")]
PointClamp,
[Display("Linear")]
LinearClamp,
[Display("Anisotropic")]
AnisotropicClamp,
// Note These values are left out on purpose, but can be included if needed
//PointWrap,
//LinearWrap,
//AnisotropicWrap,
}
public enum SpriteBlend
{
///<userdoc>No blending, the sprite is drawn as-is.</userdoc>
None,
///<userdoc>Use alpha blending if the sprite has transparent pixels, disable the blending otherwise.</userdoc>
Auto,
/// <userdoc>Use the alpha component for blending the source and sprite.</userdoc>
[Display("Alpha blend")]
AlphaBlend,
/// <userdoc>The sprite color is added to the source without using the alpha.</userdoc>
[Display("Additive blend")]
AdditiveBlend,
///<userdoc>Do not render the colors of the sprite. Renders only the depth to the stencil buffer.</userdoc>
[Display("No color")]
NoColor,
}
public class RenderSprite : RenderObject
{
// Cached states
private Matrix lastWorldMatrix;
private Vector2 lastHalfSpriteSize;
private SpriteType lastSpriteType;
private Vector2 lastSpriteCenter;
public Matrix WorldMatrix;
public float RotationEulerZ;
public Sprite Sprite;
public SpriteType SpriteType;
public bool IgnoreDepth;
public SpriteSampler Sampler;
public SpriteBlend BlendMode;
public SwizzleMode Swizzle;
public bool IsAlphaCutoff;
public bool PremultipliedAlpha;
public Color4 Color;
internal void CalculateBoundingBox()
{
// update the sprite bounding box
var halfSpriteSize = Sprite?.Size / 2 ?? Vector2.Zero;
// Only calculate if we've changed...
if (lastWorldMatrix != WorldMatrix || lastHalfSpriteSize != halfSpriteSize
|| lastSpriteType != SpriteType
+ || lastSpriteCenter != (Sprite?.Center ?? Vector2.Zero))
{
Vector3 halfBoxSize;
var boxWorldPosition = WorldMatrix.TranslationVector;
if (SpriteType == SpriteType.Billboard)
{
// Make a gross estimation here as we don't have access to the camera view matrix
// TODO: move this code or grant camera view matrix access to this processor
var maxScale = Math.Max(WorldMatrix.Row1.Length(), Math.Max(WorldMatrix.Row2.Length(), WorldMatrix.Row3.Length()));
halfBoxSize = maxScale * halfSpriteSize.Length() * Vector3.One;
}
else
{
halfBoxSize = new Vector3(
Math.Abs(WorldMatrix.M11 * halfSpriteSize.X) + Math.Abs(WorldMatrix.M21 * halfSpriteSize.Y),
Math.Abs(WorldMatrix.M12 * halfSpriteSize.X) + Math.Abs(WorldMatrix.M22 * halfSpriteSize.Y),
Math.Abs(WorldMatrix.M13 * halfSpriteSize.X) + Math.Abs(WorldMatrix.M23 * halfSpriteSize.Y));
}
// Account for Sprite.Center (pivot offset) — same logic as SpriteRenderFeature.Draw()
if (Sprite != null)
{
var sourceRegion = Sprite.Region;
var normalizedCenter = new Vector2(
Sprite.Center.X / sourceRegion.Width - 0.5f,
0.5f - Sprite.Center.Y / sourceRegion.Height);
if (Sprite.Orientation == ImageOrientation.Rotated90)
{
var oldCenterX = normalizedCenter.X;
normalizedCenter.X = -normalizedCenter.Y;
normalizedCenter.Y = oldCenterX;
}
var centerOffset = Vector2.Modulate(normalizedCenter, Sprite.SizeInternal);
boxWorldPosition -= new Vector3(
centerOffset.X * WorldMatrix.M11 + centerOffset.Y * WorldMatrix.M21,
centerOffset.X * WorldMatrix.M12 + centerOffset.Y * WorldMatrix.M22,
centerOffset.X * WorldMatrix.M13 + centerOffset.Y * WorldMatrix.M23);
}
// Update bounding box
BoundingBox = new BoundingBoxExt(boxWorldPosition - halfBoxSize, boxWorldPosition + halfBoxSize);
// Save current state for next check
lastWorldMatrix = WorldMatrix;
lastHalfSpriteSize = halfSpriteSize;
lastSpriteType = SpriteType;
lastSpriteCenter = Sprite?.Center ?? Vector2.Zero;
}
}
}
}