Fixed bug in Ninja geometry mesh caching and improved Ninja to Three.js conversion performance.

This commit is contained in:
Daan Vanden Bosch 2021-04-09 22:12:28 +02:00
parent 6003797f15
commit 126b50cb00
3 changed files with 25 additions and 13 deletions

View File

@ -3,7 +3,9 @@ package world.phantasmal.web.core.rendering.conversion
import org.khronos.webgl.Float32Array import org.khronos.webgl.Float32Array
import org.khronos.webgl.Uint16Array import org.khronos.webgl.Uint16Array
import org.khronos.webgl.set import org.khronos.webgl.set
import world.phantasmal.core.JsMap
import world.phantasmal.core.asArray import world.phantasmal.core.asArray
import world.phantasmal.core.emptyJsMap
import world.phantasmal.core.jsArrayOf import world.phantasmal.core.jsArrayOf
import world.phantasmal.lib.fileFormats.ninja.XvrTexture import world.phantasmal.lib.fileFormats.ninja.XvrTexture
import world.phantasmal.web.externals.three.* import world.phantasmal.web.externals.three.*
@ -11,7 +13,7 @@ import world.phantasmal.webui.obj
class MeshBuilder( class MeshBuilder(
private val textures: List<XvrTexture?> = emptyList(), private val textures: List<XvrTexture?> = emptyList(),
private val textureCache: MutableMap<Int, Texture?> = mutableMapOf(), private val textureCache: JsMap<Int, Texture?> = emptyJsMap(),
) { ) {
private val positions = mutableListOf<Vector3>() private val positions = mutableListOf<Vector3>()
private val normals = mutableListOf<Vector3>() private val normals = mutableListOf<Vector3>()
@ -189,11 +191,16 @@ class MeshBuilder(
indices.set(group.indices.asArray(), offset) indices.set(group.indices.asArray(), offset)
geom.addGroup(offset, group.indices.length, materials.size) geom.addGroup(offset, group.indices.length, materials.size)
val tex = group.textureIndex?.let { texIndex -> var tex: Texture? = null
textureCache.getOrPut(texIndex) {
textures.getOrNull(texIndex)?.let { xvm -> if (group.textureIndex != null) {
textureCache.get(group.textureIndex)
if (tex == null) {
tex = textures.getOrNull(group.textureIndex)?.let { xvm ->
xvrTextureToThree(xvm) xvrTextureToThree(xvm)
} }
textureCache.set(group.textureIndex, tex)
} }
} }

View File

@ -3,10 +3,7 @@ package world.phantasmal.web.core.rendering.conversion
import mu.KotlinLogging import mu.KotlinLogging
import org.khronos.webgl.Float32Array import org.khronos.webgl.Float32Array
import org.khronos.webgl.Uint16Array import org.khronos.webgl.Uint16Array
import world.phantasmal.core.JsArray import world.phantasmal.core.*
import world.phantasmal.core.asArray
import world.phantasmal.core.isBitSet
import world.phantasmal.core.jsArrayOf
import world.phantasmal.lib.fileFormats.CollisionGeometry import world.phantasmal.lib.fileFormats.CollisionGeometry
import world.phantasmal.lib.fileFormats.CollisionTriangle import world.phantasmal.lib.fileFormats.CollisionTriangle
import world.phantasmal.lib.fileFormats.RenderGeometry import world.phantasmal.lib.fileFormats.RenderGeometry
@ -129,8 +126,8 @@ fun renderGeometryToGroup(
processMesh: (RenderSection, XjObject, Mesh) -> Unit = { _, _, _ -> }, processMesh: (RenderSection, XjObject, Mesh) -> Unit = { _, _, _ -> },
): Group { ): Group {
val group = Group() val group = Group()
val textureCache = mutableMapOf<Int, Texture?>() val textureCache = emptyJsMap<Int, Texture?>()
val meshCache = mutableMapOf<XjObject, Mesh>() val meshCache = emptyJsMap<XjObject, Mesh>()
for ((i, section) in renderGeometry.sections.withIndex()) { for ((i, section) in renderGeometry.sections.withIndex()) {
for (xjObj in section.objects) { for (xjObj in section.objects) {
@ -151,14 +148,14 @@ fun renderGeometryToGroup(
private fun xjObjectToMesh( private fun xjObjectToMesh(
textures: List<XvrTexture?>, textures: List<XvrTexture?>,
textureCache: MutableMap<Int, Texture?>, textureCache: JsMap<Int, Texture?>,
meshCache: MutableMap<XjObject, Mesh>, meshCache: JsMap<XjObject, Mesh>,
xjObj: XjObject, xjObj: XjObject,
index: Int, index: Int,
section: RenderSection, section: RenderSection,
processMesh: (RenderSection, XjObject, Mesh) -> Unit, processMesh: (RenderSection, XjObject, Mesh) -> Unit,
): Mesh { ): Mesh {
var mesh = meshCache[xjObj] var mesh = meshCache.get(xjObj)
if (mesh == null) { if (mesh == null) {
val builder = MeshBuilder(textures, textureCache) val builder = MeshBuilder(textures, textureCache)
@ -172,6 +169,7 @@ private fun xjObjectToMesh(
})) }))
mesh = builder.buildMesh(boundingVolumes = true) mesh = builder.buildMesh(boundingVolumes = true)
meshCache.set(xjObj, mesh)
} else { } else {
// If we already have a mesh for this XjObject, make a copy and reuse the existing buffer // If we already have a mesh for this XjObject, make a copy and reuse the existing buffer
// geometry and materials. // geometry and materials.

View File

@ -494,7 +494,13 @@ external class Color() {
constructor(color: String) constructor(color: String)
constructor(color: Int) constructor(color: Int)
fun set(color: Color): Color
fun set(color: String): Color
fun set(color: Int): Color
fun setHSL(h: Double, s: Double, l: Double): Color fun setHSL(h: Double, s: Double, l: Double): Color
fun clone(): Color
} }
open external class BufferGeometry : EventDispatcher { open external class BufferGeometry : EventDispatcher {
@ -602,6 +608,7 @@ external interface MeshBasicMaterialParameters : MaterialParameters {
external class MeshBasicMaterial( external class MeshBasicMaterial(
parameters: MeshBasicMaterialParameters = definedExternally, parameters: MeshBasicMaterialParameters = definedExternally,
) : Material { ) : Material {
var color: Color
var map: Texture? var map: Texture?
} }