Skip to content

Commit 3e21f5c

Browse files
committed
# 修改
generateBezierCurve 的endHandle现在是相对于target的向量 而不是相对于0,0,0 在参数输入上更加人性化 # 支持 贝塞尔值曲线控制粒子组缩放
1 parent ea173b4 commit 3e21f5c

8 files changed

Lines changed: 215 additions & 47 deletions

File tree

src/main/kotlin/cn/coostack/cooparticlesapi/network/particle/style/ParticleShapeStyle.kt

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import cn.coostack.cooparticlesapi.network.buffer.ParticleControlerDataBuffer
44
import cn.coostack.cooparticlesapi.particles.ParticleDisplayer
55
import cn.coostack.cooparticlesapi.utils.RelativeLocation
66
import cn.coostack.cooparticlesapi.utils.builder.PointsBuilder
7+
import cn.coostack.cooparticlesapi.utils.helper.ScaleHelper
8+
import cn.coostack.cooparticlesapi.utils.helper.impl.StyleBezierValueScaleHelper
79
import cn.coostack.cooparticlesapi.utils.helper.impl.StyleScaleHelper
810
import net.minecraft.client.particle.ParticleTextureSheet
911
import net.minecraft.entity.player.PlayerEntity
@@ -21,7 +23,7 @@ import java.util.UUID
2123
*/
2224
open class ParticleShapeStyle(uuid: UUID) :
2325
ParticleGroupStyle(64.0, uuid) {
24-
val scaleHelper = StyleScaleHelper(1.0, 1.0, 1)
26+
var scaleHelper: ScaleHelper? = null
2527
private var onDisplayInvoke: ParticleShapeStyle.() -> Unit = {}
2628
private var beforeDisplayInvoke: ParticleShapeStyle.(Map<StyleData, RelativeLocation>) -> Unit = {}
2729
private val pointBuilders = LinkedHashMap<PointsBuilder, (RelativeLocation) -> StyleData>()
@@ -54,20 +56,31 @@ open class ParticleShapeStyle(uuid: UUID) :
5456
* @param max 直接让scale从最大开始
5557
*/
5658
fun scaleReversed(max: Boolean): ParticleShapeStyle {
59+
scaleHelper ?: return this
5760
scaleReversed = true
5861
if (max) {
59-
scaleHelper.toggleScale(scaleHelper.maxScale)
62+
scaleHelper!!.toggleScale(scaleHelper!!.maxScale)
6063
}
6164
return this
6265
}
6366

6467
fun loadScaleHelper(minScale: Double, maxScale: Double, scaleTick: Int): ParticleShapeStyle {
65-
scaleHelper.minScale = minScale
66-
scaleHelper.maxScale = maxScale
67-
scaleHelper.scaleTick = scaleTick
68+
scaleHelper = StyleScaleHelper(minScale, maxScale, scaleTick)
6869
scalePreTick = true
69-
scaleHelper.loadControler(this)
70-
scaleHelper.recalculateStep()
70+
scaleHelper!!.loadControler(this)
71+
return this
72+
}
73+
74+
fun loadScaleHelperBezierValue(
75+
minScale: Double,
76+
maxScale: Double,
77+
scaleTick: Int,
78+
c1: RelativeLocation,
79+
c2: RelativeLocation
80+
): ParticleShapeStyle {
81+
scaleHelper = StyleBezierValueScaleHelper(scaleTick, minScale, maxScale, c1, c2)
82+
scalePreTick = true
83+
scaleHelper!!.loadControler(this)
7184
return this
7285
}
7386

@@ -102,14 +115,14 @@ open class ParticleShapeStyle(uuid: UUID) :
102115
override fun onDisplay() {
103116
onDisplayInvoke()
104117
addPreTickAction {
105-
if (!scalePreTick) {
118+
if (!scalePreTick || scaleHelper == null) {
106119
return@addPreTickAction
107120
}
108121

109122
if (scaleReversed) {
110-
scaleHelper.doScaleReversed()
123+
scaleHelper!!.doScaleReversed()
111124
} else {
112-
scaleHelper.doScale()
125+
scaleHelper!!.doScale()
113126
}
114127
}
115128
}

src/main/kotlin/cn/coostack/cooparticlesapi/utils/Math3DUtil.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,12 +594,21 @@ object Math3DUtil {
594594
*/
595595
fun generateBezierCurve(
596596
target: RelativeLocation,
597+
/**
598+
* 起点的曲柄向量
599+
*/
597600
startHandle: RelativeLocation,
601+
/**
602+
* 终点的曲柄向量 (以 target为原点)
603+
* 在Pr ae的速度,值曲线的下一个关键帧曲柄中
604+
* 方向和startHandle相反
605+
* 因此这里也要相反
606+
*/
598607
endHandle: RelativeLocation,
599608
count: Int
600609
): List<RelativeLocation> {
601610
require(count >= 1) { "Number of points must be at least 1" }
602-
611+
val end = target + endHandle
603612
return List(count) { i ->
604613
val t = when (count) {
605614
1 -> 1.0
@@ -613,12 +622,12 @@ object Math3DUtil {
613622
// 三次贝塞尔曲线公式
614623
val x = (u2 * u * 0.0) + // P0 (0,0)
615624
(3 * u2 * t * startHandle.x) + // P1 control point
616-
(3 * u * t2 * endHandle.x) + // P2 control point
625+
(3 * u * t2 * end.x) + // P2 control point
617626
(t2 * t * target.x) // P3 (end point)
618627

619628
val y = (u2 * u * 0.0) +
620629
(3 * u2 * t * startHandle.y) +
621-
(3 * u * t2 * endHandle.y) +
630+
(3 * u * t2 * end.y) +
622631
(t2 * t * target.y)
623632

624633
RelativeLocation(x, y, 0.0)
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package cn.coostack.cooparticlesapi.utils.helper
2+
3+
import cn.coostack.cooparticlesapi.utils.Math3DUtil
4+
import cn.coostack.cooparticlesapi.utils.RelativeLocation
5+
import kotlin.math.abs
6+
import kotlin.math.max
7+
import kotlin.math.min
8+
9+
abstract class BezierValueScaleHelper(
10+
scaleTick: Int,
11+
minScale: Double,
12+
maxScale: Double,
13+
var controlPoint1: RelativeLocation,
14+
var controlPoint2: RelativeLocation
15+
) :
16+
ScaleHelper(minScale, maxScale, scaleTick) {
17+
private val deltaScale = maxScale - minScale
18+
19+
var bezierPoints = Math3DUtil.generateBezierCurve(
20+
RelativeLocation(scaleTick.toDouble(), deltaScale, 0.0),
21+
controlPoint1, controlPoint2, scaleTick
22+
)
23+
24+
override fun recalculateStep(): BezierValueScaleHelper {
25+
val temp = min(minScale, maxScale)
26+
maxScale = max(minScale, maxScale)
27+
minScale = temp
28+
bezierPoints = Math3DUtil.generateBezierCurve(
29+
RelativeLocation(scaleTick.toDouble(), deltaScale, 0.0),
30+
controlPoint1, controlPoint2, scaleTick
31+
)
32+
return this
33+
}
34+
35+
override fun toggleScale(scale: Double) {
36+
// 遍历scale?
37+
val currentPoint = bezierPoints.withIndex().minBy {
38+
abs(it.value.y - scale)
39+
}
40+
current = currentPoint.index
41+
scale(minScale + currentPoint.value.y)
42+
}
43+
44+
override fun doScale() {
45+
if (getLoadedGroup() == null) return
46+
if (over()) return
47+
val value = bezierPoints[current++].y
48+
scale(minScale + value)
49+
}
50+
51+
override fun doScaleTo(current: Int) {
52+
val enter = current.coerceAtLeast(0)
53+
this.current = enter
54+
if (current >= scaleTick) {
55+
resetScaleMax()
56+
return
57+
}
58+
if (current <= 0) {
59+
resetScaleMin()
60+
return
61+
}
62+
val value = bezierPoints[current].y
63+
scale(minScale + value)
64+
}
65+
66+
override fun doScaleReversed() {
67+
if (getLoadedGroup() == null) {
68+
return
69+
}
70+
if (isZero()) {
71+
return
72+
}
73+
val value = bezierPoints[current--].y
74+
scale(minScale + value)
75+
}
76+
}

src/main/kotlin/cn/coostack/cooparticlesapi/utils/helper/HelperUtil.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package cn.coostack.cooparticlesapi.utils.helper
22

3+
import cn.coostack.cooparticlesapi.utils.RelativeLocation
4+
import cn.coostack.cooparticlesapi.utils.helper.impl.GroupBezierValueScaleHelper
35
import cn.coostack.cooparticlesapi.utils.helper.impl.GroupProgressSequencedHelper
46
import cn.coostack.cooparticlesapi.utils.helper.impl.GroupScaleHelper
57
import cn.coostack.cooparticlesapi.utils.helper.impl.ParticleAlphaHelper
68
import cn.coostack.cooparticlesapi.utils.helper.impl.StyleAlphaHelper
9+
import cn.coostack.cooparticlesapi.utils.helper.impl.StyleBezierValueScaleHelper
710
import cn.coostack.cooparticlesapi.utils.helper.impl.StyleProgressSequencedHelper
811
import cn.coostack.cooparticlesapi.utils.helper.impl.StyleScaleHelper
912
import cn.coostack.cooparticlesapi.utils.helper.impl.StyleStatusHelper
@@ -25,6 +28,25 @@ object HelperUtil {
2528
fun scaleStyle(minScale: Double, maxScale: Double, scaleTick: Int): ScaleHelper =
2629
StyleScaleHelper(minScale, maxScale, scaleTick)
2730

31+
fun bezierValueScaleStyle(
32+
minScale: Double,
33+
maxScale: Double,
34+
scaleTick: Int,
35+
c1: RelativeLocation,
36+
c2: RelativeLocation
37+
): BezierValueScaleHelper {
38+
return StyleBezierValueScaleHelper(scaleTick, minScale, maxScale, c1, c2)
39+
}
40+
fun bezierValueScaleGroup(
41+
minScale: Double,
42+
maxScale: Double,
43+
scaleTick: Int,
44+
c1: RelativeLocation,
45+
c2: RelativeLocation
46+
): BezierValueScaleHelper {
47+
return GroupBezierValueScaleHelper(scaleTick, minScale, maxScale, c1, c2)
48+
}
49+
2850
fun scaleGroup(minScale: Double, maxScale: Double, scaleTick: Int): ScaleHelper =
2951
GroupScaleHelper(minScale, maxScale, scaleTick)
3052

src/main/kotlin/cn/coostack/cooparticlesapi/utils/helper/ScaleHelper.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ abstract class ScaleHelper(var minScale: Double, var maxScale: Double, var scale
5353
if (getLoadedGroup() == null) {
5454
return
5555
}
56-
current = scaleTick
56+
current = scaleTick - 1
5757
scale(maxScale)
5858
}
5959

@@ -63,7 +63,7 @@ abstract class ScaleHelper(var minScale: Double, var maxScale: Double, var scale
6363
}
6464
val enter = current.coerceAtLeast(0)
6565
this.current = enter
66-
if (current >= scaleTick) {
66+
if (current >= scaleTick - 1) {
6767
resetScaleMax()
6868
return
6969
}
@@ -96,7 +96,7 @@ abstract class ScaleHelper(var minScale: Double, var maxScale: Double, var scale
9696
scale(getGroupScale() - step)
9797
}
9898

99-
fun over(): Boolean = scaleTick <= current
99+
open fun over(): Boolean = scaleTick - 1 <= current
100100
fun isZero(): Boolean = current <= 0
101101

102102
abstract fun getLoadedGroup(): Controlable<*>?

src/main/kotlin/cn/coostack/cooparticlesapi/utils/helper/impl/BezierValueScaleHelper.kt

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package cn.coostack.cooparticlesapi.utils.helper.impl
2+
3+
import cn.coostack.cooparticlesapi.network.particle.style.ParticleGroupStyle
4+
import cn.coostack.cooparticlesapi.particles.Controlable
5+
import cn.coostack.cooparticlesapi.particles.control.group.ControlableParticleGroup
6+
import cn.coostack.cooparticlesapi.utils.RelativeLocation
7+
import cn.coostack.cooparticlesapi.utils.helper.BezierValueScaleHelper
8+
9+
class GroupBezierValueScaleHelper(
10+
scaleTick: Int,
11+
minScale: Double,
12+
maxScale: Double,
13+
controlPoint1: RelativeLocation,
14+
controlPoint2: RelativeLocation
15+
) :
16+
BezierValueScaleHelper(scaleTick, minScale, maxScale, controlPoint1, controlPoint2) {
17+
lateinit var group: ControlableParticleGroup
18+
override fun loadControler(controler: Controlable<*>) {
19+
if (controler !is ControlableParticleGroup) {
20+
return
21+
}
22+
group = controler
23+
group.scale(minScale)
24+
}
25+
26+
override fun getLoadedGroup(): Controlable<*>? {
27+
if (!::group.isInitialized) {
28+
return null
29+
}
30+
return group
31+
}
32+
33+
override fun getGroupScale(): Double {
34+
return group.scale
35+
}
36+
37+
override fun scale(scale: Double) {
38+
group.scale(scale.coerceIn(minScale, maxScale))
39+
}
40+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package cn.coostack.cooparticlesapi.utils.helper.impl
2+
3+
import cn.coostack.cooparticlesapi.network.particle.style.ParticleGroupStyle
4+
import cn.coostack.cooparticlesapi.particles.Controlable
5+
import cn.coostack.cooparticlesapi.utils.RelativeLocation
6+
import cn.coostack.cooparticlesapi.utils.helper.BezierValueScaleHelper
7+
8+
class StyleBezierValueScaleHelper(
9+
scaleTick: Int,
10+
minScale: Double,
11+
maxScale: Double,
12+
controlPoint1: RelativeLocation,
13+
controlPoint2: RelativeLocation
14+
) :
15+
BezierValueScaleHelper(scaleTick, minScale, maxScale, controlPoint1, controlPoint2) {
16+
lateinit var group: ParticleGroupStyle
17+
override fun loadControler(controler: Controlable<*>) {
18+
if (controler !is ParticleGroupStyle) {
19+
return
20+
}
21+
group = controler
22+
group.scale(minScale)
23+
}
24+
25+
override fun getLoadedGroup(): Controlable<*>? {
26+
if (!::group.isInitialized) {
27+
return null
28+
}
29+
return group
30+
}
31+
32+
override fun getGroupScale(): Double {
33+
return group.scale
34+
}
35+
36+
override fun scale(scale: Double) {
37+
group.scale(scale.coerceIn(minScale, maxScale))
38+
}
39+
}

0 commit comments

Comments
 (0)