Skip to content

Commit 4d7e3df

Browse files
authored
feat: Item projectiles support (#395)
1 parent a498778 commit 4d7e3df

File tree

3 files changed

+50
-38
lines changed

3 files changed

+50
-38
lines changed

pnpm-lock.yaml

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

renderer/viewer/three/entities.ts

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ export class Entities {
717717
return typeof component === 'string' ? component : component.text ?? ''
718718
}
719719

720-
getItemMesh (item, specificProps: ItemSpecificContextProperties, previousModel?: string) {
720+
getItemMesh (item, specificProps: ItemSpecificContextProperties, faceCamera = false, previousModel?: string) {
721721
if (!item.nbt && item.nbtData) item.nbt = item.nbtData
722722
const textureUv = this.worldRenderer.getItemRenderData(item, specificProps)
723723
if (previousModel && previousModel === textureUv?.modelName) return undefined
@@ -757,26 +757,37 @@ export class Entities {
757757
itemsTexture.needsUpdate = true
758758
itemsTexture.magFilter = THREE.NearestFilter
759759
itemsTexture.minFilter = THREE.NearestFilter
760-
const itemsTextureFlipped = itemsTexture.clone()
761-
itemsTextureFlipped.repeat.x *= -1
762-
itemsTextureFlipped.needsUpdate = true
763-
itemsTextureFlipped.offset.set(u + (sizeX), 1 - v - sizeY)
764-
const material = new THREE.MeshStandardMaterial({
765-
map: itemsTexture,
766-
transparent: true,
767-
alphaTest: 0.1,
768-
})
769-
const materialFlipped = new THREE.MeshStandardMaterial({
770-
map: itemsTextureFlipped,
771-
transparent: true,
772-
alphaTest: 0.1,
773-
})
774-
const mesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 0), [
775-
// top left and right bottom are black box materials others are transparent
776-
new THREE.MeshBasicMaterial({ color: 0x00_00_00 }), new THREE.MeshBasicMaterial({ color: 0x00_00_00 }),
777-
new THREE.MeshBasicMaterial({ color: 0x00_00_00 }), new THREE.MeshBasicMaterial({ color: 0x00_00_00 }),
778-
material, materialFlipped,
779-
])
760+
let mesh: THREE.Object3D
761+
let itemsTextureFlipped: THREE.Texture | undefined
762+
if (faceCamera) {
763+
const spriteMat = new THREE.SpriteMaterial({
764+
map: itemsTexture,
765+
transparent: true,
766+
alphaTest: 0.1,
767+
})
768+
mesh = new THREE.Sprite(spriteMat)
769+
} else {
770+
itemsTextureFlipped = itemsTexture.clone()
771+
itemsTextureFlipped.repeat.x *= -1
772+
itemsTextureFlipped.needsUpdate = true
773+
itemsTextureFlipped.offset.set(u + (sizeX), 1 - v - sizeY)
774+
const material = new THREE.MeshStandardMaterial({
775+
map: itemsTexture,
776+
transparent: true,
777+
alphaTest: 0.1,
778+
})
779+
const materialFlipped = new THREE.MeshStandardMaterial({
780+
map: itemsTextureFlipped,
781+
transparent: true,
782+
alphaTest: 0.1,
783+
})
784+
mesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 0), [
785+
// top left and right bottom are black box materials others are transparent
786+
new THREE.MeshBasicMaterial({ color: 0x00_00_00 }), new THREE.MeshBasicMaterial({ color: 0x00_00_00 }),
787+
new THREE.MeshBasicMaterial({ color: 0x00_00_00 }), new THREE.MeshBasicMaterial({ color: 0x00_00_00 }),
788+
material, materialFlipped,
789+
])
790+
}
780791
let SCALE = 1
781792
if (specificProps['minecraft:display_context'] === 'ground') {
782793
SCALE = 0.5
@@ -805,8 +816,6 @@ export class Entities {
805816
}
806817

807818
update (entity: SceneEntity['originalEntity'], overrides) {
808-
const justAdded = !this.entities[entity.id]
809-
810819
const isPlayerModel = entity.name === 'player'
811820
if (entity.name === 'zombie_villager' || entity.name === 'husk') {
812821
overrides.texture = `textures/1.16.4/entity/${entity.name === 'zombie_villager' ? 'zombie_villager/zombie_villager.png' : `zombie/${entity.name}.png`}`
@@ -817,6 +826,7 @@ export class Entities {
817826
}
818827
// this can be undefined in case where packet entity_destroy was sent twice (so it was already deleted)
819828
let e = this.entities[entity.id]
829+
const justAdded = !e
820830

821831
if (entity.delete) {
822832
if (!e) return
@@ -836,30 +846,32 @@ export class Entities {
836846
if (e === undefined) {
837847
const group = new THREE.Group() as unknown as SceneEntity
838848
group.originalEntity = entity
839-
if (entity.name === 'item' || entity.name === 'tnt' || entity.name === 'falling_block') {
840-
const item = entity.name === 'tnt'
841-
? { name: 'tnt' }
849+
if (entity.name === 'item' || entity.name === 'tnt' || entity.name === 'falling_block' || entity.name === 'snowball'
850+
|| entity.name === 'egg' || entity.name === 'ender_pearl' || entity.name === 'experience_bottle'
851+
|| entity.name === 'splash_potion' || entity.name === 'lingering_potion') {
852+
const item = entity.name === 'tnt' || entity.type === 'projectile'
853+
? { name: entity.name }
842854
: entity.name === 'falling_block'
843855
? { blockState: entity['objectData'] }
844856
: entity.metadata?.find((m: any) => typeof m === 'object' && m?.itemCount)
845857
if (item) {
846858
const object = this.getItemMesh(item, {
847859
'minecraft:display_context': 'ground',
848-
})
860+
}, entity.type === 'projectile')
849861
if (object) {
850862
mesh = object.mesh
851-
if (entity.name === 'item') {
863+
if (entity.name === 'item' || entity.type === 'projectile') {
852864
mesh.scale.set(0.5, 0.5, 0.5)
853-
mesh.position.set(0, 0.2, 0)
865+
mesh.position.set(0, entity.name === 'item' ? 0.2 : 0.1, 0)
854866
} else {
855867
mesh.scale.set(2, 2, 2)
856868
mesh.position.set(0, 0.5, 0)
857869
}
858870
// set faces
859871
// mesh.position.set(targetPos.x + 0.5 + 2, targetPos.y + 0.5, targetPos.z + 0.5)
860872
// viewer.scene.add(mesh)
861-
const clock = new THREE.Clock()
862873
if (entity.name === 'item') {
874+
const clock = new THREE.Clock()
863875
mesh.onBeforeRender = () => {
864876
const delta = clock.getDelta()
865877
mesh!.rotation.y += delta

renderer/viewer/three/holdingBlock.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ export default class HoldingBlock {
357357
'minecraft:display_context': 'firstperson',
358358
'minecraft:use_duration': this.worldRenderer.playerStateReactive.itemUsageTicks,
359359
'minecraft:using_item': !!this.worldRenderer.playerStateReactive.itemUsageTicks,
360-
}, this.lastItemModelName)
360+
}, false, this.lastItemModelName)
361361
if (result) {
362362
const { mesh: itemMesh, isBlock, modelName } = result
363363
if (isBlock) {

0 commit comments

Comments
 (0)