Kit'i 26 modele çıkar, doğrulamayı ve inceleyiciyi genişlet
Modeller (13 → 26): chest, bench, torch, lantern, bell, sign, hay bale,
sack, broom, tankard, book, phial, coin pouch. Kürek, çapa ve yaba
render'lara bakılarak yeniden yazıldı.
core:
- createKitModel artık tipli `actions` ve `update(dt)` taşıyor
- BuiltPart.extras: bir parça birden çok materyal yuvası kullanabiliyor
(sandığın kapağı = meşe tahta + demir kayış, birlikte dönmek zorunda)
- BuiltPart.origin: parça başına dönme merkezi (menteşe, sarkaç)
- bendGeometry / roughenGeometry / mottleGeometry
- 5 yeni materyal yuvası: steel, brass, straw, cloth, leather, glass
- bandGeometry({ inner }) — serbest halkalar kapalı katı olabilsin
my-registry/meta.ts: katalog metadata'sı artık build.ts ve viewer için
tek kaynak. Doğrulama modelle metadata'nın uyuştuğunu denetliyor ve bu
eklendiği gün dört modelde gerçek bir sapma yakaladı.
Doğrulama (~500 kontrol):
- metadata uyumu, eylem semantiği, kare hızı bağımsızlığı
- scripts/render.ts: tarayıcısız yazılım rasterleyici. Bütün doğrulama
geometrikti; "bu kürek küreğe benzemiyor" diyebilmek için modele
bakmak gerekiyordu
- scripts/verify-glb.ts: dışa aktar → geri oku → karşılaştır
GLB dışa aktarımı: viewer düğmesi ve toplu CLI aynı kodu kullanıyor.
Viewer:
- parça paneli (solo/izole) ve materyal yuvası paneli (canlı renk override)
- kit görünümü: 26 model tek sahnede, ölçek ve ton tutarlılığı için
- configure() sonrası gölge bayraklarının düşmesi düzeltildi
This commit is contained in:
parent
98cfbab180
commit
a3300ff233
85 changed files with 14473 additions and 1915 deletions
99
my-registry/models/wooden-fence/model.ts
Normal file
99
my-registry/models/wooden-fence/model.ts
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/**
|
||||
* @medieval-kit/wooden-fence
|
||||
*
|
||||
* Modüler çit bölümü. Kitin tek "tekrarlanabilir" parçası: `sections` alanını
|
||||
* artırarak uzatılır, ya da tek bölüm alıp sahnede kopyalanır.
|
||||
*
|
||||
* Direkler yatay kirişlerden dışa taşıyor; kirişlerin uçları direklerin içinde
|
||||
* kalıyor. İkisi de z-fighting'i yapı gereği imkânsız kılıyor.
|
||||
*/
|
||||
import { Color } from 'three'
|
||||
|
||||
import {
|
||||
chamferedBoxGeometry,
|
||||
createKitModel,
|
||||
jitter,
|
||||
MEDIEVAL_PALETTE,
|
||||
mergeColoured,
|
||||
} from '../core/index.ts'
|
||||
|
||||
export interface WoodenFenceConfig {
|
||||
/** Bölüm sayısı. Her bölüm iki direk arası. */
|
||||
readonly sections: number
|
||||
/** Bir bölümün uzunluğu (metre). */
|
||||
readonly sectionLength: number
|
||||
readonly height: number
|
||||
/** Yatay kiriş sayısı. */
|
||||
readonly railCount: number
|
||||
readonly seed: number
|
||||
}
|
||||
|
||||
export const woodenFenceDefaults: WoodenFenceConfig = {
|
||||
sections: 3,
|
||||
sectionLength: 1.6,
|
||||
height: 1.1,
|
||||
railCount: 2,
|
||||
seed: 12,
|
||||
}
|
||||
|
||||
export type WoodenFenceParts = 'posts' | 'rails'
|
||||
|
||||
export function createModel(overrides: Partial<WoodenFenceConfig> = {}) {
|
||||
return createKitModel<WoodenFenceConfig, 'oak', WoodenFenceParts>({
|
||||
id: 'wooden-fence',
|
||||
defaults: woodenFenceDefaults,
|
||||
slots: ['oak'],
|
||||
build: ({ config, random }) => {
|
||||
const tint = new Color()
|
||||
const shade = (lift = 0): Color => {
|
||||
tint.copy(MEDIEVAL_PALETTE.oak)
|
||||
tint.offsetHSL(jitter(random, 0.012), jitter(random, 0.05), lift + jitter(random, 0.06))
|
||||
return tint
|
||||
}
|
||||
|
||||
const sections = Math.max(1, config.sections)
|
||||
const post = config.height * 0.085
|
||||
const total = sections * config.sectionLength
|
||||
const half = config.height / 2
|
||||
|
||||
const posts = []
|
||||
for (let i = 0; i <= sections; i += 1) {
|
||||
const x = -total / 2 + i * config.sectionLength
|
||||
// Her direk kendi boyunda: sıra hâlinde dizildiğinde tekdüze durmasın.
|
||||
const lift = jitter(random, config.height * 0.035)
|
||||
posts.push(chamferedBoxGeometry(
|
||||
[post, post],
|
||||
[post * 0.78, post * 0.78],
|
||||
config.height + lift,
|
||||
post * 0.13,
|
||||
[x, lift / 2, 0],
|
||||
shade(-0.03),
|
||||
))
|
||||
}
|
||||
|
||||
const rails = []
|
||||
const count = Math.max(1, config.railCount)
|
||||
for (let r = 0; r < count; r += 1) {
|
||||
const t = count === 1 ? 0.55 : 0.28 + (0.5 * r) / (count - 1)
|
||||
const y = -half + t * config.height
|
||||
for (let i = 0; i < sections; i += 1) {
|
||||
const x = -total / 2 + (i + 0.5) * config.sectionLength
|
||||
// Kirişin uçları komşu direklerin ORTASINA kadar uzanır.
|
||||
rails.push(chamferedBoxGeometry(
|
||||
[config.sectionLength + post * 0.6, post * 0.5],
|
||||
[config.sectionLength + post * 0.6, post * 0.5],
|
||||
post * 0.62,
|
||||
post * 0.13,
|
||||
[x, y + jitter(random, config.height * 0.012), 0],
|
||||
shade(0.02),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
posts: { slot: 'oak', geometry: mergeColoured(posts) },
|
||||
rails: { slot: 'oak', geometry: mergeColoured(rails) },
|
||||
}
|
||||
},
|
||||
}, overrides)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue