@@ -11,40 +11,30 @@ import org.joml.Vector3f
1111import top.fifthlight.blazerod.BlazeRod
1212import top.fifthlight.blazerod.model.data.ModelMatricesBuffer
1313import top.fifthlight.blazerod.model.data.RenderSkinBuffer
14- import top.fifthlight.blazerod.model.data.RenderTargetBuffer
14+ import top.fifthlight.blazerod.model.data.MorphTargetBuffer
1515import top.fifthlight.blazerod.util.AbstractRefCount
16+ import top.fifthlight.blazerod.util.CowBuffer
17+ import top.fifthlight.blazerod.util.CowBufferList
18+ import top.fifthlight.blazerod.util.copy
1619import top.fifthlight.blazerod.util.mapToArray
1720import top.fifthlight.blazerod.util.mapToArrayIndexed
1821import java.util.function.Consumer
1922
20- class ModelInstance (
21- val scene : RenderScene ,
22- bufferEntry : ModelBufferManager .BufferEntry ,
23- ) : AbstractRefCount() {
23+ class ModelInstance (val scene : RenderScene ) : AbstractRefCount() {
2424 companion object {
2525 private val TYPE_ID = Identifier .of(" blazerod" , " model_instance" )
2626 }
2727
2828 override val typeId: Identifier
2929 get() = TYPE_ID
3030
31- val modelData = ModelData (
32- scene = scene,
33- bufferEntry = bufferEntry,
34- )
31+ val modelData = ModelData (scene)
3532
3633 init {
3734 scene.increaseReferenceCount()
3835 }
3936
40- class ModelData (
41- scene : RenderScene ,
42- private val bufferEntry : ModelBufferManager .BufferEntry ,
43- ) : AutoCloseable {
44- init {
45- bufferEntry.increaseReferenceCount()
46- }
47-
37+ class ModelData (scene : RenderScene ) : AutoCloseable {
4838 val defaultTransforms = scene.transformNodeIndices.mapToArray { nodeIndex ->
4939 val node = scene.nodes[nodeIndex] as RenderNode .Transform
5040 node.defaultTransform?.clone()
@@ -56,46 +46,41 @@ class ModelInstance(
5646
5747 val transformsDirty = Array (scene.transformNodeIndices.size) { true }
5848
59- val modelMatricesBuffer = ModelMatricesBuffer (scene, bufferEntry.modelMatricesBuffers.allocateSlot()).also {
60- it.clear()
49+ val modelMatricesBuffer = run {
50+ val buffer = ModelMatricesBuffer (scene)
51+ buffer.clear()
52+ CowBuffer .acquire(buffer).also { it.increaseReferenceCount() }
6153 }
6254
63- val skinBuffers = scene.skins.mapToArrayIndexed { index, skin ->
64- RenderSkinBuffer (skin, bufferEntry.skinBuffers[index].allocateSlot()). also {
65- it .clear()
66- }
55+ val skinBuffers = scene.skins.mapIndexed { index, skin ->
56+ val skinBuffer = RenderSkinBuffer (skin)
57+ skinBuffer .clear()
58+ CowBuffer .acquire(skinBuffer). also { it.increaseReferenceCount() }
6759 }
6860
69- val targetBuffers = scene.morphedPrimitiveNodeIndices.mapToArrayIndexed { index, nodeIndex ->
61+ val targetBuffers = scene.morphedPrimitiveNodeIndices.mapIndexed { index, nodeIndex ->
7062 val node = scene.nodes[nodeIndex] as RenderNode .Primitive
7163 val primitive = node.primitive
7264 val targets = primitive.targets!!
73- val targetBuffers = RenderTargetBuffer (
74- targets = targets,
75- weightsSlot = bufferEntry.morphWeightBuffers[index].allocateSlot(),
76- indicesSlot = bufferEntry.morphIndicesBuffers[index].allocateSlot(),
77- )
65+ val targetBuffers = MorphTargetBuffer (targets)
7866 for (targetGroup in primitive.targetGroups) {
79- fun processGroup (index : Int? , channel : RenderTargetBuffer .WeightChannel , weight : Float ) =
67+ fun processGroup (index : Int? , channel : MorphTargetBuffer .WeightChannel , weight : Float ) =
8068 index?.let {
8169 channel[index] = weight
8270 }
8371 processGroup(targetGroup.position, targetBuffers.positionChannel, targetGroup.weight)
8472 processGroup(targetGroup.color, targetBuffers.colorChannel, targetGroup.weight)
8573 processGroup(targetGroup.texCoord, targetBuffers.texCoordChannel, targetGroup.weight)
8674 }
87- targetBuffers
75+ CowBuffer .acquire( targetBuffers). also { it.increaseReferenceCount() }
8876 }
8977
90- val cameraTransforms = scene.cameras.mapToArray { CameraTransform (it.camera) }
78+ val cameraTransforms = scene.cameras.map { CameraTransform (it.camera) }
9179
9280 override fun close () {
93- // release slots
94- modelMatricesBuffer.close()
95- skinBuffers.forEach { it.close() }
96- targetBuffers.forEach { it.close() }
97- // release underlying slot buffer
98- bufferEntry.decreaseReferenceCount()
81+ modelMatricesBuffer.decreaseReferenceCount()
82+ skinBuffers.forEach { it.decreaseReferenceCount() }
83+ targetBuffers.forEach { it.decreaseReferenceCount() }
9984 }
10085 }
10186
@@ -190,9 +175,11 @@ class ModelInstance(
190175 val weightsIndex =
191176 requireNotNull(node.morphedPrimitiveIndex) { " Node $nodeIndex don't have target? Check model loader" }
192177 val weights = modelData.targetBuffers[weightsIndex]
193- group.position?.let { weights.positionChannel[it] = weight }
194- group.color?.let { weights.colorChannel[it] = weight }
195- group.texCoord?.let { weights.texCoordChannel[it] = weight }
178+ weights.edit {
179+ group.position?.let { positionChannel[it] = weight }
180+ group.color?.let { colorChannel[it] = weight }
181+ group.texCoord?.let { texCoordChannel[it] = weight }
182+ }
196183 }
197184
198185 private val updateMatrixStack = Matrix4fStack (BlazeRod .MAX_TRANSFORM_DEPTH )
@@ -210,13 +197,29 @@ class ModelInstance(
210197 }
211198
212199 fun render (modelViewMatrix : Matrix4fc , light : Int ) {
213- scene.render(this , modelViewMatrix, light)
200+ // Upload indices don't change the actual data
201+ modelData.targetBuffers.forEach { it.content.uploadIndices() }
202+ scene.render(
203+ modelViewMatrix = modelViewMatrix,
204+ light = light,
205+ modelMatricesBuffer = modelData.modelMatricesBuffer.content,
206+ skinBuffer = CowBufferList (modelData.skinBuffers),
207+ morphTargetBuffer = CowBufferList (modelData.targetBuffers),
208+ )
214209 }
215210
216- fun schedule (modelViewMatrix : Matrix4fc , light : Int ) = RenderTask . Instance .acquire(
211+ fun schedule (modelViewMatrix : Matrix4fc , light : Int ): RenderTask = RenderTask .acquire(
217212 instance = this ,
218213 modelViewMatrix = modelViewMatrix,
219214 light = light,
215+ modelMatricesBuffer = modelData.modelMatricesBuffer.copy(),
216+ skinBuffer = modelData.skinBuffers.copy(),
217+ morphTargetBuffer = modelData.targetBuffers.copy().also { buffer ->
218+ // Upload indices don't change the actual data
219+ buffer.forEach {
220+ it.content.uploadIndices()
221+ }
222+ },
220223 )
221224
222225 override fun onClosed () {
0 commit comments