Adjust materials for 3D

This commit is contained in:
Alexander Nozik 2024-01-01 15:54:29 +03:00
parent 067ed4aa3d
commit 58d7bd9383
8 changed files with 62 additions and 19 deletions

View File

@ -8,6 +8,16 @@ kscience {
jvm() jvm()
js{ js{
binaries.executable() binaries.executable()
browser{
commonWebpackConfig{
cssSupport{
enabled = true
}
scssSupport{
enabled = true
}
}
}
} }
dependencies { dependencies {
implementation(projects.visionforgeSolid) implementation(projects.visionforgeSolid)

View File

@ -24,6 +24,11 @@ fun VisionLayout<Solid>.demo(name: String, title: String = name, block: SolidGro
block() block()
ambientLight { ambientLight {
color(Colors.white) color(Colors.white)
intensity = 0.5
}
pointLight(0, 0, 1000) {
color(Colors.white)
intensity = 10.0
} }
} }
render(Name.parse(name), vision, meta) render(Name.parse(name), vision, meta)
@ -111,7 +116,7 @@ fun VisionLayout<Solid>.showcase() {
GlobalScope.launch(Dispatchers.Main) { GlobalScope.launch(Dispatchers.Main) {
while (isActive) { while (isActive) {
delay(100) delay(100)
rotate((PI/20).radians,Euclidean3DSpace.yAxis) rotate((PI / 20).radians, Euclidean3DSpace.yAxis)
} }
} }
color(Colors.red) color(Colors.red)
@ -122,13 +127,16 @@ fun VisionLayout<Solid>.showcase() {
demo("extrude", "extruded shape") { demo("extrude", "extruded shape") {
extruded { extruded {
shape { shape {
polygon(8, 50) polygon(32, 50)
} }
for (i in 0..100) { for (i in 0..100) {
layer(i * 5, 20 * sin(2 * PI / 100 * i), 20 * cos(2 * PI / 100 * i)) layer(i * 5, 20 * sin(2 * PI / 100 * i), 20 * cos(2 * PI / 100 * i))
} }
color(Colors.teal) rotationY = -PI / 2
rotationX = -PI / 2 material {
type = "lambert"
color(Colors.teal)
}
} }
} }
@ -161,7 +169,15 @@ fun VisionLayout<Solid>.showcase() {
} }
demo("STL", "STL loaded from URL") { demo("STL", "STL loaded from URL") {
stl("https://ozeki.hu/attachments/116/Menger_sponge_sample.stl") stl("Menger_sponge_sample.stl") {
scale(100f)
material {
type = "phong"
color("red")
specularColor("blue")
}
}
//stl("https://ozeki.hu/attachments/116/Menger_sponge_sample.stl")
} }
} }

View File

@ -203,6 +203,10 @@ public var Solid.position: Float32Vector3D? by float32Vector(POSITION_KEY, 0f)
public var Solid.rotation: Float32Vector3D? by float32Vector(ROTATION_KEY, 0f) public var Solid.rotation: Float32Vector3D? by float32Vector(ROTATION_KEY, 0f)
public var Solid.scale: Float32Vector3D? by float32Vector(SCALE_KEY, 1f) public var Solid.scale: Float32Vector3D? by float32Vector(SCALE_KEY, 1f)
public fun Solid.scale(scaleFactor: Number) {
scale = Float32Vector3D(scaleFactor, scaleFactor, scaleFactor)
}
public var Solid.x: Number by float32(X_POSITION_KEY, 0f) public var Solid.x: Number by float32(X_POSITION_KEY, 0f)
public var Solid.y: Number by float32(Y_POSITION_KEY, 0f) public var Solid.y: Number by float32(Y_POSITION_KEY, 0f)
public var Solid.z: Number by float32(Z_POSITION_KEY, 0f) public var Solid.z: Number by float32(Z_POSITION_KEY, 0f)
@ -255,5 +259,5 @@ public var Solid.scaleZ: Number by float32(Z_SCALE_KEY, 1f)
* Add rotation with given [angle] relative to given [axis] * Add rotation with given [angle] relative to given [axis]
*/ */
public fun Solid.rotate(angle: Angle, axis: DoubleVector3D): Unit = with(QuaternionField) { public fun Solid.rotate(angle: Angle, axis: DoubleVector3D): Unit = with(QuaternionField) {
quaternion = Quaternion.fromRotation(angle, axis)*quaternion quaternion = Quaternion.fromRotation(angle, axis) * quaternion
} }

View File

@ -18,6 +18,8 @@ import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_OPACITY
@VisionBuilder @VisionBuilder
public class SolidMaterial : Scheme() { public class SolidMaterial : Scheme() {
public var type: String by string("default", key = TYPE_KEY)
/** /**
* Primary web-color for the material * Primary web-color for the material
*/ */
@ -65,9 +67,9 @@ public class SolidMaterial : Scheme() {
MetaDescriptor { MetaDescriptor {
inherited = true inherited = true
value(TYPE_KEY, ValueType.STRING){ value(TYPE_KEY, ValueType.STRING) {
inherited = true inherited = true
allowedValues = listOf("default".asValue(), "simple".asValue()) allowedValues = listOf("default", "basic", "lambert", "phong").map { it.asValue() }
default("default") default("default")
} }

View File

@ -10,10 +10,7 @@ import space.kscience.visionforge.getStyleNodes
import space.kscience.visionforge.solid.ColorAccessor import space.kscience.visionforge.solid.ColorAccessor
import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.SolidMaterial
import space.kscience.visionforge.solid.SolidReference import space.kscience.visionforge.solid.SolidReference
import three.materials.LineBasicMaterial import three.materials.*
import three.materials.Material
import three.materials.MeshBasicMaterial
import three.materials.MeshStandardMaterial
import three.math.Color import three.math.Color
import three.objects.Mesh import three.objects.Mesh
@ -56,11 +53,23 @@ public object ThreeMaterials {
} }
internal fun buildMaterial(meta: Meta): Material = when (meta[SolidMaterial.TYPE_KEY]?.string) { internal fun buildMaterial(meta: Meta): Material = when (meta[SolidMaterial.TYPE_KEY]?.string) {
"simple" -> MeshBasicMaterial().apply { "basic" -> MeshBasicMaterial().apply {
color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR
wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false
} }
"lambert" -> MeshLambertMaterial().apply {
color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR
emissive = meta[SolidMaterial.EMISSIVE_COLOR_KEY]?.threeColor() ?: DEFAULT_EMISSIVE_COLOR
wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false
}
"phong" -> MeshPhongMaterial().apply {
color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR
emissive = meta[SolidMaterial.EMISSIVE_COLOR_KEY]?.threeColor() ?: DEFAULT_EMISSIVE_COLOR
wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false
}
else -> MeshStandardMaterial().apply { else -> MeshStandardMaterial().apply {
color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR
emissive = meta[SolidMaterial.EMISSIVE_COLOR_KEY]?.threeColor() ?: DEFAULT_EMISSIVE_COLOR emissive = meta[SolidMaterial.EMISSIVE_COLOR_KEY]?.threeColor() ?: DEFAULT_EMISSIVE_COLOR

View File

@ -44,16 +44,15 @@ public class ThreePlugin : AbstractPlugin(), ComposeVisionRenderer {
objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory
objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory
objectFactories[PointLightSource::class] = ThreePointLightFactory objectFactories[PointLightSource::class] = ThreePointLightFactory
objectFactories[StlSolid::class] = ThreeStlFactory objectFactories[StlUrlSolid::class] = ThreeStlFactory
objectFactories[StlBinarySolid::class] = ThreeStlFactory
objectFactories[AxesSolid::class] = ThreeAxesFactory objectFactories[AxesSolid::class] = ThreeAxesFactory
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
private fun findObjectFactory(type: KClass<out Vision>): ThreeFactory<Solid>? { private fun findObjectFactory(type: KClass<out Vision>): ThreeFactory<Solid>? =
return (objectFactories[type] (objectFactories[type] ?: context.gather<ThreeFactory<*>>(ThreeFactory.TYPE).values.find { it.type == type })
?: context.gather<ThreeFactory<*>>(ThreeFactory.TYPE).values.find { it.type == type })
as ThreeFactory<Solid>? as ThreeFactory<Solid>?
}
/** /**
* Build an Object3D representation of the given [Solid]. * Build an Object3D representation of the given [Solid].

View File

@ -16,7 +16,9 @@ fun ArrayBuffer.toByteArray(): ByteArray = Int8Array(this).unsafeCast<ByteArray>
public object ThreeStlFactory : ThreeMeshFactory<StlSolid>(StlSolid::class) { public object ThreeStlFactory : ThreeMeshFactory<StlSolid>(StlSolid::class) {
private val loader = STLLoader().apply { private val loader = STLLoader().apply {
requestHeader = listOf("Access-Control-Allow-Origin: *") requestHeader = listOf(
"Access-Control-Allow-Origin: *",
)
} }
override suspend fun buildGeometry(obj: StlSolid): BufferGeometry = when (obj) { override suspend fun buildGeometry(obj: StlSolid): BufferGeometry = when (obj) {
@ -25,6 +27,7 @@ public object ThreeStlFactory : ThreeMeshFactory<StlSolid>(StlSolid::class) {
loader.load( loader.load(
url = obj.url, url = obj.url,
onLoad = { onLoad = {
console.info("Loaded STL from ${obj.url}")
continuation.resume(it) continuation.resume(it)
}, },
onError = { onError = {