├── .gitattributes
├── .github
├── images
│ ├── image1.png
│ └── image2.png
└── workflows
│ ├── preview_build.yml
│ └── released.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── icon
├── icon.png
└── icon_min.png
├── settings.gradle
├── src
├── client
│ ├── java
│ │ └── dev
│ │ │ └── felnull
│ │ │ └── specialmodelloader
│ │ │ ├── api
│ │ │ ├── SpecialModelLoaderAPI.java
│ │ │ ├── data
│ │ │ │ └── SpecialModelDataGenHelper.java
│ │ │ ├── event
│ │ │ │ └── SpecialModelLoaderEvents.java
│ │ │ └── model
│ │ │ │ ├── LoadedResource.java
│ │ │ │ ├── ModelLoader.java
│ │ │ │ ├── ModelOption.java
│ │ │ │ └── obj
│ │ │ │ ├── ObjModelLoader.java
│ │ │ │ └── ObjModelOption.java
│ │ │ └── impl
│ │ │ ├── SpecialModelLoaderAPIImpl.java
│ │ │ ├── SpecialModelLoaderClient.java
│ │ │ ├── handler
│ │ │ ├── SMLClientHandler.java
│ │ │ ├── SMLModelLoadingHandler.java
│ │ │ └── package-info.java
│ │ │ ├── mixin
│ │ │ ├── BlockModelAccessor.java
│ │ │ └── package-info.java
│ │ │ ├── model
│ │ │ ├── ModelOptionImpl.java
│ │ │ ├── NeoForgeCompat.java
│ │ │ ├── SimpleMeshModel.java
│ │ │ ├── SpecialBaseModel.java
│ │ │ ├── SpecialBaseUnbakedModel.java
│ │ │ ├── obj
│ │ │ │ ├── ObjModelLoadedResource.java
│ │ │ │ ├── ObjModelLoaderImp.java
│ │ │ │ ├── ObjModelOptionImpl.java
│ │ │ │ ├── ObjUnbakedModelModel.java
│ │ │ │ └── package-info.java
│ │ │ └── package-info.java
│ │ │ ├── package-info.java
│ │ │ └── util
│ │ │ ├── JsonUtils.java
│ │ │ └── package-info.java
│ └── resources
│ │ └── special-model-loader.mixins.json
├── main
│ ├── java
│ │ └── dev
│ │ │ └── felnull
│ │ │ └── specialmodelloader
│ │ │ └── impl
│ │ │ └── SpecialModelLoader.java
│ └── resources
│ │ ├── assets
│ │ └── special-model-loader
│ │ │ └── icon.png
│ │ └── fabric.mod.json
└── test
│ ├── generated
│ ├── .cache
│ │ └── d26dbd274f1ce9df6c32c695a40e10fe4203dafa
│ └── assets
│ │ └── special-model-loader-test
│ │ ├── blockstates
│ │ ├── facing_model_block.json
│ │ ├── facing_obj_model_block.json
│ │ └── normal_model_block.json
│ │ └── models
│ │ ├── block
│ │ ├── facing_model_block.json
│ │ └── normal_model_block.json
│ │ └── item
│ │ ├── mtloverride_obj_model_item.json
│ │ ├── normal_model_item.json
│ │ ├── obj_model_item.json
│ │ └── textures_obj_model_item.json
│ ├── java
│ └── dev
│ │ └── felnull
│ │ └── smltest
│ │ ├── SMLTest.java
│ │ ├── block
│ │ ├── FacingBlock.java
│ │ └── SMLTestBlocks.java
│ │ ├── client
│ │ ├── DynamicObjModelItemSpecialRenderer.java
│ │ └── SMLTestClient.java
│ │ ├── data
│ │ ├── SMLTestDataGenerator.java
│ │ └── SMLTestModelProvider.java
│ │ └── item
│ │ └── SMLTestItems.java
│ └── resources
│ ├── assets
│ └── special-model-loader-test
│ │ ├── blockstates
│ │ └── obj_model_block.json
│ │ ├── items
│ │ ├── dynamic_obj_model_item.json
│ │ ├── forge_obj_model_item.json
│ │ └── obj2_model_item.json
│ │ ├── models
│ │ ├── block
│ │ │ ├── apple
│ │ │ │ ├── apple.mtl
│ │ │ │ └── apple.obj
│ │ │ └── obj_model_block.json
│ │ └── item
│ │ │ ├── cylinder
│ │ │ ├── cylinder.blend
│ │ │ ├── cylinder.mtl
│ │ │ └── cylinder.obj
│ │ │ ├── dynamic_obj_model_item.json
│ │ │ ├── forge_obj_model_item.json
│ │ │ ├── obj2_model_item.json
│ │ │ ├── obj_model_block.json
│ │ │ ├── obj_model_item_dynamic.json
│ │ │ ├── parabolic_antenna
│ │ │ ├── parabolic_antenna.mtl
│ │ │ ├── parabolic_antenna.obj
│ │ │ └── parabolic_antenna_2.mtl
│ │ │ ├── ring
│ │ │ ├── ring.mtl
│ │ │ ├── ring.obj
│ │ │ └── ring_2.mtl
│ │ │ ├── sea_cheken_pack
│ │ │ ├── sea_chicken.blend
│ │ │ ├── sea_chicken.mtl
│ │ │ └── sea_chicken.obj
│ │ │ └── test
│ │ │ ├── test.mtl
│ │ │ └── test.obj
│ │ ├── sml_load_scopes
│ │ └── test.json
│ │ └── textures
│ │ ├── block
│ │ ├── body.png
│ │ ├── eay.png
│ │ ├── facing_model_block_front.png
│ │ ├── facing_model_block_side.png
│ │ ├── facing_model_block_top.png
│ │ └── normal_model_block.png
│ │ └── item
│ │ ├── cheken.png
│ │ ├── cheken_pack.png
│ │ ├── normal_model_item.png
│ │ └── parabolic_antenna.png
│ └── fabric.mod.json
└── test-resourcepacks
├── SMLTestPack.zip
└── SMLTestPack
├── assets
├── minecraft
│ ├── models
│ │ └── item
│ │ │ ├── 3d_apple.mtl
│ │ │ ├── 3d_apple.obj
│ │ │ └── apple.json
│ └── textures
│ │ └── item
│ │ └── 3d_apple.png
└── sml-test-pack
│ └── sml_load_scopes
│ └── test_scopes.json
├── pack.mcmeta
└── pack.png
/.gitattributes:
--------------------------------------------------------------------------------
1 | #
2 | # https://help.github.com/articles/dealing-with-line-endings/
3 | #
4 | # Linux start script should use lf
5 | /gradlew text eol=lf
6 |
7 | # These are Windows script files and should use crlf
8 | *.bat text eol=crlf
9 |
10 |
--------------------------------------------------------------------------------
/.github/images/image1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/.github/images/image1.png
--------------------------------------------------------------------------------
/.github/images/image2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/.github/images/image2.png
--------------------------------------------------------------------------------
/.github/workflows/preview_build.yml:
--------------------------------------------------------------------------------
1 | name: Preview Build
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | jobs:
7 | preview_build:
8 | uses: TeamFelnull/actions-reusable-workflows/.github/workflows/mcmod-preview-build.yml@master
9 | with:
10 | build_tasks: "build publish"
11 | secrets:
12 | maven_password: ${{ secrets.MAVEN_PASSWORD }}
--------------------------------------------------------------------------------
/.github/workflows/released.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'v*'
7 |
8 | jobs:
9 | release:
10 | uses: TeamFelnull/actions-reusable-workflows/.github/workflows/mcmod-release.yml@master
11 | with:
12 | build_tasks: "build publishCurseForge modrinth publish"
13 | secrets:
14 | curseforge_token: ${{ secrets.CURSEFORGE_TOKEN_MORI }}
15 | modrinth_token: ${{ secrets.MODRINTH_TOKEN_MORI }}
16 | maven_password: ${{ secrets.MAVEN_PASSWORD }}
17 |
18 | postRelease:
19 | name: Update after release
20 | needs: release
21 | uses: TeamFelnull/actions-reusable-workflows/.github/workflows/mcmod-post-release.yml@master
22 | with:
23 | update_forge_version_check: false
24 | update_neoforge_version_check: false
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # gradle
2 |
3 | .gradle/
4 | build/
5 | out/
6 | classes/
7 |
8 | # eclipse
9 |
10 | *.launch
11 |
12 | # idea
13 |
14 | .idea/
15 | *.iml
16 | *.ipr
17 | *.iws
18 |
19 | # vscode
20 |
21 | .settings/
22 | .vscode/
23 | bin/
24 | .classpath
25 | .project
26 |
27 | # macos
28 |
29 | *.DS_Store
30 |
31 | # fabric
32 |
33 | run/
34 |
35 | # java
36 |
37 | hs_err_*.log
38 | replay_*.log
39 | *.hprof
40 | *.jfr
41 |
42 | src/main/generated/
43 | src/test/generated/
44 |
45 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | Changelog to track updates for this mod.
3 | Add your changes to Unreleased if you want to commit.
4 | Please write according to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
5 |
6 | ## [Unreleased]
7 |
8 | ### Added
9 |
10 | ### Changed
11 |
12 | ### Deprecated
13 |
14 | ### Removed
15 |
16 | ### Fixed
17 |
18 | ### Security
19 |
20 | ## [1.4.0] - 2025-01-19
21 |
22 | ### Changed
23 | - Port MC1.21.4
24 |
25 | ## [1.3.0] - 2024-09-21
26 |
27 | ### Changed
28 | - Port MC1.21.1
29 |
30 | ## [1.2.0] - 2023-06-11
31 |
32 | ### Added
33 | - Added ability to add model load scopes using resource packs
34 |
35 | ### Changed
36 | - Port MC1.20 [#2](https://github.com/TeamFelnull/SpecialModelLoader/pull/2)
37 |
38 | ## [1.1.0] - 2023-03-31
39 |
40 | ### Changed
41 | - Port MC1.19.4
42 |
43 | ## [1.0.1] - 2023-03-29
44 |
45 | ### Changed
46 | - Changed dependent Fabric Loader version to 0.14.17 and Fabruc API version to 0.76.0+1.19.3
47 |
48 | ### Deprecated
49 | - Adding this version to a MC1.19.4 project is deprecated, please use the 1.1.0 version to be uploaded at a later date.
50 |
51 | ### Fixed
52 | - Fixed error when adding to Fabric Loom 1.1 project
53 |
54 | [Unreleased]: https://github.com/TeamFelnull/SpecialModelLoader/compare/v1.4.0...HEAD
55 | [1.4.0]: https://github.com/TeamFelnull/SpecialModelLoader/compare/v1.3.0...v1.4.0
56 | [1.3.0]: https://github.com/TeamFelnull/SpecialModelLoader/compare/v1.2.0...v1.3.0
57 | [1.2.0]: https://github.com/TeamFelnull/SpecialModelLoader/compare/v1.1.0...v1.2.0
58 | [1.1.0]: https://github.com/TeamFelnull/SpecialModelLoader/compare/v1.0.1...v1.1.0
59 | [1.0.1]: https://github.com/TeamFelnull/SpecialModelLoader/commits/v1.0.1
60 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 TeamFelNull
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |

3 |
Special Model Loader
4 | Special Model Loader is a library for loading OBJ models in Fabric.
5 |
6 | [Example](https://github.com/TeamFelnull/SpecialModelLoader-Example) · [Report an Issue](https://github.com/TeamFelnull/SpecialModelLoader/issues/new/choose) · [Getting Started](https://github.com/TeamFelnull/SpecialModelLoader/wiki/Getting-Started)
7 |
8 |

9 |
.svg?badge_style=for_the_badge)
10 |

11 |
12 |
13 | ***
14 |
15 | Development inspired by [FOML](https://github.com/OnyxStudios/FOML) and [Myron](https://github.com/Haven-King/myron), but neither libraries are available for use in the 1.19 version of Fabric.
16 |
17 | Please see the Wiki for more information or see [SpecialModelLoader-Example](https://github.com/TeamFelnull/SpecialModelLoader-Example) for usage examples.
18 |
19 | ## Discord Support
20 | Feel free to ask for additional support in the Discord server, just open a thread in the `#special-model-loader` channel.
21 |
22 |
23 |
24 | ## Using Libraries:
25 |
26 | - [de.javagl.obj](https://github.com/javagl/Obj)
27 |
28 | Since it is built into the jar file, there is no need to add it as a separate dependency.
29 |
30 | ***
31 | 
32 | 
33 | 
34 | 
35 | 
36 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | import net.darkhax.curseforgegradle.TaskPublishCurseForge
2 |
3 | plugins {
4 | id 'fabric-loom' version '1.9-SNAPSHOT'
5 | id 'maven-publish'
6 | id 'net.darkhax.curseforgegradle' version '1.1.25'
7 | id "com.modrinth.minotaur" version '2.8.7'
8 | id 'org.jetbrains.changelog' version "2.0.0"
9 | }
10 |
11 | // Version Check
12 | if (System.getenv("GITHUB_REF") != null && System.getenv("GITHUB_REF").startsWith("refs/tags/v")) {
13 | if (System.getenv("GITHUB_REF").substring("refs/tags/v".length()) != project.mod_version)
14 | throw new IllegalStateException("The version and tag specification are different")
15 | }
16 |
17 | version = project.mod_version
18 | group = project.maven_group
19 |
20 | base {
21 | archivesName = project.archives_base_name
22 | }
23 |
24 | fabricApi {
25 | configureDataGeneration() {
26 | client = true
27 | }
28 | }
29 |
30 | loom {
31 | splitEnvironmentSourceSets()
32 |
33 | mods {
34 | "special-model-loader" {
35 | sourceSet sourceSets.main
36 | sourceSet sourceSets.client
37 | }
38 | }
39 |
40 | runs {
41 | testmodClient {
42 | client()
43 | ideConfigGenerated project.rootProject == project
44 | name = "Testmod Client"
45 | source sourceSets.test
46 | }
47 |
48 | testmodDatagen {
49 | client()
50 |
51 | ideConfigGenerated project.rootProject == project
52 |
53 | name = "Testmod Data"
54 | vmArg "-Dfabric-api.datagen"
55 | vmArg "-Dfabric-api.datagen.output-dir=${file("src/test/generated")}"
56 |
57 | runDir "build/datagen"
58 | source sourceSets.test
59 | }
60 | }
61 | }
62 |
63 | sourceSets {
64 | test {
65 | compileClasspath += main.compileClasspath
66 | runtimeClasspath += main.runtimeClasspath
67 | compileClasspath += client.compileClasspath
68 | runtimeClasspath += client.runtimeClasspath
69 |
70 | resources {
71 | srcDirs += [
72 | 'src/test/generated'
73 | ]
74 | }
75 | }
76 | }
77 |
78 | changelog {
79 | repositoryUrl = rootProject.repository_url
80 | introduction = """
81 | Changelog to track updates for this mod.
82 | Add your changes to Unreleased if you want to commit.
83 | Please write according to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
84 | """
85 | combinePreReleases = false
86 | }
87 |
88 | repositories {
89 | maven { url "https://maven.parchmentmc.org" }
90 | }
91 |
92 | configurations {
93 | modImplementation.extendsFrom includeIn
94 | include.extendsFrom includeIn
95 | }
96 |
97 | dependencies {
98 | minecraft "com.mojang:minecraft:${project.minecraft_version}"
99 |
100 | mappings loom.layered() {
101 | officialMojangMappings()
102 | parchment("org.parchmentmc.data:parchment-1.21.4:2025.01.05@zip")
103 | }
104 | modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
105 |
106 | modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
107 |
108 | includeIn "de.javagl:obj:0.4.0"
109 |
110 | testImplementation sourceSets.client.output
111 | }
112 |
113 | remapJar {
114 | archiveClassifier.set(null)
115 | setArchivesBaseName("${rootProject.archives_base_name}-mc${rootProject.minecraft_version}")
116 | }
117 |
118 | processResources {
119 | inputs.property "version", project.version
120 |
121 | filesMatching("fabric.mod.json") {
122 | expand "version": project.version
123 | }
124 | }
125 |
126 | tasks.withType(JavaCompile).configureEach {
127 | it.options.release = 21
128 | }
129 |
130 | java {
131 | withSourcesJar()
132 |
133 | sourceCompatibility = JavaVersion.VERSION_21
134 | targetCompatibility = JavaVersion.VERSION_21
135 | }
136 |
137 | jar {
138 | from("LICENSE") {
139 | rename { "${it}_${project.base.archivesName.get()}" }
140 | }
141 | }
142 |
143 | publishing {
144 | publications {
145 | mavenFabric(MavenPublication) {
146 | artifactId = rootProject.archives_base_name
147 | from components.java
148 | pom {
149 | name = 'SpecialModelLoader'
150 | description = 'Support for loading special models.'
151 | developers {
152 | developer {
153 | id = 'MORIMORI0317'
154 | name = 'MORIMORI0317'
155 | }
156 | developer {
157 | id = 'FelNull'
158 | name = 'TeamFelNull'
159 | email = 'teamfelnull@felnull.dev'
160 | }
161 | }
162 | }
163 | }
164 | }
165 |
166 | repositories {
167 | maven {
168 | url "https://maven.felnull.dev/"
169 | credentials {
170 | username = "felnull"
171 | password = "${project.maven_put_pass}" != '' ? "${project.maven_put_pass}" : System.getenv('mavenpassword')
172 | }
173 | }
174 | }
175 | }
176 |
177 | def mainJar = file("${project.layout.buildDirectory.get().asFile}/libs/${project.archives_base_name}-mc${project.minecraft_version}-${project.mod_version}.jar")
178 | def sourcesJar = file("${project.layout.buildDirectory.get().asFile}/libs/${project.archives_base_name}-mc${project.minecraft_version}-${project.mod_version}-sources.jar")
179 | def changeLogFile = file('./LATEST_CHANGELOG.md')
180 | def uploadMainName = "${project.mod_display_name}-${project.minecraft_version}-${project.mod_version}"
181 | def uploadSourcesName = "${project.mod_display_name}-${project.minecraft_version}-${project.mod_version}-sources"
182 |
183 | tasks.register('publishCurseForge', TaskPublishCurseForge) {
184 | if (System.getenv('curesforgeapikey') != null && "${project.curesforge_id}" != '') {
185 | apiToken = System.getenv('curesforgeapikey')
186 |
187 | def mainFile = upload(findProperty('curesforge_id'), mainJar)
188 | mainFile.changelogType = 'markdown'
189 | mainFile.changelog = changeLogFile.text
190 | mainFile.releaseType = "${project.release_type}"
191 | mainFile.displayName = uploadMainName
192 |
193 | project.support_versions.split(",").each {
194 | String version -> mainFile.addGameVersion(version)
195 | }
196 |
197 | mainFile.addJavaVersion('Java 21')
198 |
199 | mainFile.addModLoader('Fabric')
200 | mainFile.addModLoader('Quilt')
201 |
202 | mainFile.addGameVersion('Client')
203 |
204 | mainFile.addRequirement("fabric-api")
205 |
206 | def sourcesFile = mainFile.withAdditionalFile(sourcesJar)
207 | sourcesFile.displayName = uploadSourcesName
208 | }
209 | }
210 |
211 | if (System.getenv('modrinthapikey') != null && "${modrinth_id}" != '') {
212 | modrinth {
213 | token = System.getenv('modrinthapikey')
214 | projectId = "${project.modrinth_id}"
215 | versionName = uploadMainName
216 | versionNumber = "${project.minecraft_version}-${project.mod_version}"
217 | versionType = "${project.release_type}"
218 | uploadFile = mainJar
219 | gameVersions = List.of(project.support_versions.split(","))
220 | loaders = ["fabric", "quilt"]
221 | dependencies {
222 | required.project("P7dR8mSH") //Fabric API
223 | }
224 | changelog = changeLogFile.text
225 | }
226 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #Gradle setting
2 | org.gradle.jvmargs=-Xmx3G
3 | org.gradle.parallel=true
4 | #Minecraft
5 | minecraft_version=1.21.4
6 | support_versions=1.21.4
7 | #Mod
8 | archives_base_name=special-model-loader
9 | mod_display_name=SpecialModelLoader
10 | mod_version=1.4.0
11 | #Dependencies
12 | loader_version=0.16.9
13 | fabric_version=0.111.0+1.21.4
14 | #Maven
15 | maven_group=dev.felnull
16 | maven_put_url=https://maven.felnull.dev/
17 | maven_put_pass=
18 | #Upload
19 | curesforge_id=782421
20 | modrinth_id=ajFw7VkX
21 | release_type=release
22 | #Other
23 | repository_url=https://github.com/TeamFelnull/SpecialModelLoader
24 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 | # SPDX-License-Identifier: Apache-2.0
19 | #
20 |
21 | ##############################################################################
22 | #
23 | # Gradle start up script for POSIX generated by Gradle.
24 | #
25 | # Important for running:
26 | #
27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
28 | # noncompliant, but you have some other compliant shell such as ksh or
29 | # bash, then to run this script, type that shell name before the whole
30 | # command line, like:
31 | #
32 | # ksh Gradle
33 | #
34 | # Busybox and similar reduced shells will NOT work, because this script
35 | # requires all of these POSIX shell features:
36 | # * functions;
37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
39 | # * compound commands having a testable exit status, especially «case»;
40 | # * various built-in commands including «command», «set», and «ulimit».
41 | #
42 | # Important for patching:
43 | #
44 | # (2) This script targets any POSIX shell, so it avoids extensions provided
45 | # by Bash, Ksh, etc; in particular arrays are avoided.
46 | #
47 | # The "traditional" practice of packing multiple parameters into a
48 | # space-separated string is a well documented source of bugs and security
49 | # problems, so this is (mostly) avoided, by progressively accumulating
50 | # options in "$@", and eventually passing that to Java.
51 | #
52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
54 | # see the in-line comments for details.
55 | #
56 | # There are tweaks for specific operating systems such as AIX, CygWin,
57 | # Darwin, MinGW, and NonStop.
58 | #
59 | # (3) This script is generated from the Groovy template
60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
61 | # within the Gradle project.
62 | #
63 | # You can find Gradle at https://github.com/gradle/gradle/.
64 | #
65 | ##############################################################################
66 |
67 | # Attempt to set APP_HOME
68 |
69 | # Resolve links: $0 may be a link
70 | app_path=$0
71 |
72 | # Need this for daisy-chained symlinks.
73 | while
74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
75 | [ -h "$app_path" ]
76 | do
77 | ls=$( ls -ld "$app_path" )
78 | link=${ls#*' -> '}
79 | case $link in #(
80 | /*) app_path=$link ;; #(
81 | *) app_path=$APP_HOME$link ;;
82 | esac
83 | done
84 |
85 | # This is normally unused
86 | # shellcheck disable=SC2034
87 | APP_BASE_NAME=${0##*/}
88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
90 | ' "$PWD" ) || exit
91 |
92 | # Use the maximum available, or set MAX_FD != -1 to use that value.
93 | MAX_FD=maximum
94 |
95 | warn () {
96 | echo "$*"
97 | } >&2
98 |
99 | die () {
100 | echo
101 | echo "$*"
102 | echo
103 | exit 1
104 | } >&2
105 |
106 | # OS specific support (must be 'true' or 'false').
107 | cygwin=false
108 | msys=false
109 | darwin=false
110 | nonstop=false
111 | case "$( uname )" in #(
112 | CYGWIN* ) cygwin=true ;; #(
113 | Darwin* ) darwin=true ;; #(
114 | MSYS* | MINGW* ) msys=true ;; #(
115 | NONSTOP* ) nonstop=true ;;
116 | esac
117 |
118 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
119 |
120 |
121 | # Determine the Java command to use to start the JVM.
122 | if [ -n "$JAVA_HOME" ] ; then
123 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
124 | # IBM's JDK on AIX uses strange locations for the executables
125 | JAVACMD=$JAVA_HOME/jre/sh/java
126 | else
127 | JAVACMD=$JAVA_HOME/bin/java
128 | fi
129 | if [ ! -x "$JAVACMD" ] ; then
130 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
131 |
132 | Please set the JAVA_HOME variable in your environment to match the
133 | location of your Java installation."
134 | fi
135 | else
136 | JAVACMD=java
137 | if ! command -v java >/dev/null 2>&1
138 | then
139 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
140 |
141 | Please set the JAVA_HOME variable in your environment to match the
142 | location of your Java installation."
143 | fi
144 | fi
145 |
146 | # Increase the maximum file descriptors if we can.
147 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
148 | case $MAX_FD in #(
149 | max*)
150 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
151 | # shellcheck disable=SC2039,SC3045
152 | MAX_FD=$( ulimit -H -n ) ||
153 | warn "Could not query maximum file descriptor limit"
154 | esac
155 | case $MAX_FD in #(
156 | '' | soft) :;; #(
157 | *)
158 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
159 | # shellcheck disable=SC2039,SC3045
160 | ulimit -n "$MAX_FD" ||
161 | warn "Could not set maximum file descriptor limit to $MAX_FD"
162 | esac
163 | fi
164 |
165 | # Collect all arguments for the java command, stacking in reverse order:
166 | # * args from the command line
167 | # * the main class name
168 | # * -classpath
169 | # * -D...appname settings
170 | # * --module-path (only if needed)
171 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
172 |
173 | # For Cygwin or MSYS, switch paths to Windows format before running java
174 | if "$cygwin" || "$msys" ; then
175 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
176 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
177 |
178 | JAVACMD=$( cygpath --unix "$JAVACMD" )
179 |
180 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
181 | for arg do
182 | if
183 | case $arg in #(
184 | -*) false ;; # don't mess with options #(
185 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
186 | [ -e "$t" ] ;; #(
187 | *) false ;;
188 | esac
189 | then
190 | arg=$( cygpath --path --ignore --mixed "$arg" )
191 | fi
192 | # Roll the args list around exactly as many times as the number of
193 | # args, so each arg winds up back in the position where it started, but
194 | # possibly modified.
195 | #
196 | # NB: a `for` loop captures its iteration list before it begins, so
197 | # changing the positional parameters here affects neither the number of
198 | # iterations, nor the values presented in `arg`.
199 | shift # remove old arg
200 | set -- "$@" "$arg" # push replacement arg
201 | done
202 | fi
203 |
204 |
205 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
206 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
207 |
208 | # Collect all arguments for the java command:
209 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
210 | # and any embedded shellness will be escaped.
211 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
212 | # treated as '${Hostname}' itself on the command line.
213 |
214 | set -- \
215 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
216 | -classpath "$CLASSPATH" \
217 | org.gradle.wrapper.GradleWrapperMain \
218 | "$@"
219 |
220 | # Stop when "xargs" is not available.
221 | if ! command -v xargs >/dev/null 2>&1
222 | then
223 | die "xargs is not available"
224 | fi
225 |
226 | # Use "xargs" to parse quoted args.
227 | #
228 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
229 | #
230 | # In Bash we could simply go:
231 | #
232 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
233 | # set -- "${ARGS[@]}" "$@"
234 | #
235 | # but POSIX shell has neither arrays nor command substitution, so instead we
236 | # post-process each arg (as a line of input to sed) to backslash-escape any
237 | # character that might be a shell metacharacter, then use eval to reverse
238 | # that process (while maintaining the separation between arguments), and wrap
239 | # the whole thing up as a single "set" statement.
240 | #
241 | # This will of course break if any of these variables contains a newline or
242 | # an unmatched quote.
243 | #
244 |
245 | eval "set -- $(
246 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
247 | xargs -n1 |
248 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
249 | tr '\n' ' '
250 | )" '"$@"'
251 |
252 | exec "$JAVACMD" "$@"
253 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/icon/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/icon/icon.png
--------------------------------------------------------------------------------
/icon/icon_min.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/icon/icon_min.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | maven {
4 | name = 'Fabric'
5 | url = 'https://maven.fabricmc.net/'
6 | }
7 | mavenCentral()
8 | gradlePluginPortal()
9 | }
10 | }
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/api/SpecialModelLoaderAPI.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.api;
2 |
3 | import dev.felnull.specialmodelloader.api.model.LoadedResource;
4 | import dev.felnull.specialmodelloader.api.model.ModelLoader;
5 | import dev.felnull.specialmodelloader.api.model.obj.ObjModelLoader;
6 | import dev.felnull.specialmodelloader.impl.SpecialModelLoaderAPIImpl;
7 | import net.minecraft.client.resources.model.UnbakedModel;
8 | import net.minecraft.resources.ResourceLocation;
9 | import net.minecraft.server.packs.resources.ResourceManager;
10 | import org.jetbrains.annotations.NotNull;
11 | import org.jetbrains.annotations.Nullable;
12 | import org.jetbrains.annotations.Unmodifiable;
13 |
14 | import java.util.List;
15 |
16 | public interface SpecialModelLoaderAPI {
17 |
18 | static SpecialModelLoaderAPI getInstance() {
19 | return SpecialModelLoaderAPIImpl.INSTANCE;
20 | }
21 |
22 | /**
23 | * A complete list of model loaders supported by this mod.
24 | * Currently, there is only an OBJ loader
25 | *
26 | * @return ModelLoader list
27 | */
28 | @Unmodifiable
29 | @NotNull List getLoaders();
30 |
31 | /**
32 | * A loader for reading OBJ files
33 | *
34 | * @return OBJModel Loader
35 | */
36 | @NotNull ObjModelLoader getObjLoader();
37 |
38 | /**
39 | * Loads a model at a specified location using the resource manager and returns the loaded resource.
40 | *
41 | * @param resourceManager ResourceManager
42 | * @param modelLocation The location of the JsonModel (e.g. minecraft:item/apple)
43 | * @return The loaded resource instances required to make the model. Null if unable to load.
44 | */
45 | @Nullable
46 | LoadedResource loadResource(@NotNull ResourceManager resourceManager, @NotNull ResourceLocation modelLocation);
47 |
48 | /**
49 | * Made a model from the loaded resources.
50 | *
51 | * @param resource Resources loaded using{@link #loadResource(ResourceManager, ResourceLocation)}
52 | * @return Made model
53 | */
54 | @NotNull
55 | UnbakedModel makeModel(@NotNull LoadedResource resource);
56 | }
57 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/api/data/SpecialModelDataGenHelper.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.api.data;
2 |
3 | import com.google.gson.JsonObject;
4 | import dev.felnull.specialmodelloader.impl.SpecialModelLoader;
5 | import net.minecraft.client.data.models.model.ModelInstance;
6 | import net.minecraft.client.data.models.model.ModelLocationUtils;
7 | import net.minecraft.resources.ResourceLocation;
8 | import net.minecraft.world.item.Item;
9 | import net.minecraft.world.level.block.Block;
10 | import org.jetbrains.annotations.NotNull;
11 | import org.jetbrains.annotations.Nullable;
12 | import org.jetbrains.annotations.Unmodifiable;
13 |
14 | import java.util.Map;
15 | import java.util.function.BiConsumer;
16 |
17 | public final class SpecialModelDataGenHelper {
18 | private static final ResourceLocation OBJ_LOADER = ResourceLocation.fromNamespaceAndPath(SpecialModelLoader.MODID, "builtin/obj");
19 |
20 | public static void generateObjModel(@NotNull ResourceLocation location, @NotNull ResourceLocation objLocation,
21 | boolean flipV, boolean useAmbientOcclusion, @Nullable String mtlOverride, @Unmodifiable @NotNull Map textures,
22 | @Nullable ResourceLocation particle, @NotNull BiConsumer output) {
23 |
24 | output.accept(location, () -> {
25 | var jo = new JsonObject();
26 | jo.addProperty("parent", OBJ_LOADER.toString());
27 | jo.addProperty("model", objLocation.toString());
28 | jo.addProperty("flip_v", flipV);
29 | jo.addProperty("ambientocclusion", useAmbientOcclusion);
30 |
31 | if (mtlOverride != null) {
32 | jo.addProperty("mtl_override", mtlOverride);
33 | }
34 |
35 | if (!textures.isEmpty()) {
36 | JsonObject texturesJo = new JsonObject();
37 | textures.forEach((name, loc) -> {
38 | texturesJo.addProperty(name, loc.toString());
39 | });
40 | jo.add("textures", texturesJo);
41 | }
42 |
43 | if (particle != null) {
44 | jo.addProperty("particle", particle.toString());
45 | }
46 |
47 | return jo;
48 | });
49 | }
50 |
51 | public static void generateObjModel(@NotNull Item item, @NotNull ResourceLocation objLocation,
52 | boolean flipV, boolean useAmbientOcclusion, @Nullable String mtlOverride, @Unmodifiable @NotNull Map textures,
53 | @Nullable ResourceLocation particle, @NotNull BiConsumer output) {
54 | generateObjModel(ModelLocationUtils.getModelLocation(item), objLocation, flipV, useAmbientOcclusion, mtlOverride, textures, particle, output);
55 | }
56 |
57 | public static void generateObjModel(@NotNull Block block, @NotNull ResourceLocation objLocation,
58 | boolean flipV, boolean useAmbientOcclusion, @Nullable String mtlOverride, @Unmodifiable @NotNull Map textures,
59 | @Nullable ResourceLocation particle, @NotNull BiConsumer output) {
60 | generateObjModel(ModelLocationUtils.getModelLocation(block), objLocation, flipV, useAmbientOcclusion, mtlOverride, textures, particle, output);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/api/event/SpecialModelLoaderEvents.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.api.event;
2 |
3 | import net.fabricmc.fabric.api.event.Event;
4 | import net.fabricmc.fabric.api.event.EventFactory;
5 | import net.minecraft.resources.ResourceLocation;
6 | import net.minecraft.server.packs.resources.ResourceManager;
7 |
8 | import java.util.Arrays;
9 | import java.util.concurrent.CompletableFuture;
10 | import java.util.concurrent.Executor;
11 | import java.util.function.BiPredicate;
12 | import java.util.function.Predicate;
13 |
14 | public final class SpecialModelLoaderEvents {
15 |
16 | public static final Event LOAD_SCOPE = EventFactory.createArrayBacked(LoadScope.class, loadScopes -> {
17 | BiPredicate predicate = Arrays.stream(loadScopes)
18 | .map(LoadScope::provideLoadScopePredicate)
19 | .reduce(BiPredicate::or)
20 | .orElseGet(() -> (res, loc) -> false);
21 | return () -> predicate;
22 | });
23 |
24 | public static final Event LOAD_SCOPE_ASYNC = EventFactory.createArrayBacked(AsyncLoadScope.class, loadScopes -> (resourceManager, executor) ->
25 | Arrays.stream(loadScopes)
26 | .map(it -> it.provideAsyncLoadScopePredicate(resourceManager, executor))
27 | .reduce((cf1, cf2) -> cf1.thenCombineAsync(cf2, Predicate::or, executor))
28 | .orElseGet(() -> CompletableFuture.completedFuture(loc -> false)));
29 |
30 | public interface LoadScope {
31 |
32 | /**
33 | * It must return a Predicate to check if the given resource location is Load Scope.
34 | * This method is called from the rendering thread, but the Predicate test is called asynchronously, so be careful not to have side effects.
35 | *
36 | * @return A predicate to check if the location is a Load Scope.
37 | */
38 | BiPredicate provideLoadScopePredicate();
39 |
40 | }
41 |
42 | public interface AsyncLoadScope {
43 |
44 | /**
45 | * Must return a CompletableFuture that obtains a Predicate to check if the given resource location is Load Scope.
46 | * his method is called from the rendering thread, but the Predicate test is called asynchronously, so be careful not to have side effects.
47 | *
48 | * @param resourceManager Resource Manager
49 | * @param executor Executor
50 | * @return A CompletableFuture that takes a predicate to check if the location is a load scope.
51 | */
52 | CompletableFuture> provideAsyncLoadScopePredicate(ResourceManager resourceManager, Executor executor);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/api/model/LoadedResource.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.api.model;
2 |
3 | public interface LoadedResource {
4 | ModelLoader getLoader();
5 | }
6 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/api/model/ModelLoader.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.api.model;
2 |
3 | import com.google.gson.JsonObject;
4 | import dev.felnull.specialmodelloader.impl.SpecialModelLoader;
5 | import net.minecraft.client.resources.model.UnbakedModel;
6 | import net.minecraft.resources.ResourceLocation;
7 | import net.minecraft.server.packs.resources.ResourceManager;
8 | import org.jetbrains.annotations.NotNull;
9 | import org.jetbrains.annotations.Nullable;
10 |
11 | public interface ModelLoader {
12 |
13 | /**
14 | * Load the resource needed to create the model from the Resource Manager and Model Json.
15 | *
16 | * @param resourceManager Resource Manager
17 | * @param modelJson Model json
18 | * @return Loaded Model, null if not loaded.
19 | */
20 | @Nullable LoadedResource loadResource(@NotNull ResourceManager resourceManager, @NotNull JsonObject modelJson);
21 |
22 | /**
23 | * Make model from loaded resources.
24 | *
25 | * @param loadedResource Loaded resource
26 | * @return UnbakedModel
27 | */
28 | @NotNull UnbakedModel makeModel(@NotNull LoadedResource loadedResource);
29 |
30 | /**
31 | * Load model from Resource Manager and Model Json.
32 | *
33 | * @param resourceManager Resource Manager
34 | * @param modelJson Model json
35 | * @return UnbakedModel
36 | */
37 | default @Nullable UnbakedModel loadModel(@NotNull ResourceManager resourceManager, @NotNull JsonObject modelJson) {
38 | LoadedResource res = loadResource(resourceManager, modelJson);
39 |
40 | if (res == null) {
41 | return null;
42 | }
43 |
44 | return makeModel(res);
45 | }
46 |
47 | /**
48 | * ID of this model loader
49 | *
50 | * @return ID
51 | */
52 | @Nullable String getId();
53 |
54 | /**
55 | * Whether the model uses this model loader or not.
56 | *
57 | * @param modelLocation Model Location
58 | * @return true if this loader is used, false if not.
59 | */
60 | default boolean isLoaderLocation(@NotNull ResourceLocation modelLocation) {
61 | if (SpecialModelLoader.MODID.equals(modelLocation.getNamespace()) || "sml".equals(modelLocation.getNamespace()))
62 | return modelLocation.getPath().equals("builtin/" + getId());
63 | return false;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/api/model/ModelOption.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.api.model;
2 |
3 | import com.google.gson.JsonObject;
4 | import dev.felnull.specialmodelloader.impl.model.ModelOptionImpl;
5 | import net.minecraft.client.renderer.block.model.BlockModel;
6 | import net.minecraft.client.renderer.block.model.ItemTransforms;
7 | import net.minecraft.resources.ResourceLocation;
8 | import org.jetbrains.annotations.NotNull;
9 | import org.jetbrains.annotations.Nullable;
10 |
11 | public interface ModelOption {
12 |
13 | @NotNull
14 | static ModelOption of(boolean useAmbientOcclusion, @Nullable BlockModel.GuiLight guiLight, @Nullable ResourceLocation particle, @NotNull ItemTransforms transforms) {
15 | return new ModelOptionImpl(useAmbientOcclusion, guiLight, particle, transforms);
16 | }
17 |
18 | @NotNull
19 | static ModelOption parse(@NotNull JsonObject modelJson) {
20 | return ModelOptionImpl.parse(modelJson);
21 | }
22 |
23 | boolean isUseAmbientOcclusion();
24 |
25 | @Nullable
26 | BlockModel.GuiLight getGuiLight();
27 |
28 | @Nullable
29 | ResourceLocation getParticle();
30 |
31 | @NotNull
32 | ItemTransforms getTransforms();
33 | }
34 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/api/model/obj/ObjModelLoader.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.api.model.obj;
2 |
3 | import dev.felnull.specialmodelloader.api.model.LoadedResource;
4 | import dev.felnull.specialmodelloader.api.model.ModelLoader;
5 | import net.minecraft.client.resources.model.UnbakedModel;
6 | import net.minecraft.resources.ResourceLocation;
7 | import net.minecraft.server.packs.resources.ResourceManager;
8 | import org.jetbrains.annotations.NotNull;
9 | import org.jetbrains.annotations.Nullable;
10 |
11 | public interface ObjModelLoader extends ModelLoader {
12 |
13 | /**
14 | * Load resource from OBJ file location and options.
15 | *
16 | * @param resourceManager ResourceManager
17 | * @param location OBJ Location
18 | * @param option Model Option
19 | * @return Loaded Model, null if not loaded.
20 | */
21 | @Nullable
22 | LoadedResource loadResource(@NotNull ResourceManager resourceManager, @NotNull ResourceLocation location, @NotNull ObjModelOption option);
23 |
24 | /**
25 | * Load model from OBJ file location and options.
26 | *
27 | * @param resourceManager ResourceManager
28 | * @param location OBJ Location
29 | * @param option Model Option
30 | * @return UnbakedModel
31 | */
32 | default @Nullable UnbakedModel loadModel(@NotNull ResourceManager resourceManager, @NotNull ResourceLocation location, @NotNull ObjModelOption option) {
33 | LoadedResource res = loadResource(resourceManager, location, option);
34 |
35 | if (res == null) {
36 | return null;
37 | }
38 |
39 | return makeModel(res);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/api/model/obj/ObjModelOption.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.api.model.obj;
2 |
3 | import com.google.common.collect.ImmutableMap;
4 | import com.google.gson.JsonObject;
5 | import dev.felnull.specialmodelloader.api.model.ModelOption;
6 | import dev.felnull.specialmodelloader.impl.model.obj.ObjModelOptionImpl;
7 | import net.minecraft.resources.ResourceLocation;
8 | import org.jetbrains.annotations.NotNull;
9 | import org.jetbrains.annotations.Nullable;
10 | import org.jetbrains.annotations.Unmodifiable;
11 |
12 | import java.util.Map;
13 |
14 | public interface ObjModelOption extends ModelOption {
15 |
16 | @NotNull
17 | static ObjModelOption of(@NotNull ModelOption modelOption, boolean flipV,
18 | String mtlOverride, Map textures) {
19 | return new ObjModelOptionImpl(modelOption, flipV, mtlOverride, ImmutableMap.copyOf(textures));
20 | }
21 |
22 | @NotNull
23 | static ObjModelOption parse(@NotNull JsonObject modelJson) {
24 | return ObjModelOptionImpl.parse(modelJson);
25 | }
26 |
27 | boolean isFlipV();
28 |
29 | @Nullable
30 | String getMtlOverride();
31 |
32 | @Unmodifiable
33 | @NotNull
34 | Map getTextures();
35 | }
36 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/SpecialModelLoaderAPIImpl.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl;
2 |
3 | import com.google.common.collect.ImmutableList;
4 | import com.google.gson.JsonObject;
5 | import dev.felnull.specialmodelloader.api.SpecialModelLoaderAPI;
6 | import dev.felnull.specialmodelloader.api.model.LoadedResource;
7 | import dev.felnull.specialmodelloader.api.model.ModelLoader;
8 | import dev.felnull.specialmodelloader.api.model.obj.ObjModelLoader;
9 | import dev.felnull.specialmodelloader.api.model.obj.ObjModelOption;
10 | import dev.felnull.specialmodelloader.impl.model.NeoForgeCompat;
11 | import dev.felnull.specialmodelloader.impl.model.obj.ObjModelLoaderImp;
12 | import dev.felnull.specialmodelloader.impl.util.JsonUtils;
13 | import net.minecraft.client.resources.model.UnbakedModel;
14 | import net.minecraft.resources.ResourceLocation;
15 | import net.minecraft.server.packs.resources.ResourceManager;
16 | import net.minecraft.util.GsonHelper;
17 | import org.apache.commons.lang3.tuple.Pair;
18 | import org.jetbrains.annotations.NotNull;
19 | import org.jetbrains.annotations.Nullable;
20 | import org.jetbrains.annotations.Unmodifiable;
21 |
22 | import java.io.IOException;
23 | import java.util.*;
24 |
25 | public class SpecialModelLoaderAPIImpl implements SpecialModelLoaderAPI {
26 | public static final SpecialModelLoaderAPIImpl INSTANCE = new SpecialModelLoaderAPIImpl();
27 | private final List loaders = ImmutableList.of(ObjModelLoaderImp.INSTANCE);
28 |
29 | @Override
30 | public @NotNull ObjModelLoader getObjLoader() {
31 | return ObjModelLoaderImp.INSTANCE;
32 | }
33 |
34 | @Override
35 | public @Nullable LoadedResource loadResource(@NotNull ResourceManager resourceManager, @NotNull ResourceLocation modelLocation) {
36 | List models = new ArrayList<>();
37 | JsonObject jo = readJson(resourceManager, modelLocation);
38 |
39 | if (NeoForgeCompat.isEnable()) {
40 | Pair forgeModel = NeoForgeCompat.getObjModelData(jo);
41 | if (forgeModel != null) {
42 | return getObjLoader().loadResource(resourceManager, forgeModel.getLeft(), forgeModel.getRight());
43 | }
44 | }
45 |
46 | ResourceLocation location = JsonUtils.getParentLocation(jo);
47 | Set parents = new HashSet<>();
48 |
49 | while (location != null) {
50 | models.add(jo);
51 |
52 | if (parents.contains(location)) {
53 | SpecialModelLoader.LOGGER.warn("Model parent specification is looping: '{}', '{}'", modelLocation, location);
54 | return null;
55 | }
56 |
57 | parents.add(location);
58 |
59 | ModelLoader loader = getLoader(location);
60 | if (loader != null) {
61 | JsonObject ret = new JsonObject();
62 | Collections.reverse(models);
63 | models.forEach(r -> r.asMap().forEach((name, rlm) -> ret.add(name, rlm.deepCopy())));
64 | return loader.loadResource(resourceManager, ret);
65 | }
66 |
67 | jo = readJson(resourceManager, location);
68 | location = JsonUtils.getParentLocation(jo);
69 | }
70 |
71 | return null;
72 | }
73 |
74 | @Override
75 | public @NotNull UnbakedModel makeModel(@NotNull LoadedResource resource) {
76 | return resource.getLoader().makeModel(resource);
77 | }
78 |
79 | @Override
80 | public @Unmodifiable @NotNull List getLoaders() {
81 | return loaders;
82 | }
83 |
84 | private ModelLoader getLoader(ResourceLocation location) {
85 | return getLoaders().stream()
86 | .filter(r -> r.isLoaderLocation(location))
87 | .limit(1)
88 | .findFirst()
89 | .orElse(null);
90 | }
91 |
92 | private JsonObject readJson(ResourceManager resourceManager, ResourceLocation modelLocation) {
93 | ResourceLocation modelPath = ResourceLocation.fromNamespaceAndPath(modelLocation.getNamespace(), "models/" + modelLocation.getPath() + ".json");
94 | var res = resourceManager.getResource(modelPath);
95 | if (res.isEmpty()) return null;
96 | JsonObject jo;
97 | try (var reader = res.get().openAsReader()) {
98 | jo = GsonHelper.parse(reader);
99 | } catch (IOException ex) {
100 | throw new IllegalStateException("Failed to load json: " + modelLocation, ex);
101 | }
102 | return jo;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/SpecialModelLoaderClient.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl;
2 |
3 | import dev.felnull.specialmodelloader.impl.handler.SMLClientHandler;
4 | import dev.felnull.specialmodelloader.impl.handler.SMLModelLoadingHandler;
5 | import dev.felnull.specialmodelloader.impl.model.NeoForgeCompat;
6 | import net.fabricmc.api.ClientModInitializer;
7 |
8 | public class SpecialModelLoaderClient implements ClientModInitializer {
9 |
10 | @Override
11 | public void onInitializeClient() {
12 | SMLClientHandler.init();
13 | SMLModelLoadingHandler.init();
14 | NeoForgeCompat.init();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/handler/SMLClientHandler.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.handler;
2 |
3 | import com.google.common.collect.ImmutableSet;
4 | import com.google.gson.Gson;
5 | import com.google.gson.JsonArray;
6 | import com.google.gson.JsonElement;
7 | import com.google.gson.JsonObject;
8 | import dev.felnull.specialmodelloader.api.event.SpecialModelLoaderEvents;
9 | import dev.felnull.specialmodelloader.impl.SpecialModelLoader;
10 | import net.minecraft.resources.ResourceLocation;
11 | import net.minecraft.server.packs.resources.ResourceManager;
12 |
13 | import java.io.Reader;
14 | import java.util.concurrent.CompletableFuture;
15 | import java.util.concurrent.Executor;
16 | import java.util.function.BiPredicate;
17 | import java.util.function.Predicate;
18 | import java.util.regex.Pattern;
19 |
20 | public class SMLClientHandler {
21 | private static final Gson GSON = new Gson();
22 | private static final String MANUAL_LOAD_SCOPE_RESOURCE_NAME = "sml_load_scopes";
23 |
24 | public static void init() {
25 | SpecialModelLoaderEvents.LOAD_SCOPE_ASYNC.register(SMLClientHandler::provideSimpleLoadScopePredicate);
26 | SpecialModelLoaderEvents.LOAD_SCOPE_ASYNC.register(SMLClientHandler::provideManualLoadScopePredicate);
27 | }
28 |
29 | private static CompletableFuture> provideSimpleLoadScopePredicate(ResourceManager resourceManager, Executor executor) {
30 | BiPredicate predicate = SpecialModelLoaderEvents.LOAD_SCOPE.invoker().provideLoadScopePredicate();
31 | return CompletableFuture.supplyAsync(() -> loc -> predicate.test(resourceManager, loc), executor);
32 | }
33 |
34 | private static CompletableFuture> provideManualLoadScopePredicate(ResourceManager resourceManager, Executor executor) {
35 | return CompletableFuture.supplyAsync(() -> {
36 |
37 | ImmutableSet.Builder patternsBuilder = new ImmutableSet.Builder<>();
38 |
39 | resourceManager.listResources(MANUAL_LOAD_SCOPE_RESOURCE_NAME, loc -> loc.getPath().endsWith(".json")).forEach((location, resource) -> {
40 | try (Reader reader = resource.openAsReader()) {
41 | JsonObject jo = GSON.fromJson(reader, JsonObject.class);
42 | loadManualLoadScope(patternsBuilder, jo);
43 | } catch (Exception e) {
44 | SpecialModelLoader.LOGGER.error("Error occurred while loading model load scope resource json {}", location, e);
45 | }
46 | });
47 |
48 | final ImmutableSet patterns = patternsBuilder.build();
49 | int size = patterns.size();
50 | if (size >= 1) {
51 | SpecialModelLoader.LOGGER.info("Loaded {} manual model load scope", size);
52 | }
53 |
54 | return loc -> patterns.stream()
55 | .anyMatch(pattern -> pattern.matcher(loc.toString()).matches());
56 | }, executor);
57 | }
58 |
59 | private static void loadManualLoadScope(ImmutableSet.Builder builder, JsonObject jsonObject) {
60 |
61 | if (!jsonObject.has("version") || !jsonObject.get("version").isJsonPrimitive() || !jsonObject.getAsJsonPrimitive("version").isNumber()) {
62 | throw new IllegalStateException("Unknown version");
63 | }
64 |
65 | int version = jsonObject.getAsJsonPrimitive("version").getAsInt();
66 |
67 | if (version != 1) {
68 | throw new IllegalStateException("Unsupported version");
69 | }
70 |
71 | if (!jsonObject.has("entry") || !jsonObject.get("entry").isJsonArray()) {
72 | return;
73 | }
74 |
75 | JsonArray entries = jsonObject.getAsJsonArray("entry");
76 | for (JsonElement entry : entries) {
77 | if (entry.isJsonPrimitive() && entry.getAsJsonPrimitive().isString()) {
78 | builder.add(Pattern.compile(entry.getAsString()));
79 | }
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/handler/SMLModelLoadingHandler.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.handler;
2 |
3 | import com.google.common.collect.ImmutableMap;
4 | import dev.felnull.specialmodelloader.api.SpecialModelLoaderAPI;
5 | import dev.felnull.specialmodelloader.api.event.SpecialModelLoaderEvents;
6 | import dev.felnull.specialmodelloader.api.model.LoadedResource;
7 | import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin;
8 | import net.fabricmc.fabric.api.client.model.loading.v1.ModelModifier;
9 | import net.fabricmc.fabric.api.client.model.loading.v1.PreparableModelLoadingPlugin;
10 | import net.minecraft.client.resources.model.UnbakedModel;
11 | import net.minecraft.resources.ResourceLocation;
12 | import net.minecraft.server.packs.resources.ResourceManager;
13 |
14 | import java.util.Map;
15 | import java.util.concurrent.CompletableFuture;
16 | import java.util.concurrent.Executor;
17 | import java.util.function.Predicate;
18 |
19 | public final class SMLModelLoadingHandler {
20 |
21 | public static void init() {
22 | PreparableModelLoadingPlugin.register(SMLModelLoadingHandler::loadPrepareData, new MyModelLoadingPlugin());
23 | }
24 |
25 | private static UnbakedModel modifyModelOnLoad(PreparationData data, UnbakedModel original, ModelModifier.OnLoad.Context context) {
26 |
27 | ResourceLocation resId = context.id();
28 | if (resId != null) {
29 | LoadedResource loadedResource = data.resources().get(resId);
30 | if (loadedResource != null) {
31 | return SpecialModelLoaderAPI.getInstance().makeModel(loadedResource);
32 | }
33 | }
34 |
35 | return original;
36 | }
37 |
38 | private static CompletableFuture loadPrepareData(ResourceManager resourceManager, Executor executor) {
39 | CompletableFuture> loadScopePredicates = SpecialModelLoaderEvents.LOAD_SCOPE_ASYNC.invoker().provideAsyncLoadScopePredicate(resourceManager, executor);
40 | return loadScopePredicates.thenApplyAsync((lpPre) -> {
41 | ImmutableMap.Builder resBuilder = ImmutableMap.builder();
42 |
43 | resourceManager.listResources("models", loc -> loc.getPath().endsWith(".json")).forEach((location, resource) -> {
44 | String path = location.getPath().substring("models/".length());
45 | path = path.substring(0, path.length() - ".json".length());
46 | ResourceLocation modelLoc = ResourceLocation.fromNamespaceAndPath(location.getNamespace(), path);
47 |
48 | if (!lpPre.test(modelLoc)) {
49 | return;
50 | }
51 |
52 | LoadedResource res = SpecialModelLoaderAPI.getInstance().loadResource(resourceManager, modelLoc);
53 | if (res != null) {
54 | resBuilder.put(modelLoc, res);
55 | }
56 | });
57 |
58 | return new PreparationData(resBuilder.build());
59 | }, executor);
60 | }
61 |
62 | private static class MyModelLoadingPlugin implements PreparableModelLoadingPlugin {
63 | @Override
64 | public void initialize(PreparationData data, ModelLoadingPlugin.Context pluginContext) {
65 | pluginContext.modifyModelOnLoad().register((model, context) -> modifyModelOnLoad(data, model, context));
66 | }
67 | }
68 |
69 | private record PreparationData(Map resources) {
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/handler/package-info.java:
--------------------------------------------------------------------------------
1 | @ApiStatus.Internal
2 | package dev.felnull.specialmodelloader.impl.handler;
3 |
4 | import org.jetbrains.annotations.ApiStatus;
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/mixin/BlockModelAccessor.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.mixin;
2 |
3 | import com.google.gson.Gson;
4 | import net.minecraft.client.renderer.block.model.BlockModel;
5 | import org.spongepowered.asm.mixin.Mixin;
6 | import org.spongepowered.asm.mixin.gen.Accessor;
7 |
8 | @Mixin(BlockModel.class)
9 | public interface BlockModelAccessor {
10 | @Accessor("GSON")
11 | static Gson getGson() {
12 | throw new AssertionError();
13 | }
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/mixin/package-info.java:
--------------------------------------------------------------------------------
1 | @ApiStatus.Internal
2 | package dev.felnull.specialmodelloader.impl.mixin;
3 |
4 | import org.jetbrains.annotations.ApiStatus;
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/model/ModelOptionImpl.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.model;
2 |
3 | import com.google.gson.JsonObject;
4 | import dev.felnull.specialmodelloader.api.model.ModelOption;
5 | import dev.felnull.specialmodelloader.impl.mixin.BlockModelAccessor;
6 | import net.minecraft.client.renderer.block.model.BlockModel;
7 | import net.minecraft.client.renderer.block.model.ItemTransforms;
8 | import net.minecraft.resources.ResourceLocation;
9 | import net.minecraft.util.GsonHelper;
10 | import org.jetbrains.annotations.NotNull;
11 | import org.jetbrains.annotations.Nullable;
12 |
13 | public record ModelOptionImpl(boolean useAmbientOcclusion, BlockModel.GuiLight guiLight, ResourceLocation particle,
14 | ItemTransforms transforms) implements ModelOption {
15 |
16 | public static ModelOptionImpl parse(JsonObject modelJson) {
17 | ItemTransforms transform = ItemTransforms.NO_TRANSFORMS;
18 |
19 | if (modelJson.has("display")) {
20 | var jo = GsonHelper.getAsJsonObject(modelJson, "display");
21 | transform = BlockModelAccessor.getGson().fromJson(jo, ItemTransforms.class);
22 | }
23 |
24 | BlockModel.GuiLight guiLight = null;
25 | if (modelJson.has("gui_light"))
26 | guiLight = BlockModel.GuiLight.getByName(GsonHelper.getAsString(modelJson, "gui_light"));
27 |
28 | ResourceLocation particle = null;
29 | if (modelJson.has("particle"))
30 | particle = ResourceLocation.parse(GsonHelper.getAsString(modelJson, "particle"));
31 |
32 | return new ModelOptionImpl(GsonHelper.getAsBoolean(modelJson, "ambientocclusion", true), guiLight, particle, transform);
33 | }
34 |
35 | @Override
36 | public boolean isUseAmbientOcclusion() {
37 | return useAmbientOcclusion;
38 | }
39 |
40 | @Override
41 | public @Nullable BlockModel.GuiLight getGuiLight() {
42 | return guiLight;
43 | }
44 |
45 | @Override
46 | public @Nullable ResourceLocation getParticle() {
47 | return particle;
48 | }
49 |
50 | @Override
51 | public @NotNull ItemTransforms getTransforms() {
52 | return transforms;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/model/NeoForgeCompat.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.model;
2 |
3 | import com.google.gson.JsonObject;
4 | import dev.felnull.specialmodelloader.api.model.obj.ObjModelOption;
5 | import dev.felnull.specialmodelloader.impl.SpecialModelLoader;
6 | import dev.felnull.specialmodelloader.impl.util.JsonUtils;
7 | import net.fabricmc.loader.api.FabricLoader;
8 | import net.minecraft.resources.ResourceLocation;
9 | import org.apache.commons.lang3.tuple.Pair;
10 |
11 | /**
12 | * Compatibility to load models in formats supported by NeoForge
13 | */
14 | public final class NeoForgeCompat {
15 | private static final ResourceLocation NEO_FORGE_OBJ = ResourceLocation.fromNamespaceAndPath("neoforge", "obj");
16 |
17 | public static void init() {
18 | if (FabricLoader.getInstance().isModLoaded("connector")) {
19 | SpecialModelLoader.LOGGER.info("Sinytra Connector detected.");
20 | SpecialModelLoader.LOGGER.info("Disable NeoForge compatibility for OBJ loader.");
21 | }
22 | }
23 |
24 | public static boolean isEnable() {
25 | // If the Sinytra Connector is present, disable compatibility as it was launched in NeoForge
26 | // https://sinytra.org/docs/connector/developers
27 | return !FabricLoader.getInstance().isModLoaded("connector");
28 | }
29 |
30 | public static Pair getObjModelData(JsonObject modelJson) {
31 | if (modelJson == null) {
32 | return null;
33 | }
34 |
35 | // https://docs.neoforged.net/docs/resources/client/models/modelloaders/#obj-model
36 |
37 | ResourceLocation loaderLoc = JsonUtils.getResourceLocation(modelJson, "loader");
38 | if (!NEO_FORGE_OBJ.equals(loaderLoc)) {
39 | return null;
40 | }
41 |
42 | ResourceLocation model = JsonUtils.getResourceLocation(modelJson, "model");
43 | if (model == null) {
44 | return null;
45 | }
46 |
47 | return Pair.of(model, ObjModelOption.parse(modelJson));
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/model/SimpleMeshModel.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.model;
2 |
3 | import com.google.common.base.Suppliers;
4 | import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
5 | import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
6 | import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
7 | import net.minecraft.client.renderer.block.model.BakedQuad;
8 | import net.minecraft.client.renderer.block.model.ItemTransforms;
9 | import net.minecraft.client.renderer.texture.TextureAtlasSprite;
10 | import net.minecraft.core.BlockPos;
11 | import net.minecraft.core.Direction;
12 | import net.minecraft.util.RandomSource;
13 | import net.minecraft.world.level.BlockAndTintGetter;
14 | import net.minecraft.world.level.block.state.BlockState;
15 | import org.jetbrains.annotations.NotNull;
16 | import org.jetbrains.annotations.Nullable;
17 |
18 | import java.util.List;
19 | import java.util.function.Predicate;
20 | import java.util.function.Supplier;
21 |
22 | public class SimpleMeshModel extends SpecialBaseModel {
23 | private final Mesh mesh;
24 | private final Supplier[]> quadCache;
25 |
26 | public SimpleMeshModel(boolean useAmbientOcclusion, boolean usesBlockLight, TextureAtlasSprite particleIcon, ItemTransforms transforms, Mesh mesh) {
27 | super(useAmbientOcclusion, usesBlockLight, particleIcon, transforms);
28 | this.mesh = mesh;
29 | this.quadCache = Suppliers.memoize(() -> ModelHelper.toQuadLists(mesh));
30 | }
31 |
32 | @Override
33 | public void emitBlockQuads(QuadEmitter emitter, BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, Predicate<@Nullable Direction> cullTest) {
34 | mesh.outputTo(emitter);
35 | }
36 |
37 | @Override
38 | public void emitItemQuads(QuadEmitter emitter, Supplier randomSupplier) {
39 | mesh.outputTo(emitter);
40 | }
41 |
42 | @Override
43 | public @NotNull List getQuads(@Nullable BlockState blockState, @Nullable Direction direction, RandomSource randomSource) {
44 | return this.quadCache.get()[ModelHelper.toFaceIndex(direction)];
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/model/SpecialBaseModel.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.model;
2 |
3 | import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
4 | import net.minecraft.client.renderer.block.model.ItemTransforms;
5 | import net.minecraft.client.renderer.texture.TextureAtlasSprite;
6 | import net.minecraft.client.resources.model.BakedModel;
7 | import org.jetbrains.annotations.NotNull;
8 |
9 | public abstract class SpecialBaseModel implements BakedModel, FabricBakedModel {
10 | private final boolean useAmbientOcclusion;
11 | private final boolean usesBlockLight;
12 | private final TextureAtlasSprite particleIcon;
13 | private final ItemTransforms transforms;
14 |
15 | protected SpecialBaseModel(boolean useAmbientOcclusion, boolean usesBlockLight, TextureAtlasSprite particleIcon, ItemTransforms transforms) {
16 | this.useAmbientOcclusion = useAmbientOcclusion;
17 | this.usesBlockLight = usesBlockLight;
18 | this.particleIcon = particleIcon;
19 | this.transforms = transforms;
20 | }
21 |
22 | @Override
23 | public boolean isVanillaAdapter() {
24 | return false;
25 | }
26 |
27 | @Override
28 | public boolean useAmbientOcclusion() {
29 | return useAmbientOcclusion;
30 | }
31 |
32 | @Override
33 | public boolean isGui3d() {
34 | return true;
35 | }
36 |
37 | @Override
38 | public boolean usesBlockLight() {
39 | return usesBlockLight;
40 | }
41 |
42 | @Override
43 | public @NotNull TextureAtlasSprite getParticleIcon() {
44 | return particleIcon;
45 | }
46 |
47 | @Override
48 | public @NotNull ItemTransforms getTransforms() {
49 | return transforms;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/model/SpecialBaseUnbakedModel.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.model;
2 |
3 | import dev.felnull.specialmodelloader.api.model.ModelOption;
4 | import net.minecraft.client.renderer.block.model.BlockModel;
5 | import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
6 | import net.minecraft.client.renderer.texture.TextureAtlas;
7 | import net.minecraft.client.resources.model.Material;
8 | import net.minecraft.client.resources.model.UnbakedModel;
9 |
10 | public abstract class SpecialBaseUnbakedModel implements UnbakedModel {
11 | protected static final Material MISSING = new Material(TextureAtlas.LOCATION_BLOCKS, MissingTextureAtlasSprite.getLocation());
12 | private final ModelOption modelOption;
13 |
14 | protected SpecialBaseUnbakedModel(ModelOption modelOption) {
15 | this.modelOption = modelOption;
16 | }
17 |
18 | public ModelOption getModelOption() {
19 | return modelOption;
20 | }
21 |
22 | public Material getParticleLocation() {
23 | if (modelOption.getParticle() != null)
24 | return new Material(TextureAtlas.LOCATION_BLOCKS, modelOption.getParticle());
25 | return MISSING;
26 | }
27 |
28 | public BlockModel.GuiLight getGuiLight() {
29 | if (modelOption.getGuiLight() == null)
30 | return BlockModel.GuiLight.SIDE;
31 | return modelOption.getGuiLight();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/model/obj/ObjModelLoadedResource.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.model.obj;
2 |
3 | import de.javagl.obj.Mtl;
4 | import de.javagl.obj.Obj;
5 | import dev.felnull.specialmodelloader.api.model.LoadedResource;
6 | import dev.felnull.specialmodelloader.api.model.ModelLoader;
7 | import dev.felnull.specialmodelloader.api.model.obj.ObjModelOption;
8 | import net.minecraft.resources.ResourceLocation;
9 |
10 | import java.util.Map;
11 |
12 | record ObjModelLoadedResource(ResourceLocation location,
13 | Obj obj,
14 | Map mtl,
15 | ObjModelOption option) implements LoadedResource {
16 | @Override
17 | public ModelLoader getLoader() {
18 | return ObjModelLoaderImp.INSTANCE;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/model/obj/ObjModelLoaderImp.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.model.obj;
2 |
3 | import com.google.common.collect.ImmutableList;
4 | import com.google.common.collect.ImmutableMap;
5 | import com.google.gson.JsonObject;
6 | import de.javagl.obj.*;
7 | import dev.felnull.specialmodelloader.api.model.LoadedResource;
8 | import dev.felnull.specialmodelloader.api.model.obj.ObjModelLoader;
9 | import dev.felnull.specialmodelloader.api.model.obj.ObjModelOption;
10 | import dev.felnull.specialmodelloader.impl.SpecialModelLoader;
11 | import net.minecraft.client.resources.model.UnbakedModel;
12 | import net.minecraft.resources.ResourceLocation;
13 | import net.minecraft.server.packs.resources.Resource;
14 | import net.minecraft.server.packs.resources.ResourceManager;
15 | import org.apache.commons.lang3.ArrayUtils;
16 | import org.jetbrains.annotations.NotNull;
17 | import org.jetbrains.annotations.Nullable;
18 |
19 | import java.io.IOException;
20 | import java.util.ArrayList;
21 | import java.util.List;
22 | import java.util.Map;
23 | import java.util.Optional;
24 | import java.util.stream.Collectors;
25 |
26 | public class ObjModelLoaderImp implements ObjModelLoader {
27 | public static final ObjModelLoaderImp INSTANCE = new ObjModelLoaderImp();
28 |
29 | @Override
30 | public @Nullable LoadedResource loadResource(@NotNull ResourceManager resourceManager, @NotNull JsonObject modelJson) {
31 | if (!modelJson.has("model") || !modelJson.get("model").isJsonPrimitive() || !modelJson.getAsJsonPrimitive("model").isString()) {
32 | return null;
33 | }
34 |
35 | ResourceLocation modelLocation = ResourceLocation.parse(modelJson.get("model").getAsString());
36 |
37 | return loadResource(resourceManager, modelLocation, ObjModelOption.parse(modelJson));
38 | }
39 |
40 | @Override
41 | public @Nullable LoadedResource loadResource(@NotNull ResourceManager resourceManager, @NotNull ResourceLocation modelLocation, @NotNull ObjModelOption option) {
42 | Optional res = resourceManager.getResource(modelLocation);
43 |
44 | if (res.isEmpty()) {
45 | return null;
46 | }
47 |
48 | try (var reader = res.get().openAsReader()) {
49 | Obj obj = ObjUtils.convertToRenderable(ObjReader.read(reader));
50 |
51 | ResourceLocation mtlDirLoc;
52 | List mtlFileNames;
53 |
54 | String mtlOverride;
55 | if ((mtlOverride = option.getMtlOverride()) != null) {
56 | String[] overrideSplit = mtlOverride.split("/");
57 |
58 | mtlDirLoc = ResourceLocation.parse(String.join("/", ArrayUtils.remove(overrideSplit, overrideSplit.length - 1)));
59 | mtlFileNames = ImmutableList.of(overrideSplit[overrideSplit.length - 1]);
60 | } else {
61 | String[] mtlDirPaths = modelLocation.getPath().split("/");
62 | mtlDirPaths = ArrayUtils.remove(mtlDirPaths, mtlDirPaths.length - 1);
63 |
64 | mtlDirLoc = ResourceLocation.fromNamespaceAndPath(modelLocation.getNamespace(), String.join("/", mtlDirPaths));
65 | mtlFileNames = obj.getMtlFileNames();
66 | }
67 |
68 | return new ObjModelLoadedResource(modelLocation, obj,
69 | ImmutableMap.copyOf(loadMtl(resourceManager, mtlDirLoc, mtlFileNames)), option);
70 | } catch (IOException e) {
71 | throw new IllegalStateException("Failed to load obj file.", e);
72 | }
73 | }
74 |
75 | @Override
76 | public @NotNull UnbakedModel makeModel(@NotNull LoadedResource loadedResource) {
77 | if (loadedResource instanceof ObjModelLoadedResource objRes) {
78 | return new ObjUnbakedModelModel(objRes.location(), objRes.obj(), objRes.mtl(), objRes.option());
79 | } else {
80 | throw new IllegalArgumentException("A loaded resource that is not an OBJ model was received as an argument.");
81 | }
82 | }
83 |
84 | private Map loadMtl(ResourceManager resourceManager, ResourceLocation location, List mtlNames) {
85 | return mtlNames.stream()
86 | .flatMap(r -> loadMtl(resourceManager, location, r).stream())
87 | .collect(Collectors.toMap(Mtl::getName, r -> r));
88 | }
89 |
90 | private List loadMtl(ResourceManager resourceManager, ResourceLocation location, String mtlName) {
91 | var loc = ResourceLocation.fromNamespaceAndPath(location.getNamespace(), location.getPath() + "/" + mtlName);
92 | return resourceManager.getResource(loc).map(res -> {
93 | try (var reader = res.openAsReader()) {
94 | return MtlReader.read(reader);
95 | } catch (IOException e) {
96 | SpecialModelLoader.LOGGER.error("Failed to read mtl file.", e);
97 | return new ArrayList();
98 | }
99 | }).orElseGet(List::of);
100 | }
101 |
102 | @Override
103 | public String getId() {
104 | return "obj";
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/model/obj/ObjModelOptionImpl.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.model.obj;
2 |
3 | import com.google.common.collect.ImmutableMap;
4 | import com.google.gson.JsonObject;
5 | import dev.felnull.specialmodelloader.api.model.ModelOption;
6 | import dev.felnull.specialmodelloader.api.model.obj.ObjModelOption;
7 | import dev.felnull.specialmodelloader.impl.util.JsonUtils;
8 | import net.minecraft.client.renderer.block.model.BlockModel;
9 | import net.minecraft.client.renderer.block.model.ItemTransforms;
10 | import net.minecraft.resources.ResourceLocation;
11 | import net.minecraft.util.GsonHelper;
12 | import org.jetbrains.annotations.NotNull;
13 | import org.jetbrains.annotations.Nullable;
14 | import org.jetbrains.annotations.Unmodifiable;
15 |
16 | import java.util.Map;
17 |
18 | public record ObjModelOptionImpl(ModelOption modelOption, boolean flipV, String mtlOverride,
19 | Map textures) implements ObjModelOption {
20 |
21 | public static ObjModelOptionImpl parse(JsonObject modelJson) {
22 | boolean flipV = GsonHelper.getAsBoolean(modelJson, "flip_v", false);
23 | String mtlOverride = GsonHelper.getAsString(modelJson, "mtl_override", null);
24 |
25 | ImmutableMap.Builder textures = ImmutableMap.builder();
26 | if (modelJson.has("textures") && modelJson.get("textures").isJsonObject()) {
27 | JsonObject texturesJo = modelJson.getAsJsonObject("textures");
28 | texturesJo.keySet().forEach(key -> {
29 | ResourceLocation tex = JsonUtils.getResourceLocation(texturesJo, key);
30 | if (tex != null) {
31 | textures.put(key, tex);
32 | }
33 | });
34 | }
35 |
36 | return new ObjModelOptionImpl(ModelOption.parse(modelJson), flipV, mtlOverride, textures.build());
37 | }
38 |
39 | @Override
40 | public boolean isFlipV() {
41 | return flipV;
42 | }
43 |
44 | @Nullable
45 | @Override
46 | public String getMtlOverride() {
47 | return mtlOverride;
48 | }
49 |
50 | @Override
51 | public @Unmodifiable @NotNull Map getTextures() {
52 | return textures;
53 | }
54 |
55 | @Override
56 | public boolean isUseAmbientOcclusion() {
57 | return modelOption.isUseAmbientOcclusion();
58 | }
59 |
60 | @Override
61 | public @Nullable BlockModel.GuiLight getGuiLight() {
62 | return modelOption.getGuiLight();
63 | }
64 |
65 | @Override
66 | public @Nullable ResourceLocation getParticle() {
67 | return modelOption.getParticle();
68 | }
69 |
70 | @Override
71 | public @NotNull ItemTransforms getTransforms() {
72 | return modelOption.getTransforms();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/model/obj/ObjUnbakedModelModel.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.model.obj;
2 |
3 | import de.javagl.obj.Mtl;
4 | import de.javagl.obj.Obj;
5 | import de.javagl.obj.ObjFace;
6 | import de.javagl.obj.ObjSplitting;
7 | import dev.felnull.specialmodelloader.api.model.obj.ObjModelOption;
8 | import dev.felnull.specialmodelloader.impl.SpecialModelLoader;
9 | import dev.felnull.specialmodelloader.impl.model.SimpleMeshModel;
10 | import dev.felnull.specialmodelloader.impl.model.SpecialBaseUnbakedModel;
11 | import net.fabricmc.fabric.api.renderer.v1.Renderer;
12 | import net.fabricmc.fabric.api.renderer.v1.mesh.MutableMesh;
13 | import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
14 | import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
15 | import net.fabricmc.fabric.impl.client.indigo.renderer.IndigoRenderer;
16 | import net.minecraft.client.renderer.block.model.ItemTransforms;
17 | import net.minecraft.client.renderer.block.model.TextureSlots;
18 | import net.minecraft.client.renderer.texture.TextureAtlas;
19 | import net.minecraft.client.resources.model.*;
20 | import net.minecraft.resources.ResourceLocation;
21 | import org.jetbrains.annotations.NotNull;
22 | import org.joml.Vector3f;
23 |
24 | import java.util.Map;
25 |
26 | public class ObjUnbakedModelModel extends SpecialBaseUnbakedModel {
27 | private final ResourceLocation location;
28 | private final Obj obj;
29 | private final Map mtl;
30 | private final ObjModelOption option;
31 |
32 | public ObjUnbakedModelModel(ResourceLocation location, Obj obj, Map mtl, ObjModelOption option) {
33 | super(option);
34 | this.location = location;
35 | this.obj = obj;
36 | this.mtl = mtl;
37 | this.option = option;
38 | }
39 |
40 | @Override
41 | public void resolveDependencies(Resolver resolver) {
42 | }
43 |
44 | @Override
45 | public @NotNull BakedModel bake(TextureSlots textureSlots, ModelBaker baker, ModelState modelState, boolean hasAmbientOcclusion, boolean useBlockLight, ItemTransforms transforms) {
46 | Renderer renderer = Renderer.get();
47 |
48 | if (renderer == null) {
49 | SpecialModelLoader.LOGGER.warn("IndigoRenderer is used since the Renderer cannot be obtained. ({})", location);
50 | renderer = IndigoRenderer.INSTANCE;
51 | }
52 |
53 | MutableMesh builder = renderer.mutableMesh();
54 | QuadEmitter emitter = builder.emitter();
55 | SpriteGetter spriteGetter = baker.sprites();
56 | Map materialGroups = ObjSplitting.splitByMaterialGroups(obj);
57 |
58 | materialGroups.forEach((name, model) -> {
59 | for (int i = 0; i < model.getNumFaces(); i++) {
60 | emitFace(emitter, modelState, spriteGetter, name, model, model.getFace(i));
61 | }
62 | });
63 |
64 | return new SimpleMeshModel(
65 | getModelOption().isUseAmbientOcclusion(),
66 | getGuiLight().lightLikeBlock(),
67 | spriteGetter.get(getParticleLocation()),
68 | getModelOption().getTransforms(),
69 | builder.immutableCopy()
70 | );
71 | }
72 |
73 | private void emitFace(QuadEmitter emitter, ModelState modelState, SpriteGetter spriteGetter, String materialName, Obj fObj, ObjFace face) {
74 | for (int i = 0; i < face.getNumVertices(); i++) {
75 | emitVertex(i, i, emitter, modelState, fObj, face);
76 | }
77 |
78 | if (face.getNumVertices() == 3)
79 | emitVertex(3, 2, emitter, modelState, fObj, face);
80 |
81 | var smtl = mtl.get(materialName);
82 |
83 | int flg = MutableQuadView.BAKE_NORMALIZED;
84 |
85 | if (option.isFlipV())
86 | flg |= MutableQuadView.BAKE_FLIP_V;
87 |
88 | if (modelState.isUvLocked())
89 | flg |= MutableQuadView.BAKE_LOCK_UV;
90 |
91 | ResourceLocation texLoc = null;
92 | String tex;
93 | if (smtl != null && (tex = smtl.getMapKd()) != null) {
94 | if (tex.startsWith("#")) {
95 | texLoc = option.getTextures().get(tex.substring(1));
96 | } else {
97 | texLoc = ResourceLocation.parse(tex);
98 | }
99 | }
100 |
101 | if (texLoc != null) {
102 | emitter.spriteBake(spriteGetter.get(new Material(TextureAtlas.LOCATION_BLOCKS, texLoc)), flg);
103 | } else {
104 | emitter.spriteBake(spriteGetter.get(MISSING), flg);
105 | }
106 |
107 | emitter.color(-1, -1, -1, -1);
108 |
109 | emitter.emit();
110 | }
111 |
112 | private void emitVertex(int index, int vertexNum, QuadEmitter emitter, ModelState modelState, Obj fObj, ObjFace face) {
113 | var vt = fObj.getVertex(face.getVertexIndex(vertexNum));
114 | var vertex = new Vector3f(vt.getX(), vt.getY(), vt.getZ());
115 |
116 | vertex.add(-0.5f, -0.5f, -0.5f);
117 | vertex.rotate(modelState.getRotation().getLeftRotation());
118 | vertex.add(0.5f, 0.5f, 0.5f);
119 |
120 | var normal = fObj.getNormal(face.getNormalIndex(vertexNum));
121 | var tex = fObj.getTexCoord(face.getTexCoordIndex(vertexNum));
122 |
123 | emitter.pos(index, vertex.x(), vertex.y(), vertex.z())
124 | .normal(index, normal.getX(), normal.getY(), normal.getZ())
125 | .uv(index, tex.getX(), tex.getY());
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/model/obj/package-info.java:
--------------------------------------------------------------------------------
1 | @ApiStatus.Internal
2 | package dev.felnull.specialmodelloader.impl.model.obj;
3 |
4 | import org.jetbrains.annotations.ApiStatus;
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/model/package-info.java:
--------------------------------------------------------------------------------
1 | @ApiStatus.Internal
2 | package dev.felnull.specialmodelloader.impl.model;
3 |
4 | import org.jetbrains.annotations.ApiStatus;
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/package-info.java:
--------------------------------------------------------------------------------
1 | @ApiStatus.Internal
2 | package dev.felnull.specialmodelloader.impl;
3 |
4 | import org.jetbrains.annotations.ApiStatus;
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/util/JsonUtils.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl.util;
2 |
3 | import com.google.gson.JsonObject;
4 | import net.minecraft.resources.ResourceLocation;
5 | import net.minecraft.util.GsonHelper;
6 |
7 | public class JsonUtils {
8 | public static ResourceLocation getParentLocation(JsonObject modelJson) {
9 | if (modelJson == null)
10 | return null;
11 |
12 | if (modelJson.has("parent"))
13 | return ResourceLocation.parse(GsonHelper.getAsString(modelJson, "parent"));
14 | return null;
15 | }
16 |
17 | public static ResourceLocation getResourceLocation(JsonObject jsonObject, String name) {
18 | if (jsonObject.has(name) && jsonObject.get(name).isJsonPrimitive() && jsonObject.getAsJsonPrimitive(name).isString()) {
19 | return ResourceLocation.parse(jsonObject.get(name).getAsString());
20 | }
21 | return null;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/client/java/dev/felnull/specialmodelloader/impl/util/package-info.java:
--------------------------------------------------------------------------------
1 | @ApiStatus.Internal
2 | package dev.felnull.specialmodelloader.impl.util;
3 |
4 | import org.jetbrains.annotations.ApiStatus;
--------------------------------------------------------------------------------
/src/client/resources/special-model-loader.mixins.json:
--------------------------------------------------------------------------------
1 | {
2 | "required": true,
3 | "package": "dev.felnull.specialmodelloader.impl.mixin",
4 | "compatibilityLevel": "JAVA_21",
5 | "client": [
6 | "BlockModelAccessor"
7 | ],
8 | "injectors": {
9 | "defaultRequire": 1
10 | }
11 | }
--------------------------------------------------------------------------------
/src/main/java/dev/felnull/specialmodelloader/impl/SpecialModelLoader.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.specialmodelloader.impl;
2 |
3 | import org.apache.logging.log4j.LogManager;
4 | import org.apache.logging.log4j.Logger;
5 |
6 | public class SpecialModelLoader {
7 | public static final Logger LOGGER = LogManager.getLogger(SpecialModelLoader.class);
8 | public static final String MODID = "special-model-loader";
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/resources/assets/special-model-loader/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/main/resources/assets/special-model-loader/icon.png
--------------------------------------------------------------------------------
/src/main/resources/fabric.mod.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": 1,
3 | "id": "special-model-loader",
4 | "version": "${version}",
5 | "name": "Special Model Loader",
6 | "description": "Support for loading special models.\nThe ikisugi model loader mod...",
7 | "authors": [
8 | "MORIMORI0317",
9 | "FelNull Developers"
10 | ],
11 | "contributors": [
12 | "StarBoyCeleste",
13 | "MerlinDaWizard"
14 | ],
15 | "contact": {
16 | "email": "teamfelnull@felnull.dev",
17 | "homepage": "https://modrinth.com/mod/special-model-loader",
18 | "sources": "https://github.com/TeamFelnull/SpecialModelLoader",
19 | "issues": "https://github.com/TeamFelnull/SpecialModelLoader/issues"
20 | },
21 | "license": "MIT License",
22 | "icon": "assets/special-model-loader/icon.png",
23 | "environment": "client",
24 | "entrypoints": {
25 | "client": [
26 | "dev.felnull.specialmodelloader.impl.SpecialModelLoaderClient"
27 | ]
28 | },
29 | "mixins": [
30 | {
31 | "config": "special-model-loader.mixins.json",
32 | "environment": "client"
33 | }
34 | ],
35 | "depends": {
36 | "fabricloader": ">=0.16.9",
37 | "minecraft": ">=1.21.4",
38 | "java": ">=21",
39 | "fabric-api": "*"
40 | },
41 | "custom": {
42 | "modmenu": {
43 | "badges": [
44 | "library"
45 | ]
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/src/test/generated/.cache/d26dbd274f1ce9df6c32c695a40e10fe4203dafa:
--------------------------------------------------------------------------------
1 | // 1.21.4 -999999999-01-01T00:00:00 Special Model Loader Test/Model Definitions
2 | 2fe12a7b7f26a1434370749403837d2301d330c4 assets/special-model-loader-test/blockstates/facing_model_block.json
3 | 2026021089f1eb67bb59680a39566b65319b9c1d assets/special-model-loader-test/blockstates/facing_obj_model_block.json
4 | 09d86e9b817b52a30a7afdc219645cb7f67cd5c8 assets/special-model-loader-test/blockstates/normal_model_block.json
5 | 2a6689e3962f0c56716ee7a2840038d8e1c6f65d assets/special-model-loader-test/items/facing_model_block.json
6 | db12e0af083675fa1ab711028e4f2d7fe81d7644 assets/special-model-loader-test/items/facing_obj_model_block.json
7 | 5da9262165426aa448e0b149c06cb5baf1f2d119 assets/special-model-loader-test/items/mtloverride_obj_model_item.json
8 | e9bb5e2f398bccd6253053b120344d1b7b0b7385 assets/special-model-loader-test/items/normal_model_block.json
9 | 1fd027e47bb05c0928fc934bcf6c3cfb85ad90b8 assets/special-model-loader-test/items/normal_model_item.json
10 | 0ca9dcce673b914bf2c74024d4b2b7ef7303d268 assets/special-model-loader-test/items/obj_model_block.json
11 | 08d17fdf5d40bca50f52581e517c952a837994a5 assets/special-model-loader-test/items/obj_model_item.json
12 | b744e088d55e2ea5a1d9ea27b93c720a3356e8ec assets/special-model-loader-test/items/textures_obj_model_item.json
13 | e61360716d4882fb639d854551e14f9a9130c6ac assets/special-model-loader-test/models/block/facing_model_block.json
14 | d8c8c782516cf0bc564998dcaed70a1592d59fb7 assets/special-model-loader-test/models/block/normal_model_block.json
15 | 900ce8dcc85cb9354e94b586092cb1fb2c2bc204 assets/special-model-loader-test/models/item/mtloverride_obj_model_item.json
16 | 29b5a4f3bf537fd7d26d638c82162277ceed8152 assets/special-model-loader-test/models/item/normal_model_item.json
17 | 92aa0969bc41ff465724c5cce1982fc91c53a428 assets/special-model-loader-test/models/item/obj_model_item.json
18 | b86b8a89c6b8c2cd5f75410589c716570e9c4b7d assets/special-model-loader-test/models/item/textures_obj_model_item.json
19 |
--------------------------------------------------------------------------------
/src/test/generated/assets/special-model-loader-test/blockstates/facing_model_block.json:
--------------------------------------------------------------------------------
1 | {
2 | "variants": {
3 | "facing=east": {
4 | "model": "special-model-loader-test:block/facing_model_block",
5 | "y": 90
6 | },
7 | "facing=north": {
8 | "model": "special-model-loader-test:block/facing_model_block"
9 | },
10 | "facing=south": {
11 | "model": "special-model-loader-test:block/facing_model_block",
12 | "y": 180
13 | },
14 | "facing=west": {
15 | "model": "special-model-loader-test:block/facing_model_block",
16 | "y": 270
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/test/generated/assets/special-model-loader-test/blockstates/facing_obj_model_block.json:
--------------------------------------------------------------------------------
1 | {
2 | "variants": {
3 | "facing=east": {
4 | "model": "special-model-loader-test:block/obj_model_block",
5 | "y": 90
6 | },
7 | "facing=north": {
8 | "model": "special-model-loader-test:block/obj_model_block"
9 | },
10 | "facing=south": {
11 | "model": "special-model-loader-test:block/obj_model_block",
12 | "y": 180
13 | },
14 | "facing=west": {
15 | "model": "special-model-loader-test:block/obj_model_block",
16 | "y": 270
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/test/generated/assets/special-model-loader-test/blockstates/normal_model_block.json:
--------------------------------------------------------------------------------
1 | {
2 | "variants": {
3 | "": {
4 | "model": "special-model-loader-test:block/normal_model_block"
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/src/test/generated/assets/special-model-loader-test/models/block/facing_model_block.json:
--------------------------------------------------------------------------------
1 | {
2 | "parent": "minecraft:block/orientable",
3 | "textures": {
4 | "front": "special-model-loader-test:block/facing_model_block_front",
5 | "side": "special-model-loader-test:block/facing_model_block_side",
6 | "top": "special-model-loader-test:block/facing_model_block_top"
7 | }
8 | }
--------------------------------------------------------------------------------
/src/test/generated/assets/special-model-loader-test/models/block/normal_model_block.json:
--------------------------------------------------------------------------------
1 | {
2 | "parent": "minecraft:block/cube_all",
3 | "textures": {
4 | "all": "special-model-loader-test:block/normal_model_block"
5 | }
6 | }
--------------------------------------------------------------------------------
/src/test/generated/assets/special-model-loader-test/models/item/mtloverride_obj_model_item.json:
--------------------------------------------------------------------------------
1 | {
2 | "parent": "special-model-loader:builtin/obj",
3 | "ambientocclusion": false,
4 | "flip_v": true,
5 | "model": "special-model-loader-test:models/item/ring/ring.obj",
6 | "mtl_override": "special-model-loader-test:models/item/ring/ring_2.mtl"
7 | }
--------------------------------------------------------------------------------
/src/test/generated/assets/special-model-loader-test/models/item/normal_model_item.json:
--------------------------------------------------------------------------------
1 | {
2 | "parent": "minecraft:item/generated",
3 | "textures": {
4 | "layer0": "special-model-loader-test:item/normal_model_item"
5 | }
6 | }
--------------------------------------------------------------------------------
/src/test/generated/assets/special-model-loader-test/models/item/obj_model_item.json:
--------------------------------------------------------------------------------
1 | {
2 | "parent": "special-model-loader:builtin/obj",
3 | "ambientocclusion": false,
4 | "flip_v": true,
5 | "model": "special-model-loader-test:models/item/sea_cheken_pack/sea_chicken.obj"
6 | }
--------------------------------------------------------------------------------
/src/test/generated/assets/special-model-loader-test/models/item/textures_obj_model_item.json:
--------------------------------------------------------------------------------
1 | {
2 | "parent": "special-model-loader:builtin/obj",
3 | "ambientocclusion": false,
4 | "flip_v": true,
5 | "model": "special-model-loader-test:models/item/ring/ring.obj",
6 | "textures": {
7 | "texture0": "minecraft:block/cobblestone"
8 | }
9 | }
--------------------------------------------------------------------------------
/src/test/java/dev/felnull/smltest/SMLTest.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.smltest;
2 |
3 | import dev.felnull.smltest.block.SMLTestBlocks;
4 | import dev.felnull.smltest.item.SMLTestItems;
5 | import net.fabricmc.api.ModInitializer;
6 |
7 | public class SMLTest implements ModInitializer {
8 | public static final String MODID = "special-model-loader-test";
9 |
10 | @Override
11 | public void onInitialize() {
12 | SMLTestItems.init();
13 | SMLTestBlocks.init();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/test/java/dev/felnull/smltest/block/FacingBlock.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.smltest.block;
2 |
3 | import net.minecraft.core.Direction;
4 | import net.minecraft.world.item.context.BlockPlaceContext;
5 | import net.minecraft.world.level.block.Block;
6 | import net.minecraft.world.level.block.HorizontalDirectionalBlock;
7 | import net.minecraft.world.level.block.Mirror;
8 | import net.minecraft.world.level.block.Rotation;
9 | import net.minecraft.world.level.block.state.BlockState;
10 | import net.minecraft.world.level.block.state.StateDefinition;
11 | import net.minecraft.world.level.block.state.properties.EnumProperty;
12 | import org.jetbrains.annotations.Nullable;
13 |
14 | public class FacingBlock extends Block {
15 | public static final EnumProperty FACING = HorizontalDirectionalBlock.FACING;
16 |
17 | public FacingBlock(Properties properties) {
18 | super(properties);
19 | this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH));
20 | }
21 |
22 | @Nullable
23 | @Override
24 | public BlockState getStateForPlacement(BlockPlaceContext blockPlaceContext) {
25 | return this.defaultBlockState().setValue(FACING, blockPlaceContext.getHorizontalDirection().getOpposite());
26 | }
27 |
28 | @Override
29 | public BlockState rotate(BlockState blockState, Rotation rotation) {
30 | return blockState.setValue(FACING, rotation.rotate(blockState.getValue(FACING)));
31 | }
32 |
33 | @Override
34 | public BlockState mirror(BlockState blockState, Mirror mirror) {
35 | return blockState.rotate(mirror.getRotation(blockState.getValue(FACING)));
36 | }
37 |
38 | @Override
39 | protected void createBlockStateDefinition(StateDefinition.Builder builder) {
40 | builder.add(FACING);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/test/java/dev/felnull/smltest/block/SMLTestBlocks.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.smltest.block;
2 |
3 | import dev.felnull.smltest.SMLTest;
4 | import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
5 | import net.minecraft.core.registries.Registries;
6 | import net.minecraft.resources.ResourceKey;
7 | import net.minecraft.resources.ResourceLocation;
8 | import net.minecraft.world.item.CreativeModeTabs;
9 | import net.minecraft.world.item.Items;
10 | import net.minecraft.world.level.block.Block;
11 | import net.minecraft.world.level.block.Blocks;
12 | import net.minecraft.world.level.block.SoundType;
13 | import net.minecraft.world.level.block.state.BlockBehaviour;
14 | import net.minecraft.world.level.material.MapColor;
15 |
16 | import java.util.function.Function;
17 |
18 | public class SMLTestBlocks {
19 | public static final Block NORMAL_MODEL_BLOCK = register("normal_model_block", Block::new, BlockBehaviour.Properties.of().sound(SoundType.AMETHYST).mapColor(MapColor.DEEPSLATE));
20 | public static final Block OBJ_MODEL_BLOCK = register("obj_model_block", Block::new, BlockBehaviour.Properties.of().sound(SoundType.AMETHYST).mapColor(MapColor.DEEPSLATE));
21 | public static final Block FACING_MODEL_BLOCK = register("facing_model_block", FacingBlock::new, BlockBehaviour.Properties.of().sound(SoundType.AMETHYST).mapColor(MapColor.DEEPSLATE));
22 | public static final Block FACING_OBJ_MODEL_BLOCK = register("facing_obj_model_block", FacingBlock::new, BlockBehaviour.Properties.of().sound(SoundType.AMETHYST).mapColor(MapColor.DEEPSLATE));
23 |
24 | public static void init() {
25 | ItemGroupEvents.modifyEntriesEvent(CreativeModeTabs.BUILDING_BLOCKS).register(ct -> {
26 | ct.accept(NORMAL_MODEL_BLOCK);
27 | ct.accept(OBJ_MODEL_BLOCK);
28 | ct.accept(FACING_MODEL_BLOCK);
29 | ct.accept(FACING_OBJ_MODEL_BLOCK);
30 | });
31 | }
32 |
33 | public static Block register(String name, Function factory, BlockBehaviour.Properties properties) {
34 | ResourceKey resKey = ResourceKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath(SMLTest.MODID, name));
35 | Block block = Blocks.register(resKey, factory, properties);
36 | Items.registerBlock(block);
37 | return block;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/test/java/dev/felnull/smltest/client/DynamicObjModelItemSpecialRenderer.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.smltest.client;
2 |
3 | import com.mojang.blaze3d.vertex.PoseStack;
4 | import com.mojang.blaze3d.vertex.VertexConsumer;
5 | import com.mojang.math.Axis;
6 | import com.mojang.serialization.MapCodec;
7 | import net.minecraft.client.Minecraft;
8 | import net.minecraft.client.model.geom.EntityModelSet;
9 | import net.minecraft.client.renderer.MultiBufferSource;
10 | import net.minecraft.client.renderer.Sheets;
11 | import net.minecraft.client.renderer.special.NoDataSpecialModelRenderer;
12 | import net.minecraft.client.renderer.special.SpecialModelRenderer;
13 | import net.minecraft.client.resources.model.BakedModel;
14 | import net.minecraft.world.item.ItemDisplayContext;
15 | import org.jetbrains.annotations.NotNull;
16 |
17 | import java.util.Objects;
18 | import java.util.function.Consumer;
19 |
20 | public class DynamicObjModelItemSpecialRenderer implements NoDataSpecialModelRenderer {
21 |
22 | @Override
23 | public void render(ItemDisplayContext displayContext, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay, boolean hasFoilType) {
24 | poseStack.pushPose();
25 |
26 | poseCenterConsumer(poseStack, 0.5f, 0.5f, 0.5f, pose -> {
27 | poseRotateX(poseStack, 360f * (float) (System.currentTimeMillis() % 10000) / 10000f);
28 | poseRotateY(poseStack, 360f * (float) (System.currentTimeMillis() % 20000) / 20000f);
29 | poseRotateZ(poseStack, 360f * (float) (System.currentTimeMillis() % 30000) / 30000f);
30 | });
31 |
32 | var model = Minecraft.getInstance().getModelManager().getModel(SMLTestClient.TEST_OBJ_MODEL);
33 | var vc = bufferSource.getBuffer(Sheets.solidBlockSheet());
34 | renderModel(poseStack, vc, model, packedLight, packedOverlay);
35 |
36 | poseStack.popPose();
37 | }
38 |
39 | public static void poseCenterConsumer(@NotNull PoseStack poseStack, float centerX, float centerY, float centerZ, @NotNull Consumer poseStackConsumer) {
40 | poseStack.translate(centerX, centerY, centerZ);
41 | poseStackConsumer.accept(poseStack);
42 | poseStack.translate(-centerX, -centerY, -centerZ);
43 | }
44 |
45 | public static void renderModel(PoseStack poseStack, VertexConsumer vertexConsumer, @NotNull BakedModel bakedModel, int combinedLight, int combinedOverlay) {
46 | Objects.requireNonNull(bakedModel);
47 | var bmr = Minecraft.getInstance().getBlockRenderer().getModelRenderer();
48 | bmr.renderModel(poseStack.last(), vertexConsumer, null, bakedModel, 1.0F, 1.0F, 1.0F, combinedLight, combinedOverlay);
49 | }
50 |
51 | public static void poseRotateX(@NotNull PoseStack poseStack, float angle) {
52 | poseStack.mulPose(Axis.XP.rotationDegrees(angle));
53 | }
54 |
55 | public static void poseRotateY(@NotNull PoseStack poseStack, float angle) {
56 | poseStack.mulPose(Axis.YP.rotationDegrees(angle));
57 | }
58 |
59 | public static void poseRotateZ(@NotNull PoseStack poseStack, float angle) {
60 | poseStack.mulPose(Axis.ZP.rotationDegrees(angle));
61 | }
62 |
63 | public record Unbaked() implements SpecialModelRenderer.Unbaked {
64 | public static final MapCodec MAP_CODEC = MapCodec.unit(new Unbaked());
65 |
66 | @Override
67 | public @NotNull SpecialModelRenderer> bake(EntityModelSet modelSet) {
68 | return new DynamicObjModelItemSpecialRenderer();
69 | }
70 |
71 | @Override
72 | public @NotNull MapCodec extends SpecialModelRenderer.Unbaked> type() {
73 | return MAP_CODEC;
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/test/java/dev/felnull/smltest/client/SMLTestClient.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.smltest.client;
2 |
3 | import dev.felnull.smltest.SMLTest;
4 | import dev.felnull.specialmodelloader.api.event.SpecialModelLoaderEvents;
5 | import net.fabricmc.api.ClientModInitializer;
6 | import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin;
7 | import net.minecraft.client.renderer.special.SpecialModelRenderers;
8 | import net.minecraft.resources.ResourceLocation;
9 |
10 | public class SMLTestClient implements ClientModInitializer {
11 | public static final ResourceLocation TEST_OBJ_MODEL = ResourceLocation.fromNamespaceAndPath(SMLTest.MODID, "item/obj_model_item_dynamic");
12 |
13 | @Override
14 | public void onInitializeClient() {
15 | SpecialModelLoaderEvents.LOAD_SCOPE.register(() -> (resManager, location) -> SMLTest.MODID.equals(location.getNamespace()));
16 | ModelLoadingPlugin.register(pluginContext -> pluginContext.addModels(TEST_OBJ_MODEL));
17 |
18 | SpecialModelRenderers.ID_MAPPER.put(
19 | ResourceLocation.fromNamespaceAndPath(SMLTest.MODID, "dynamic_obj_model_item"),
20 | DynamicObjModelItemSpecialRenderer.Unbaked.MAP_CODEC
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/test/java/dev/felnull/smltest/data/SMLTestDataGenerator.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.smltest.data;
2 |
3 | import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
4 | import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
5 |
6 | public class SMLTestDataGenerator implements DataGeneratorEntrypoint {
7 | @Override
8 | public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) {
9 | var pack = fabricDataGenerator.createPack();
10 | pack.addProvider(SMLTestModelProvider::new);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/test/java/dev/felnull/smltest/data/SMLTestModelProvider.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.smltest.data;
2 |
3 | import com.google.common.collect.ImmutableMap;
4 | import dev.felnull.smltest.SMLTest;
5 | import dev.felnull.smltest.block.SMLTestBlocks;
6 | import dev.felnull.smltest.item.SMLTestItems;
7 | import dev.felnull.specialmodelloader.api.data.SpecialModelDataGenHelper;
8 | import net.fabricmc.fabric.api.client.datagen.v1.provider.FabricModelProvider;
9 | import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
10 | import net.minecraft.client.data.models.BlockModelGenerators;
11 | import net.minecraft.client.data.models.ItemModelGenerators;
12 | import net.minecraft.client.data.models.blockstates.MultiVariantGenerator;
13 | import net.minecraft.client.data.models.blockstates.Variant;
14 | import net.minecraft.client.data.models.blockstates.VariantProperties;
15 | import net.minecraft.client.data.models.model.ItemModelUtils;
16 | import net.minecraft.client.data.models.model.ModelLocationUtils;
17 | import net.minecraft.client.data.models.model.ModelTemplates;
18 | import net.minecraft.client.data.models.model.TexturedModel;
19 | import net.minecraft.resources.ResourceLocation;
20 | import net.minecraft.world.level.block.Block;
21 |
22 | public class SMLTestModelProvider extends FabricModelProvider {
23 |
24 | public SMLTestModelProvider(FabricDataOutput output) {
25 | super(output);
26 | }
27 |
28 | @Override
29 | public void generateBlockStateModels(BlockModelGenerators blockStateModelGenerator) {
30 | blockStateModelGenerator.createTrivialCube(SMLTestBlocks.NORMAL_MODEL_BLOCK);
31 |
32 | createFacing(blockStateModelGenerator, SMLTestBlocks.FACING_MODEL_BLOCK);
33 |
34 | blockStateModelGenerator.blockStateOutput.accept(MultiVariantGenerator.multiVariant(SMLTestBlocks.FACING_OBJ_MODEL_BLOCK, Variant.variant().with(VariantProperties.MODEL, ModelLocationUtils.getModelLocation(SMLTestBlocks.OBJ_MODEL_BLOCK, "")))
35 | .with(BlockModelGenerators.createHorizontalFacingDispatch()));
36 | }
37 |
38 | private void createFacing(BlockModelGenerators blockStateModelGenerator, Block block) {
39 | var r = TexturedModel.ORIENTABLE_ONLY_TOP.create(SMLTestBlocks.FACING_MODEL_BLOCK, blockStateModelGenerator.modelOutput);
40 |
41 | blockStateModelGenerator.blockStateOutput.accept(MultiVariantGenerator.multiVariant(block, Variant.variant().with(VariantProperties.MODEL, r))
42 | .with(BlockModelGenerators.createHorizontalFacingDispatch()));
43 | }
44 |
45 | @Override
46 | public void generateItemModels(ItemModelGenerators itemModelGenerator) {
47 | itemModelGenerator.generateFlatItem(SMLTestItems.NORMAL_MODEL_ITEM, ModelTemplates.FLAT_ITEM);
48 |
49 | SpecialModelDataGenHelper.generateObjModel(SMLTestItems.OBJ_MODEL_ITEM, ResourceLocation.fromNamespaceAndPath(SMLTest.MODID, "models/item/sea_cheken_pack/sea_chicken.obj"),
50 | true, false, null, ImmutableMap.of(),
51 | null, itemModelGenerator.modelOutput);
52 | itemModelGenerator.itemModelOutput.accept(SMLTestItems.OBJ_MODEL_ITEM,
53 | ItemModelUtils.plainModel(ModelLocationUtils.getModelLocation(SMLTestItems.OBJ_MODEL_ITEM)));
54 |
55 | SpecialModelDataGenHelper.generateObjModel(SMLTestItems.MTLOVERRIDE_OBJ_MODEL_ITEM,
56 | ResourceLocation.fromNamespaceAndPath(SMLTest.MODID, "models/item/ring/ring.obj"),
57 | true, false, SMLTest.MODID + ":models/item/ring/ring_2.mtl", ImmutableMap.of(),
58 | null, itemModelGenerator.modelOutput);
59 | itemModelGenerator.itemModelOutput.accept(SMLTestItems.MTLOVERRIDE_OBJ_MODEL_ITEM,
60 | ItemModelUtils.plainModel(ModelLocationUtils.getModelLocation(SMLTestItems.MTLOVERRIDE_OBJ_MODEL_ITEM)));
61 |
62 | SpecialModelDataGenHelper.generateObjModel(SMLTestItems.TEXTURES_OBJ_MODEL_ITEM,
63 | ResourceLocation.fromNamespaceAndPath(SMLTest.MODID, "models/item/ring/ring.obj"),
64 | true, false, null, ImmutableMap.of("texture0", ResourceLocation.withDefaultNamespace("block/cobblestone")),
65 | null, itemModelGenerator.modelOutput);
66 | itemModelGenerator.itemModelOutput.accept(SMLTestItems.TEXTURES_OBJ_MODEL_ITEM,
67 | ItemModelUtils.plainModel(ModelLocationUtils.getModelLocation(SMLTestItems.TEXTURES_OBJ_MODEL_ITEM)));
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/test/java/dev/felnull/smltest/item/SMLTestItems.java:
--------------------------------------------------------------------------------
1 | package dev.felnull.smltest.item;
2 |
3 | import dev.felnull.smltest.SMLTest;
4 | import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
5 | import net.minecraft.core.registries.Registries;
6 | import net.minecraft.resources.ResourceKey;
7 | import net.minecraft.resources.ResourceLocation;
8 | import net.minecraft.world.item.CreativeModeTabs;
9 | import net.minecraft.world.item.Item;
10 | import net.minecraft.world.item.Items;
11 |
12 | import java.util.function.Function;
13 |
14 | public class SMLTestItems {
15 | public static final Item NORMAL_MODEL_ITEM = register("normal_model_item", Item::new, new Item.Properties());
16 | public static final Item OBJ_MODEL_ITEM = register("obj_model_item", Item::new, new Item.Properties());
17 | public static final Item OBJ2_MODEL_ITEM = register("obj2_model_item", Item::new, new Item.Properties());
18 | public static final Item FORGE_OBJ_MODEL_ITEM = register("forge_obj_model_item", Item::new, new Item.Properties());
19 | public static final Item DYNAMIC_OBJ_MODEL_ITEM = register("dynamic_obj_model_item", Item::new, new Item.Properties());
20 | public static final Item MTLOVERRIDE_OBJ_MODEL_ITEM = register("mtloverride_obj_model_item", Item::new, new Item.Properties());
21 | public static final Item TEXTURES_OBJ_MODEL_ITEM = register("textures_obj_model_item", Item::new, new Item.Properties());
22 |
23 | public static void init() {
24 | ItemGroupEvents.modifyEntriesEvent(CreativeModeTabs.BUILDING_BLOCKS).register(ct -> {
25 | ct.accept(NORMAL_MODEL_ITEM);
26 | ct.accept(OBJ_MODEL_ITEM);
27 | ct.accept(OBJ2_MODEL_ITEM);
28 | ct.accept(FORGE_OBJ_MODEL_ITEM);
29 | ct.accept(DYNAMIC_OBJ_MODEL_ITEM);
30 | ct.accept(MTLOVERRIDE_OBJ_MODEL_ITEM);
31 | ct.accept(TEXTURES_OBJ_MODEL_ITEM);
32 | });
33 | }
34 |
35 | public static Item register(String name, Function factory, Item.Properties properties) {
36 | ResourceKey- resKey = ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(SMLTest.MODID, name));
37 | return Items.registerItem(resKey, factory, properties);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/blockstates/obj_model_block.json:
--------------------------------------------------------------------------------
1 | {
2 | "variants": {
3 | "": {
4 | "model": "special-model-loader-test:block/obj_model_block"
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/items/dynamic_obj_model_item.json:
--------------------------------------------------------------------------------
1 | {
2 | "model": {
3 | "type": "minecraft:special",
4 | "base": "special-model-loader-test:item/dynamic_obj_model_item",
5 | "model": {
6 | "type": "special-model-loader-test:dynamic_obj_model_item"
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/items/forge_obj_model_item.json:
--------------------------------------------------------------------------------
1 | {
2 | "model": {
3 | "type": "minecraft:model",
4 | "model": "special-model-loader-test:item/forge_obj_model_item"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/items/obj2_model_item.json:
--------------------------------------------------------------------------------
1 | {
2 | "model": {
3 | "type": "minecraft:model",
4 | "model": "special-model-loader-test:item/obj2_model_item"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/block/apple/apple.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'None'
2 | # Material Count: 6
3 |
4 | newmtl body
5 | Ns 225.000000
6 | Ka 1.000000 1.000000 1.000000
7 | Kd 0.800000 0.800000 0.800000
8 | Ks 0.500000 0.500000 0.500000
9 | Ke 0.000000 0.000000 0.000000
10 | Ni 1.450000
11 | d 1.000000
12 | illum 2
13 | map_Kd special-model-loader-test:block/body
14 |
15 | newmtl eda
16 | Ns 225.000000
17 | Ka 1.000000 1.000000 1.000000
18 | Kd 0.310813 0.122194 0.018597
19 | Ks 0.500000 0.500000 0.500000
20 | Ke 0.000000 0.000000 0.000000
21 | Ni 1.450000
22 | d 1.000000
23 | illum 2
24 |
25 | newmtl ha
26 | Ns 225.000000
27 | Ka 1.000000 1.000000 1.000000
28 | Kd 0.005605 0.318547 0.005605
29 | Ks 0.500000 0.500000 0.500000
30 | Ke 0.000000 0.000000 0.000000
31 | Ni 1.450000
32 | d 1.000000
33 | illum 2
34 |
35 | newmtl ikisugi
36 | Ns 225.000000
37 | Ka 1.000000 1.000000 1.000000
38 | Kd 0.800000 0.800000 0.800000
39 | Ks 0.500000 0.500000 0.500000
40 | Ke 0.000000 0.000000 0.000000
41 | Ni 1.450000
42 | d 1.000000
43 | illum 2
44 | map_Kd special-model-loader-test:block/eay
45 |
46 | newmtl ikisugi.002
47 | Ns 225.000000
48 | Ka 1.000000 1.000000 1.000000
49 | Kd 0.800000 0.800000 0.800000
50 | Ks 0.500000 0.500000 0.500000
51 | Ke 0.000000 0.000000 0.000000
52 | Ni 1.450000
53 | d 1.000000
54 | illum 2
55 | map_Kd special-model-loader-test:block/eay
56 |
57 | newmtl te
58 | Ns 225.000000
59 | Ka 1.000000 1.000000 1.000000
60 | Kd 0.000000 0.000000 0.000000
61 | Ks 0.500000 0.500000 0.500000
62 | Ke 0.000000 0.000000 0.000000
63 | Ni 1.450000
64 | d 1.000000
65 | illum 2
66 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/block/obj_model_block.json:
--------------------------------------------------------------------------------
1 | {
2 | "parent": "special-model-loader:builtin/obj",
3 | "model": "special-model-loader-test:models/block/apple/apple.obj",
4 | "gui_light": "side",
5 | "particle": "block/sand",
6 | "display": {
7 | "gui": {
8 | "rotation": [
9 | 30,
10 | 225,
11 | 0
12 | ],
13 | "translation": [
14 | 0,
15 | 0,
16 | 0
17 | ],
18 | "scale": [
19 | 0.625,
20 | 0.625,
21 | 0.625
22 | ]
23 | },
24 | "ground": {
25 | "rotation": [
26 | 0,
27 | 0,
28 | 0
29 | ],
30 | "translation": [
31 | 0,
32 | 3,
33 | 0
34 | ],
35 | "scale": [
36 | 0.25,
37 | 0.25,
38 | 0.25
39 | ]
40 | },
41 | "fixed": {
42 | "rotation": [
43 | 0,
44 | 0,
45 | 0
46 | ],
47 | "translation": [
48 | 0,
49 | 0,
50 | 0
51 | ],
52 | "scale": [
53 | 0.5,
54 | 0.5,
55 | 0.5
56 | ]
57 | },
58 | "thirdperson_righthand": {
59 | "rotation": [
60 | 75,
61 | 45,
62 | 0
63 | ],
64 | "translation": [
65 | 0,
66 | 2.5,
67 | 0
68 | ],
69 | "scale": [
70 | 0.375,
71 | 0.375,
72 | 0.375
73 | ]
74 | },
75 | "firstperson_righthand": {
76 | "rotation": [
77 | 0,
78 | 45,
79 | 0
80 | ],
81 | "translation": [
82 | 0,
83 | 0,
84 | 0
85 | ],
86 | "scale": [
87 | 0.40,
88 | 0.40,
89 | 0.40
90 | ]
91 | },
92 | "firstperson_lefthand": {
93 | "rotation": [
94 | 0,
95 | 225,
96 | 0
97 | ],
98 | "translation": [
99 | 0,
100 | 0,
101 | 0
102 | ],
103 | "scale": [
104 | 0.40,
105 | 0.40,
106 | 0.40
107 | ]
108 | }
109 | }
110 | }
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/cylinder/cylinder.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/test/resources/assets/special-model-loader-test/models/item/cylinder/cylinder.blend
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/cylinder/cylinder.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'cylinder.blend'
2 | # Material Count: 1
3 |
4 | newmtl マテリアル
5 | Ns 250.000000
6 | Ka 1.000000 1.000000 1.000000
7 | Kd 0.800000 0.800000 0.800000
8 | Ks 0.500000 0.500000 0.500000
9 | Ke 0.000000 0.000000 0.000000
10 | Ni 1.450000
11 | d 1.000000
12 | illum 2
13 | map_Kd block/ancient_debris_side
14 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/cylinder/cylinder.obj:
--------------------------------------------------------------------------------
1 | # Blender v3.2.2 OBJ File: 'cylinder.blend'
2 | # www.blender.org
3 | mtllib cylinder.mtl
4 | o 円柱
5 | v 0.000000 -1.845595 -0.365594
6 | v 0.000000 1.845595 -0.365594
7 | v 0.071324 -1.845595 -0.358569
8 | v 0.071324 1.845595 -0.358569
9 | v 0.139907 -1.845595 -0.337765
10 | v 0.139907 1.845595 -0.337765
11 | v 0.203113 -1.845595 -0.303980
12 | v 0.203113 1.845595 -0.303980
13 | v 0.258514 -1.845595 -0.258514
14 | v 0.258514 1.845595 -0.258514
15 | v 0.303980 -1.845595 -0.203113
16 | v 0.303980 1.845595 -0.203113
17 | v 0.337765 -1.845595 -0.139907
18 | v 0.337765 1.845595 -0.139907
19 | v 0.358569 -1.845595 -0.071324
20 | v 0.358569 1.845595 -0.071324
21 | v 0.365594 -1.845595 0.000000
22 | v 0.365594 1.845595 0.000000
23 | v 0.358569 -1.845595 0.071324
24 | v 0.358569 1.845595 0.071324
25 | v 0.337765 -1.845595 0.139907
26 | v 0.337765 1.845595 0.139907
27 | v 0.303980 -1.845595 0.203113
28 | v 0.303980 1.845595 0.203113
29 | v 0.258514 -1.845595 0.258514
30 | v 0.258514 1.845595 0.258514
31 | v 0.203113 -1.845595 0.303980
32 | v 0.203113 1.845595 0.303980
33 | v 0.139907 -1.845595 0.337765
34 | v 0.139907 1.845595 0.337765
35 | v 0.071324 -1.845595 0.358569
36 | v 0.071324 1.845595 0.358569
37 | v -0.000000 -1.845595 0.365594
38 | v -0.000000 1.845595 0.365594
39 | v -0.071324 -1.845595 0.358569
40 | v -0.071324 1.845595 0.358569
41 | v -0.139907 -1.845595 0.337765
42 | v -0.139907 1.845595 0.337765
43 | v -0.203113 -1.845595 0.303980
44 | v -0.203113 1.845595 0.303980
45 | v -0.258514 -1.845595 0.258514
46 | v -0.258514 1.845595 0.258514
47 | v -0.303980 -1.845595 0.203113
48 | v -0.303980 1.845595 0.203113
49 | v -0.337765 -1.845595 0.139907
50 | v -0.337765 1.845595 0.139907
51 | v -0.358569 -1.845595 0.071324
52 | v -0.358569 1.845595 0.071324
53 | v -0.365594 -1.845595 -0.000000
54 | v -0.365594 1.845595 -0.000000
55 | v -0.358569 -1.845595 -0.071324
56 | v -0.358569 1.845595 -0.071324
57 | v -0.337765 -1.845595 -0.139907
58 | v -0.337765 1.845595 -0.139907
59 | v -0.303980 -1.845595 -0.203113
60 | v -0.303980 1.845595 -0.203113
61 | v -0.258514 -1.845595 -0.258514
62 | v -0.258514 1.845595 -0.258514
63 | v -0.203113 -1.845595 -0.303980
64 | v -0.203113 1.845595 -0.303980
65 | v -0.139907 -1.845595 -0.337765
66 | v -0.139907 1.845595 -0.337765
67 | v -0.071324 -1.845595 -0.358569
68 | v -0.071324 1.845595 -0.358569
69 | vt 1.000000 0.500000
70 | vt 1.000000 1.000000
71 | vt 0.968750 1.000000
72 | vt 0.968750 0.500000
73 | vt 0.937500 1.000000
74 | vt 0.937500 0.500000
75 | vt 0.906250 1.000000
76 | vt 0.906250 0.500000
77 | vt 0.875000 1.000000
78 | vt 0.875000 0.500000
79 | vt 0.843750 1.000000
80 | vt 0.843750 0.500000
81 | vt 0.812500 1.000000
82 | vt 0.812500 0.500000
83 | vt 0.781250 1.000000
84 | vt 0.781250 0.500000
85 | vt 0.750000 1.000000
86 | vt 0.750000 0.500000
87 | vt 0.718750 1.000000
88 | vt 0.718750 0.500000
89 | vt 0.687500 1.000000
90 | vt 0.687500 0.500000
91 | vt 0.656250 1.000000
92 | vt 0.656250 0.500000
93 | vt 0.625000 1.000000
94 | vt 0.625000 0.500000
95 | vt 0.593750 1.000000
96 | vt 0.593750 0.500000
97 | vt 0.562500 1.000000
98 | vt 0.562500 0.500000
99 | vt 0.531250 1.000000
100 | vt 0.531250 0.500000
101 | vt 0.500000 1.000000
102 | vt 0.500000 0.500000
103 | vt 0.468750 1.000000
104 | vt 0.468750 0.500000
105 | vt 0.437500 1.000000
106 | vt 0.437500 0.500000
107 | vt 0.406250 1.000000
108 | vt 0.406250 0.500000
109 | vt 0.375000 1.000000
110 | vt 0.375000 0.500000
111 | vt 0.343750 1.000000
112 | vt 0.343750 0.500000
113 | vt 0.312500 1.000000
114 | vt 0.312500 0.500000
115 | vt 0.281250 1.000000
116 | vt 0.281250 0.500000
117 | vt 0.250000 1.000000
118 | vt 0.250000 0.500000
119 | vt 0.218750 1.000000
120 | vt 0.218750 0.500000
121 | vt 0.187500 1.000000
122 | vt 0.187500 0.500000
123 | vt 0.156250 1.000000
124 | vt 0.156250 0.500000
125 | vt 0.125000 1.000000
126 | vt 0.125000 0.500000
127 | vt 0.093750 1.000000
128 | vt 0.093750 0.500000
129 | vt 0.062500 1.000000
130 | vt 0.062500 0.500000
131 | vt 0.296822 0.485388
132 | vt 0.250000 0.490000
133 | vt 0.203178 0.485388
134 | vt 0.158156 0.471731
135 | vt 0.116663 0.449553
136 | vt 0.080294 0.419706
137 | vt 0.050447 0.383337
138 | vt 0.028269 0.341844
139 | vt 0.014612 0.296822
140 | vt 0.010000 0.250000
141 | vt 0.014612 0.203178
142 | vt 0.028269 0.158156
143 | vt 0.050447 0.116663
144 | vt 0.080294 0.080294
145 | vt 0.116663 0.050447
146 | vt 0.158156 0.028269
147 | vt 0.203178 0.014612
148 | vt 0.250000 0.010000
149 | vt 0.296822 0.014612
150 | vt 0.341844 0.028269
151 | vt 0.383337 0.050447
152 | vt 0.419706 0.080294
153 | vt 0.449553 0.116663
154 | vt 0.471731 0.158156
155 | vt 0.485388 0.203178
156 | vt 0.490000 0.250000
157 | vt 0.485388 0.296822
158 | vt 0.471731 0.341844
159 | vt 0.449553 0.383337
160 | vt 0.419706 0.419706
161 | vt 0.383337 0.449553
162 | vt 0.341844 0.471731
163 | vt 0.031250 1.000000
164 | vt 0.031250 0.500000
165 | vt 0.000000 1.000000
166 | vt 0.000000 0.500000
167 | vt 0.750000 0.490000
168 | vt 0.796822 0.485388
169 | vt 0.841844 0.471731
170 | vt 0.883337 0.449553
171 | vt 0.919706 0.419706
172 | vt 0.949553 0.383337
173 | vt 0.971731 0.341844
174 | vt 0.985388 0.296822
175 | vt 0.990000 0.250000
176 | vt 0.985388 0.203178
177 | vt 0.971731 0.158156
178 | vt 0.949553 0.116663
179 | vt 0.919706 0.080294
180 | vt 0.883337 0.050447
181 | vt 0.841844 0.028269
182 | vt 0.796822 0.014612
183 | vt 0.750000 0.010000
184 | vt 0.703178 0.014612
185 | vt 0.658156 0.028269
186 | vt 0.616663 0.050447
187 | vt 0.580294 0.080294
188 | vt 0.550447 0.116663
189 | vt 0.528269 0.158156
190 | vt 0.514612 0.203178
191 | vt 0.510000 0.250000
192 | vt 0.514612 0.296822
193 | vt 0.528269 0.341844
194 | vt 0.550447 0.383337
195 | vt 0.580294 0.419706
196 | vt 0.616663 0.449553
197 | vt 0.658156 0.471731
198 | vt 0.703178 0.485388
199 | vn 0.0980 0.0000 -0.9952
200 | vn 0.2903 0.0000 -0.9569
201 | vn 0.4714 0.0000 -0.8819
202 | vn 0.6344 0.0000 -0.7730
203 | vn 0.7730 0.0000 -0.6344
204 | vn 0.8819 0.0000 -0.4714
205 | vn 0.9569 0.0000 -0.2903
206 | vn 0.9952 0.0000 -0.0980
207 | vn 0.9952 0.0000 0.0980
208 | vn 0.9569 0.0000 0.2903
209 | vn 0.8819 0.0000 0.4714
210 | vn 0.7730 0.0000 0.6344
211 | vn 0.6344 0.0000 0.7730
212 | vn 0.4714 0.0000 0.8819
213 | vn 0.2903 0.0000 0.9569
214 | vn 0.0980 0.0000 0.9952
215 | vn -0.0980 0.0000 0.9952
216 | vn -0.2903 0.0000 0.9569
217 | vn -0.4714 0.0000 0.8819
218 | vn -0.6344 0.0000 0.7730
219 | vn -0.7730 0.0000 0.6344
220 | vn -0.8819 0.0000 0.4714
221 | vn -0.9569 0.0000 0.2903
222 | vn -0.9952 0.0000 0.0980
223 | vn -0.9952 0.0000 -0.0980
224 | vn -0.9569 0.0000 -0.2903
225 | vn -0.8819 0.0000 -0.4714
226 | vn -0.7730 0.0000 -0.6344
227 | vn -0.6344 0.0000 -0.7730
228 | vn -0.4714 0.0000 -0.8819
229 | vn 0.0000 1.0000 0.0000
230 | vn -0.2903 0.0000 -0.9569
231 | vn -0.0980 0.0000 -0.9952
232 | vn 0.0000 -1.0000 0.0000
233 | usemtl マテリアル
234 | s off
235 | f 1/1/1 2/2/1 4/3/1 3/4/1
236 | f 3/4/2 4/3/2 6/5/2 5/6/2
237 | f 5/6/3 6/5/3 8/7/3 7/8/3
238 | f 7/8/4 8/7/4 10/9/4 9/10/4
239 | f 9/10/5 10/9/5 12/11/5 11/12/5
240 | f 11/12/6 12/11/6 14/13/6 13/14/6
241 | f 13/14/7 14/13/7 16/15/7 15/16/7
242 | f 15/16/8 16/15/8 18/17/8 17/18/8
243 | f 17/18/9 18/17/9 20/19/9 19/20/9
244 | f 19/20/10 20/19/10 22/21/10 21/22/10
245 | f 21/22/11 22/21/11 24/23/11 23/24/11
246 | f 23/24/12 24/23/12 26/25/12 25/26/12
247 | f 25/26/13 26/25/13 28/27/13 27/28/13
248 | f 27/28/14 28/27/14 30/29/14 29/30/14
249 | f 29/30/15 30/29/15 32/31/15 31/32/15
250 | f 31/32/16 32/31/16 34/33/16 33/34/16
251 | f 33/34/17 34/33/17 36/35/17 35/36/17
252 | f 35/36/18 36/35/18 38/37/18 37/38/18
253 | f 37/38/19 38/37/19 40/39/19 39/40/19
254 | f 39/40/20 40/39/20 42/41/20 41/42/20
255 | f 41/42/21 42/41/21 44/43/21 43/44/21
256 | f 43/44/22 44/43/22 46/45/22 45/46/22
257 | f 45/46/23 46/45/23 48/47/23 47/48/23
258 | f 47/48/24 48/47/24 50/49/24 49/50/24
259 | f 49/50/25 50/49/25 52/51/25 51/52/25
260 | f 51/52/26 52/51/26 54/53/26 53/54/26
261 | f 53/54/27 54/53/27 56/55/27 55/56/27
262 | f 55/56/28 56/55/28 58/57/28 57/58/28
263 | f 57/58/29 58/57/29 60/59/29 59/60/29
264 | f 59/60/30 60/59/30 62/61/30 61/62/30
265 | f 4/63/31 2/64/31 64/65/31 62/66/31 60/67/31 58/68/31 56/69/31 54/70/31 52/71/31 50/72/31 48/73/31 46/74/31 44/75/31 42/76/31 40/77/31 38/78/31 36/79/31 34/80/31 32/81/31 30/82/31 28/83/31 26/84/31 24/85/31 22/86/31 20/87/31 18/88/31 16/89/31 14/90/31 12/91/31 10/92/31 8/93/31 6/94/31
266 | f 61/62/32 62/61/32 64/95/32 63/96/32
267 | f 63/96/33 64/95/33 2/97/33 1/98/33
268 | f 1/99/34 3/100/34 5/101/34 7/102/34 9/103/34 11/104/34 13/105/34 15/106/34 17/107/34 19/108/34 21/109/34 23/110/34 25/111/34 27/112/34 29/113/34 31/114/34 33/115/34 35/116/34 37/117/34 39/118/34 41/119/34 43/120/34 45/121/34 47/122/34 49/123/34 51/124/34 53/125/34 55/126/34 57/127/34 59/128/34 61/129/34 63/130/34
269 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/dynamic_obj_model_item.json:
--------------------------------------------------------------------------------
1 | {
2 | "gui_light": "side",
3 | "display": {
4 | "gui": {
5 | "rotation": [
6 | 30,
7 | 225,
8 | 0
9 | ],
10 | "translation": [
11 | 0,
12 | 0,
13 | 0
14 | ],
15 | "scale": [
16 | 0.625,
17 | 0.625,
18 | 0.625
19 | ]
20 | },
21 | "ground": {
22 | "rotation": [
23 | 0,
24 | 0,
25 | 0
26 | ],
27 | "translation": [
28 | 0,
29 | 3,
30 | 0
31 | ],
32 | "scale": [
33 | 0.25,
34 | 0.25,
35 | 0.25
36 | ]
37 | },
38 | "fixed": {
39 | "rotation": [
40 | 0,
41 | 0,
42 | 0
43 | ],
44 | "translation": [
45 | 0,
46 | 0,
47 | 0
48 | ],
49 | "scale": [
50 | 0.5,
51 | 0.5,
52 | 0.5
53 | ]
54 | },
55 | "thirdperson_righthand": {
56 | "rotation": [
57 | 75,
58 | 45,
59 | 0
60 | ],
61 | "translation": [
62 | 0,
63 | 2.5,
64 | 0
65 | ],
66 | "scale": [
67 | 0.375,
68 | 0.375,
69 | 0.375
70 | ]
71 | },
72 | "firstperson_righthand": {
73 | "rotation": [
74 | 0,
75 | 45,
76 | 0
77 | ],
78 | "translation": [
79 | 0,
80 | 0,
81 | 0
82 | ],
83 | "scale": [
84 | 0.40,
85 | 0.40,
86 | 0.40
87 | ]
88 | },
89 | "firstperson_lefthand": {
90 | "rotation": [
91 | 0,
92 | 225,
93 | 0
94 | ],
95 | "translation": [
96 | 0,
97 | 0,
98 | 0
99 | ],
100 | "scale": [
101 | 0.40,
102 | 0.40,
103 | 0.40
104 | ]
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/forge_obj_model_item.json:
--------------------------------------------------------------------------------
1 | {
2 | "loader": "neoforge:obj",
3 | "model": "special-model-loader-test:models/item/parabolic_antenna/parabolic_antenna.obj",
4 | "flip_v": true,
5 | "display": {
6 | "ground": {
7 | "rotation": [
8 | 0,
9 | 0,
10 | 0
11 | ],
12 | "translation": [
13 | 0.8,
14 | 7,
15 | 0.8
16 | ],
17 | "scale": [
18 | 0.1,
19 | 0.1,
20 | 0.1
21 | ]
22 | },
23 | "head": {
24 | "rotation": [
25 | 0,
26 | 180,
27 | 0
28 | ],
29 | "translation": [
30 | -0.9,
31 | 11.5,
32 | 0
33 | ],
34 | "scale": [
35 | 0.1,
36 | 0.1,
37 | 0.1
38 | ]
39 | },
40 | "thirdperson_righthand": {
41 | "rotation": [
42 | 0,
43 | 0,
44 | 0
45 | ],
46 | "translation": [
47 | 1,
48 | 5.25,
49 | 2
50 | ],
51 | "scale": [
52 | 0.1,
53 | 0.1,
54 | 0.1
55 | ]
56 | },
57 | "thirdperson_lefthand": {
58 | "rotation": [
59 | 0,
60 | 0,
61 | 0
62 | ],
63 | "translation": [
64 | -1,
65 | 5.25,
66 | 2
67 | ],
68 | "scale": [
69 | 0.1,
70 | 0.1,
71 | 0.1
72 | ]
73 | },
74 | "firstperson_righthand": {
75 | "rotation": [
76 | 0,
77 | 0,
78 | 25
79 | ],
80 | "translation": [
81 | 0,
82 | 5,
83 | 0
84 | ],
85 | "scale": [
86 | 0.1,
87 | 0.1,
88 | 0.1
89 | ]
90 | },
91 | "fixed": {
92 | "rotation": [
93 | 45,
94 | 180,
95 | 0
96 | ],
97 | "translation": [
98 | -1,
99 | 4,
100 | 0.65
101 | ],
102 | "scale": [
103 | 0.1,
104 | 0.1,
105 | 0.1
106 | ]
107 | },
108 | "gui": {
109 | "rotation": [
110 | 15,
111 | 0,
112 | 45
113 | ],
114 | "translation": [
115 | -5,
116 | 7,
117 | 0
118 | ],
119 | "scale": [
120 | 0.25,
121 | 0.25,
122 | 0.25
123 | ]
124 | }
125 | }
126 | }
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/obj2_model_item.json:
--------------------------------------------------------------------------------
1 | {
2 | "parent": "special-model-loader:builtin/obj",
3 | "model": "special-model-loader-test:models/item/cylinder/cylinder.obj",
4 | "display": {
5 | "gui": {
6 | "rotation": [
7 | 30,
8 | 225,
9 | 0
10 | ],
11 | "translation": [
12 | 0,
13 | 0,
14 | 0
15 | ],
16 | "scale": [
17 | 0.625,
18 | 0.625,
19 | 0.625
20 | ]
21 | },
22 | "ground": {
23 | "rotation": [
24 | 0,
25 | 0,
26 | 0
27 | ],
28 | "translation": [
29 | 0,
30 | 3,
31 | 0
32 | ],
33 | "scale": [
34 | 0.25,
35 | 0.25,
36 | 0.25
37 | ]
38 | },
39 | "fixed": {
40 | "rotation": [
41 | 0,
42 | 0,
43 | 0
44 | ],
45 | "translation": [
46 | 0,
47 | 0,
48 | 0
49 | ],
50 | "scale": [
51 | 0.5,
52 | 0.5,
53 | 0.5
54 | ]
55 | },
56 | "thirdperson_righthand": {
57 | "rotation": [
58 | 75,
59 | 45,
60 | 0
61 | ],
62 | "translation": [
63 | 0,
64 | 2.5,
65 | 0
66 | ],
67 | "scale": [
68 | 0.375,
69 | 0.375,
70 | 0.375
71 | ]
72 | },
73 | "firstperson_righthand": {
74 | "rotation": [
75 | 0,
76 | 45,
77 | 0
78 | ],
79 | "translation": [
80 | 0,
81 | 0,
82 | 0
83 | ],
84 | "scale": [
85 | 0.40,
86 | 0.40,
87 | 0.40
88 | ]
89 | },
90 | "firstperson_lefthand": {
91 | "rotation": [
92 | 0,
93 | 225,
94 | 0
95 | ],
96 | "translation": [
97 | 0,
98 | 0,
99 | 0
100 | ],
101 | "scale": [
102 | 0.40,
103 | 0.40,
104 | 0.40
105 | ]
106 | }
107 | }
108 | }
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/obj_model_block.json:
--------------------------------------------------------------------------------
1 | {
2 | "parent": "special-model-loader-test:block/obj_model_block"
3 | }
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/obj_model_item_dynamic.json:
--------------------------------------------------------------------------------
1 | {
2 | "parent": "special-model-loader:builtin/obj",
3 | "ambientocclusion": true,
4 | "flip_v": true,
5 | "model": "special-model-loader-test:models/item/test/test.obj"
6 | }
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/parabolic_antenna/parabolic_antenna.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'parabolic_antenna.blend'
2 | # Material Count: 1
3 |
4 | newmtl Material.001
5 | Ns 224.999983
6 | Ka 1.000000 1.000000 1.000000
7 | Kd 0.800000 0.800000 0.800000
8 | Ks 0.500000 0.500000 0.500000
9 | Ke 0.000000 0.000000 0.000000
10 | Ni 1.450000
11 | d 1.000000
12 | illum 2
13 | map_Kd special-model-loader-test:item/parabolic_antenna
14 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/parabolic_antenna/parabolic_antenna.obj:
--------------------------------------------------------------------------------
1 | # Blender v3.2.2 OBJ File: 'parabolic_antenna.blend'
2 | # www.blender.org
3 | mtllib parabolic_antenna.mtl
4 | o Cylinder.001
5 | v 0.000000 -2.492532 -1.000000
6 | v 0.500000 -2.492532 -0.866025
7 | v 0.874318 -1.959199 -1.514364
8 | v 0.000000 -1.959199 -1.748637
9 | v 0.866025 -2.492532 -0.500000
10 | v 1.514364 -1.959199 -0.874318
11 | v 1.000000 -2.492532 -0.000000
12 | v 1.748637 -1.959199 -0.000000
13 | v 0.866025 -2.492532 0.500000
14 | v 1.514364 -1.959199 0.874318
15 | v 0.500000 -2.492532 0.866025
16 | v 0.874318 -1.959199 1.514364
17 | v 0.000000 -2.492532 1.000000
18 | v 0.000000 -1.959199 1.748637
19 | v -0.500000 -2.492532 0.866026
20 | v -0.874318 -1.959199 1.514364
21 | v -0.866025 -2.492532 0.500000
22 | v -1.514364 -1.959199 0.874319
23 | v -1.000000 -2.492532 -0.000000
24 | v -1.748637 -1.959199 0.000001
25 | v -0.866026 -2.492532 -0.499999
26 | v -1.514364 -1.959199 -0.874318
27 | v -1.655755 -1.638039 -0.955949
28 | v -1.911900 -1.638039 0.000001
29 | v -0.500001 -2.492532 -0.866025
30 | v -0.874319 -1.959199 -1.514363
31 | v -1.655754 -1.638039 0.955951
32 | v -0.955950 -1.638039 1.655754
33 | v 0.000000 -1.638039 1.911900
34 | v 0.955950 -1.638039 1.655754
35 | v 1.655754 -1.638039 0.955950
36 | v 1.911900 -1.638039 -0.000000
37 | v 0.000000 -1.638039 -1.911901
38 | v -0.955951 -1.638039 -1.655754
39 | v 0.955950 -1.638039 -1.655754
40 | v 1.655754 -1.638039 -0.955950
41 | v 1.655754 -1.638039 -0.955950
42 | v 1.911900 -1.638039 -0.000000
43 | v 1.801995 -1.604232 -0.000000
44 | v 1.560573 -1.604232 -0.900997
45 | v 0.955950 -1.638039 1.655754
46 | v 0.000000 -1.638039 1.911900
47 | v 0.000000 -1.604232 1.801995
48 | v 0.900997 -1.604232 1.560573
49 | v -1.655754 -1.638039 0.955951
50 | v -1.911900 -1.638039 0.000001
51 | v -1.801995 -1.604232 0.000001
52 | v -1.560573 -1.604232 0.900998
53 | v 0.955950 -1.638039 -1.655754
54 | v 0.900997 -1.604232 -1.560573
55 | v -0.955951 -1.638039 -1.655754
56 | v 0.000000 -1.638039 -1.911901
57 | v 0.000000 -1.604232 -1.801995
58 | v -0.900998 -1.604232 -1.560573
59 | v 1.655754 -1.638039 0.955950
60 | v 1.560573 -1.604232 0.900997
61 | v -0.955950 -1.638039 1.655754
62 | v -0.900997 -1.604232 1.560573
63 | v -1.655755 -1.638039 -0.955949
64 | v -1.560574 -1.604232 -0.900997
65 | v 0.000000 -2.409605 -0.942515
66 | v 0.000000 -1.906930 -1.648116
67 | v 0.824058 -1.906930 -1.427311
68 | v 0.471257 -2.409605 -0.816242
69 | v 1.427311 -1.906930 -0.824058
70 | v 0.816242 -2.409605 -0.471257
71 | v 1.648116 -1.906930 -0.000000
72 | v 0.942515 -2.409605 -0.000000
73 | v 1.427311 -1.906930 0.824058
74 | v 0.816242 -2.409605 0.471258
75 | v 0.824058 -1.906930 1.427311
76 | v 0.471258 -2.409605 0.816242
77 | v 0.000000 -1.906930 1.648116
78 | v 0.000000 -2.409605 0.942515
79 | v -0.824058 -1.906930 1.427311
80 | v -0.471257 -2.409605 0.816242
81 | v -1.427310 -1.906930 0.824059
82 | v -0.816242 -2.409605 0.471258
83 | v -1.648116 -1.906930 0.000001
84 | v -0.942515 -2.409605 -0.000000
85 | v -1.427311 -1.906930 -0.824057
86 | v -0.816242 -2.409605 -0.471257
87 | v -0.824059 -1.906930 -1.427310
88 | v -0.471258 -2.409605 -0.816242
89 | vt 0.491267 0.294338
90 | vt 0.692385 0.148190
91 | vt 0.594496 0.317777
92 | vt 0.672272 0.389832
93 | vt 0.842011 0.291974
94 | vt 0.703053 0.491760
95 | vt 0.850665 0.692965
96 | vt 0.680616 0.595629
97 | vt 0.707299 0.843021
98 | vt 0.608906 0.673696
99 | vt 0.507918 0.705377
100 | vt 0.508074 0.901085
101 | vt 0.404586 0.681571
102 | vt 0.156762 0.707835
103 | vt 0.326429 0.609722
104 | vt 0.098834 0.508512
105 | vt 0.295292 0.508046
106 | vt 0.318129 0.404313
107 | vt 0.067867 0.265076
108 | vt 0.148170 0.306705
109 | vt 0.390305 0.326364
110 | vt 0.291684 0.156761
111 | vt 0.008466 0.512544
112 | vt 0.264926 0.931798
113 | vt 0.080525 0.756487
114 | vt 0.306652 0.851573
115 | vt 0.512120 0.991402
116 | vt 0.756036 0.919189
117 | vt 0.990102 0.487123
118 | vt 0.930982 0.734514
119 | vt 0.490963 0.098652
120 | vt 0.242982 0.080556
121 | vt 0.486923 0.008328
122 | vt 0.734129 0.068011
123 | vt 0.899795 0.491155
124 | vt 0.918220 0.243416
125 | vt 0.918220 0.243416
126 | vt 0.990102 0.487123
127 | vt 0.918220 0.243416
128 | vt 0.756036 0.919189
129 | vt 0.512120 0.991402
130 | vt 0.756036 0.919189
131 | vt 0.080525 0.756487
132 | vt 0.008466 0.512544
133 | vt 0.080525 0.756487
134 | vt 0.734129 0.068011
135 | vt 0.734129 0.068011
136 | vt 0.242982 0.080556
137 | vt 0.486923 0.008328
138 | vt 0.242982 0.080556
139 | vt 0.930982 0.734514
140 | vt 0.930982 0.734514
141 | vt 0.264926 0.931798
142 | vt 0.264926 0.931798
143 | vt 0.486923 0.008328
144 | vt 0.067867 0.265076
145 | vt 0.067867 0.265076
146 | vt 0.008466 0.512544
147 | vt 0.594496 0.317777
148 | vt 0.490963 0.098652
149 | vt 0.491267 0.294338
150 | vt 0.842011 0.291974
151 | vt 0.692385 0.148190
152 | vt 0.672272 0.389832
153 | vt 0.899795 0.491155
154 | vt 0.680616 0.595629
155 | vt 0.703053 0.491760
156 | vt 0.608906 0.673696
157 | vt 0.850665 0.692965
158 | vt 0.507918 0.705377
159 | vt 0.707299 0.843021
160 | vt 0.404586 0.681571
161 | vt 0.508074 0.901085
162 | vt 0.326429 0.609722
163 | vt 0.306652 0.851573
164 | vt 0.098834 0.508512
165 | vt 0.156762 0.707835
166 | vt 0.295292 0.508046
167 | vt 0.148170 0.306705
168 | vt 0.390305 0.326364
169 | vt 0.318129 0.404313
170 | vt 0.291684 0.156761
171 | vt 0.512120 0.991402
172 | vt 0.990102 0.487123
173 | vn 0.1536 -0.8048 -0.5733
174 | vn 0.4197 -0.8048 -0.4197
175 | vn 0.5733 -0.8048 -0.1536
176 | vn 0.5733 -0.8048 0.1536
177 | vn 0.4197 -0.8048 0.4197
178 | vn 0.1536 -0.8048 0.5733
179 | vn -0.1536 -0.8048 0.5733
180 | vn -0.4197 -0.8048 0.4197
181 | vn -0.5733 -0.8048 0.1536
182 | vn -0.5733 -0.8048 -0.1536
183 | vn -0.8670 -0.4408 -0.2323
184 | vn -0.4197 -0.8048 -0.4197
185 | vn -0.1536 -0.8048 -0.5733
186 | vn -0.0000 -1.0000 -0.0000
187 | vn -0.8670 -0.4408 0.2323
188 | vn -0.6347 -0.4408 0.6347
189 | vn -0.2323 -0.4408 0.8670
190 | vn 0.2323 -0.4408 0.8670
191 | vn 0.6347 -0.4408 0.6347
192 | vn 0.8670 -0.4408 0.2323
193 | vn -0.2323 -0.4408 -0.8670
194 | vn 0.2323 -0.4408 -0.8670
195 | vn 0.8670 -0.4408 -0.2323
196 | vn -0.6347 -0.4408 -0.6347
197 | vn 0.6347 -0.4408 -0.6347
198 | vn 0.2931 0.9529 -0.0785
199 | vn 0.0785 0.9529 0.2931
200 | vn -0.2931 0.9529 0.0785
201 | vn 0.2146 0.9529 -0.2146
202 | vn -0.0785 0.9529 -0.2931
203 | vn 0.2146 0.9529 0.2146
204 | vn -0.2146 0.9529 0.2146
205 | vn 0.0785 0.9529 -0.2931
206 | vn -0.2146 0.9529 -0.2146
207 | vn 0.2931 0.9529 0.0785
208 | vn -0.0785 0.9529 0.2931
209 | vn -0.2931 0.9529 -0.0785
210 | vn 0.0000 0.0000 1.0000
211 | vn -0.1536 0.8048 0.5733
212 | vn -0.4197 0.8048 0.4197
213 | vn -0.5733 0.8048 0.1536
214 | vn -0.5733 0.8048 -0.1536
215 | vn -0.4197 0.8048 -0.4197
216 | vn -0.1536 0.8048 -0.5733
217 | vn 0.1536 0.8048 -0.5733
218 | vn 0.4197 0.8048 -0.4197
219 | vn 0.5733 0.8048 -0.1536
220 | vn 0.5733 0.8048 0.1536
221 | vn 0.8670 0.4408 0.2323
222 | vn 0.4197 0.8048 0.4197
223 | vn 0.1536 0.8048 0.5733
224 | vn -0.0000 1.0000 0.0000
225 | vn 0.8670 0.4408 -0.2323
226 | vn 0.6347 0.4408 -0.6347
227 | vn 0.2323 0.4408 -0.8670
228 | vn -0.2323 0.4408 -0.8670
229 | vn -0.6347 0.4408 -0.6347
230 | vn -0.8670 0.4408 -0.2323
231 | vn 0.2323 0.4408 0.8670
232 | vn -0.2323 0.4408 0.8670
233 | vn -0.8670 0.4408 0.2323
234 | vn 0.6347 0.4408 0.6347
235 | vn -0.6347 0.4408 0.6347
236 | usemtl Material.001
237 | s 1
238 | f 1/1/1 3/2/1 2/3/1
239 | f 3/2/2 5/4/2 2/3/2
240 | f 6/5/3 7/6/3 5/4/3
241 | f 7/6/4 10/7/4 9/8/4
242 | f 9/8/5 12/9/5 11/10/5
243 | f 12/9/6 13/11/6 11/10/6
244 | f 14/12/7 15/13/7 13/11/7
245 | f 15/13/8 18/14/8 17/15/8
246 | f 17/15/9 20/16/9 19/17/9
247 | f 20/16/10 21/18/10 19/17/10
248 | f 20/16/11 23/19/11 22/20/11
249 | f 22/20/12 25/21/12 21/18/12
250 | f 26/22/13 1/1/13 25/21/13
251 | f 7/6/14 15/13/14 25/21/14
252 | f 18/14/15 24/23/15 20/16/15
253 | f 18/14/16 28/24/16 27/25/16
254 | f 16/26/17 29/27/17 28/24/17
255 | f 12/9/18 29/27/18 14/12/18
256 | f 10/7/19 30/28/19 12/9/19
257 | f 10/7/20 32/29/20 31/30/20
258 | f 4/31/21 34/32/21 33/33/21
259 | f 3/2/22 33/33/22 35/34/22
260 | f 6/5/23 32/29/23 8/35/23
261 | f 22/20/24 34/32/24 26/22/24
262 | f 3/2/25 36/36/25 6/5/25
263 | f 25/21/14 1/1/14 2/3/14
264 | f 2/3/14 5/4/14 7/6/14
265 | f 7/6/14 9/8/14 11/10/14
266 | f 11/10/14 13/11/14 15/13/14
267 | f 15/13/14 17/15/14 19/17/14
268 | f 19/17/14 21/18/14 25/21/14
269 | f 25/21/14 2/3/14 7/6/14
270 | f 7/6/14 11/10/14 15/13/14
271 | f 15/13/14 19/17/14 25/21/14
272 | f 40/37/26 38/38/26 37/39/26
273 | f 44/40/27 42/41/27 41/42/27
274 | f 48/43/28 46/44/28 45/45/28
275 | f 50/46/29 37/39/29 49/47/29
276 | f 54/48/30 52/49/30 51/50/30
277 | f 56/51/31 41/42/31 55/52/31
278 | f 58/53/32 45/45/32 57/54/32
279 | f 53/55/33 49/47/33 52/49/33
280 | f 60/56/34 51/50/34 59/57/34
281 | f 38/38/35 56/51/35 55/52/35
282 | f 42/41/36 58/53/36 57/54/36
283 | f 47/58/37 59/57/37 46/44/37
284 | f 36/36/38 38/38/38 32/29/38
285 | f 24/23/38 59/57/38 23/19/38
286 | f 29/27/38 57/54/38 28/24/38
287 | f 32/29/38 55/52/38 31/30/38
288 | f 23/19/38 51/50/38 34/32/38
289 | f 33/33/38 49/47/38 35/34/38
290 | f 28/24/38 45/45/38 27/25/38
291 | f 31/30/38 41/42/38 30/28/38
292 | f 34/32/38 52/49/38 33/33/38
293 | f 35/34/38 37/39/38 36/36/38
294 | f 27/25/38 46/44/38 24/23/38
295 | f 30/28/38 42/41/38 29/27/38
296 | f 64/59/39 62/60/39 61/61/39
297 | f 64/59/40 65/62/40 63/63/40
298 | f 66/64/41 67/65/41 65/62/41
299 | f 70/66/42 67/65/42 68/67/42
300 | f 72/68/43 69/69/43 70/66/43
301 | f 74/70/44 71/71/44 72/68/44
302 | f 76/72/45 73/73/45 74/70/45
303 | f 78/74/46 75/75/46 76/72/46
304 | f 78/74/47 79/76/47 77/77/47
305 | f 80/78/48 81/79/48 79/76/48
306 | f 81/79/49 47/58/49 79/76/49
307 | f 84/80/50 81/79/50 82/81/50
308 | f 84/80/51 62/60/51 83/82/51
309 | f 68/67/52 84/80/52 76/72/52
310 | f 79/76/53 48/43/53 77/77/53
311 | f 77/77/54 58/53/54 75/75/54
312 | f 58/53/55 73/73/55 75/75/55
313 | f 43/83/56 71/71/56 73/73/56
314 | f 44/40/57 69/69/57 71/71/57
315 | f 56/51/58 67/65/58 69/69/58
316 | f 62/60/59 54/48/59 83/82/59
317 | f 50/46/60 62/60/60 63/63/60
318 | f 67/65/61 40/37/61 65/62/61
319 | f 83/82/62 60/56/62 81/79/62
320 | f 40/37/63 63/63/63 65/62/63
321 | f 84/80/52 64/59/52 61/61/52
322 | f 64/59/52 68/67/52 66/64/52
323 | f 68/67/52 72/68/52 70/66/52
324 | f 72/68/52 76/72/52 74/70/52
325 | f 76/72/52 80/78/52 78/74/52
326 | f 80/78/52 84/80/52 82/81/52
327 | f 84/80/52 68/67/52 64/59/52
328 | f 68/67/52 76/72/52 72/68/52
329 | f 76/72/52 84/80/52 80/78/52
330 | f 1/1/1 4/31/1 3/2/1
331 | f 3/2/2 6/5/2 5/4/2
332 | f 6/5/3 8/35/3 7/6/3
333 | f 7/6/4 8/35/4 10/7/4
334 | f 9/8/5 10/7/5 12/9/5
335 | f 12/9/6 14/12/6 13/11/6
336 | f 14/12/7 16/26/7 15/13/7
337 | f 15/13/8 16/26/8 18/14/8
338 | f 17/15/9 18/14/9 20/16/9
339 | f 20/16/10 22/20/10 21/18/10
340 | f 20/16/11 24/23/11 23/19/11
341 | f 22/20/12 26/22/12 25/21/12
342 | f 26/22/13 4/31/13 1/1/13
343 | f 18/14/15 27/25/15 24/23/15
344 | f 18/14/16 16/26/16 28/24/16
345 | f 16/26/17 14/12/17 29/27/17
346 | f 12/9/18 30/28/18 29/27/18
347 | f 10/7/19 31/30/19 30/28/19
348 | f 10/7/20 8/35/20 32/29/20
349 | f 4/31/21 26/22/21 34/32/21
350 | f 3/2/22 4/31/22 33/33/22
351 | f 6/5/23 36/36/23 32/29/23
352 | f 22/20/24 23/19/24 34/32/24
353 | f 3/2/25 35/34/25 36/36/25
354 | f 40/37/26 39/84/26 38/38/26
355 | f 44/40/27 43/83/27 42/41/27
356 | f 48/43/28 47/58/28 46/44/28
357 | f 50/46/29 40/37/29 37/39/29
358 | f 54/48/30 53/55/30 52/49/30
359 | f 56/51/31 44/40/31 41/42/31
360 | f 58/53/32 48/43/32 45/45/32
361 | f 53/55/33 50/46/33 49/47/33
362 | f 60/56/34 54/48/34 51/50/34
363 | f 38/38/35 39/84/35 56/51/35
364 | f 42/41/36 43/83/36 58/53/36
365 | f 47/58/37 60/56/37 59/57/37
366 | f 36/36/38 37/39/38 38/38/38
367 | f 24/23/38 46/44/38 59/57/38
368 | f 29/27/38 42/41/38 57/54/38
369 | f 32/29/38 38/38/38 55/52/38
370 | f 23/19/38 59/57/38 51/50/38
371 | f 33/33/38 52/49/38 49/47/38
372 | f 28/24/38 57/54/38 45/45/38
373 | f 31/30/38 55/52/38 41/42/38
374 | f 34/32/38 51/50/38 52/49/38
375 | f 35/34/38 49/47/38 37/39/38
376 | f 27/25/38 45/45/38 46/44/38
377 | f 30/28/38 41/42/38 42/41/38
378 | f 64/59/39 63/63/39 62/60/39
379 | f 64/59/40 66/64/40 65/62/40
380 | f 66/64/41 68/67/41 67/65/41
381 | f 70/66/42 69/69/42 67/65/42
382 | f 72/68/43 71/71/43 69/69/43
383 | f 74/70/44 73/73/44 71/71/44
384 | f 76/72/45 75/75/45 73/73/45
385 | f 78/74/46 77/77/46 75/75/46
386 | f 78/74/47 80/78/47 79/76/47
387 | f 80/78/48 82/81/48 81/79/48
388 | f 81/79/49 60/56/49 47/58/49
389 | f 84/80/50 83/82/50 81/79/50
390 | f 84/80/51 61/61/51 62/60/51
391 | f 79/76/53 47/58/53 48/43/53
392 | f 77/77/54 48/43/54 58/53/54
393 | f 58/53/55 43/83/55 73/73/55
394 | f 43/83/56 44/40/56 71/71/56
395 | f 44/40/57 56/51/57 69/69/57
396 | f 56/51/58 39/84/58 67/65/58
397 | f 62/60/59 53/55/59 54/48/59
398 | f 50/46/60 53/55/60 62/60/60
399 | f 67/65/61 39/84/61 40/37/61
400 | f 83/82/62 54/48/62 60/56/62
401 | f 40/37/63 50/46/63 63/63/63
402 | o Cylinder.004
403 | v -1.757394 -1.895375 -0.060000
404 | v -0.007336 -0.229707 -0.060000
405 | v 0.034029 -0.273169 -0.000000
406 | v -1.716029 -1.938837 -0.000000
407 | v -0.007336 -0.229707 0.060000
408 | v -1.757394 -1.895375 0.060000
409 | v -0.048702 -0.186246 -0.000000
410 | v -1.798760 -1.851914 -0.000000
411 | vt 0.171147 0.001058
412 | vt 0.150027 0.998942
413 | vt 0.150027 0.001058
414 | vt 0.128906 0.001058
415 | vt 0.751953 0.980234
416 | vt 0.751953 0.500234
417 | vt 0.991953 0.740234
418 | vt 0.107786 0.998942
419 | vt 0.107786 0.001058
420 | vt 0.086665 0.001058
421 | vt 0.750000 0.490000
422 | vt 0.750000 0.010000
423 | vt 0.510000 0.250000
424 | vt 0.171147 0.998942
425 | vt 0.128906 0.998942
426 | vt 0.511953 0.740234
427 | vt 0.086665 0.998942
428 | vt 0.990000 0.250000
429 | vn 0.4875 -0.5122 -0.7071
430 | vn 0.4875 -0.5122 0.7071
431 | vn 0.7244 0.6894 0.0000
432 | vn -0.4875 0.5122 0.7071
433 | vn -0.4875 0.5122 -0.7071
434 | vn -0.7244 -0.6894 0.0000
435 | vn -0.7243 -0.6894 0.0000
436 | vn 0.7243 0.6894 0.0000
437 | usemtl Material.001
438 | s 1
439 | f 85/85/64 87/86/64 88/87/64
440 | f 87/86/65 90/88/65 88/87/65
441 | f 86/89/66 89/90/66 87/91/66
442 | f 90/88/67 91/92/67 92/93/67
443 | f 91/92/68 85/94/68 92/93/68
444 | f 85/95/69 90/96/69 92/97/70
445 | f 85/85/64 86/98/64 87/86/64
446 | f 87/86/65 89/99/65 90/88/65
447 | f 86/89/66 91/100/71 89/90/66
448 | f 90/88/67 89/99/67 91/92/67
449 | f 91/92/68 86/101/68 85/94/68
450 | f 85/95/69 88/102/69 90/96/69
451 | o Cylinder.003
452 | v 0.000000 -2.811414 -0.130000
453 | v 0.000000 -1.788067 -0.130000
454 | v 0.130000 -1.788067 -0.000000
455 | v 0.130000 -2.811414 -0.000000
456 | v 0.000000 -1.788067 0.130000
457 | v 0.000000 -2.811414 0.130000
458 | v 0.000000 -1.415264 -0.000000
459 | v -0.130000 -1.788067 -0.000000
460 | v -0.130000 -2.811414 -0.000000
461 | vt 0.210623 0.829295
462 | vt 0.169652 0.563570
463 | vt 0.210623 0.563570
464 | vt 0.169652 0.829295
465 | vt 0.128682 0.563570
466 | vt 0.178994 0.018632
467 | vt 0.241359 0.018450
468 | vt 0.210557 0.148792
469 | vt 0.128682 0.829295
470 | vt 0.087711 0.563570
471 | vt 0.087711 0.829295
472 | vt 0.046740 0.563570
473 | vt 0.851829 0.092661
474 | vt 0.972761 0.092661
475 | vt 0.912295 0.032195
476 | vt 0.033710 0.022537
477 | vt 0.096075 0.022355
478 | vt 0.065273 0.152697
479 | vt 0.109356 0.022918
480 | vt 0.171722 0.022736
481 | vt 0.140919 0.153078
482 | vt 0.250584 0.019448
483 | vt 0.312950 0.019266
484 | vt 0.282147 0.149608
485 | vt 0.046740 0.829295
486 | vt 0.912295 0.153128
487 | vn 0.7071 0.0000 -0.7071
488 | vn 0.7071 -0.0000 0.7071
489 | vn 0.6865 0.2394 -0.6865
490 | vn -0.7071 -0.0000 0.7071
491 | vn -0.7071 0.0000 -0.7071
492 | vn 0.0000 -1.0000 0.0000
493 | vn -0.6865 0.2394 0.6865
494 | vn -0.6865 0.2394 -0.6865
495 | vn 0.6865 0.2394 0.6865
496 | usemtl Material.001
497 | s 1
498 | f 94/103/72 96/104/72 93/105/72
499 | f 95/106/73 98/107/73 96/104/73
500 | f 95/108/74 94/109/74 99/110/74
501 | f 97/111/75 101/112/75 98/107/75
502 | f 100/113/76 93/114/76 101/112/76
503 | f 96/115/77 101/116/77 93/117/77
504 | f 100/118/78 97/119/78 99/120/78
505 | f 94/121/79 100/122/79 99/123/79
506 | f 97/124/80 95/125/80 99/126/80
507 | f 94/103/72 95/106/72 96/104/72
508 | f 95/106/73 97/111/73 98/107/73
509 | f 97/111/75 100/113/75 101/112/75
510 | f 100/113/76 94/127/76 93/114/76
511 | f 96/115/77 98/128/77 101/116/77
512 | o Cylinder.005_Cylinder.004
513 | v -0.060000 -1.895375 1.757394
514 | v -0.060000 -0.229707 0.007336
515 | v 0.000000 -0.273169 -0.034029
516 | v 0.000000 -1.938837 1.716029
517 | v 0.060000 -0.229707 0.007336
518 | v 0.060000 -1.895375 1.757394
519 | v 0.000000 -0.186246 0.048702
520 | v 0.000000 -1.851914 1.798760
521 | vt 0.171147 0.998942
522 | vt 0.150027 0.001058
523 | vt 0.171147 0.001058
524 | vt 0.150027 0.998942
525 | vt 0.128906 0.001058
526 | vt 0.751953 0.980234
527 | vt 0.751953 0.500234
528 | vt 0.991953 0.740234
529 | vt 0.107786 0.998942
530 | vt 0.107786 0.001058
531 | vt 0.086665 0.998942
532 | vt 0.086665 0.001058
533 | vt 0.990000 0.250000
534 | vt 0.510000 0.250000
535 | vt 0.750000 0.490000
536 | vt 0.128906 0.998942
537 | vt 0.511953 0.740234
538 | vt 0.750000 0.010000
539 | vn -0.7071 -0.5122 -0.4875
540 | vn 0.7071 -0.5122 -0.4875
541 | vn 0.0000 0.6894 -0.7244
542 | vn 0.7071 0.5122 0.4875
543 | vn -0.7071 0.5122 0.4875
544 | vn 0.0000 -0.6894 0.7244
545 | vn 0.0000 0.6894 -0.7243
546 | usemtl Material.001
547 | s 1
548 | f 103/129/81 105/130/81 102/131/81
549 | f 104/132/82 107/133/82 105/130/82
550 | f 103/134/83 106/135/83 104/136/83
551 | f 107/133/84 108/137/84 109/138/84
552 | f 109/138/85 103/139/85 102/140/85
553 | f 105/141/86 109/142/86 102/143/86
554 | f 103/129/81 104/132/81 105/130/81
555 | f 104/132/82 106/144/82 107/133/82
556 | f 103/134/83 108/145/87 106/135/83
557 | f 107/133/84 106/144/84 108/137/84
558 | f 109/138/85 108/137/85 103/139/85
559 | f 105/141/86 107/146/86 109/142/86
560 | o Cylinder.006_Cylinder.004
561 | v 1.757394 -1.895375 0.060000
562 | v 0.007336 -0.229707 0.060000
563 | v -0.034029 -0.273169 -0.000000
564 | v 1.716029 -1.938837 -0.000000
565 | v 0.007336 -0.229707 -0.060000
566 | v 1.757394 -1.895375 -0.060000
567 | v 0.048702 -0.186246 -0.000000
568 | v 1.798760 -1.851914 -0.000000
569 | vt 0.171147 0.001058
570 | vt 0.150027 0.998942
571 | vt 0.150027 0.001058
572 | vt 0.128906 0.001058
573 | vt 0.751953 0.980234
574 | vt 0.751953 0.500234
575 | vt 0.991953 0.740234
576 | vt 0.107786 0.998942
577 | vt 0.107786 0.001058
578 | vt 0.086665 0.001058
579 | vt 0.750000 0.490000
580 | vt 0.750000 0.010000
581 | vt 0.510000 0.250000
582 | vt 0.171147 0.998942
583 | vt 0.128906 0.998942
584 | vt 0.511953 0.740234
585 | vt 0.086665 0.998942
586 | vt 0.990000 0.250000
587 | vn -0.4875 -0.5122 0.7071
588 | vn -0.4875 -0.5122 -0.7071
589 | vn -0.7244 0.6894 0.0000
590 | vn 0.4875 0.5122 -0.7071
591 | vn 0.4875 0.5122 0.7071
592 | vn 0.7244 -0.6894 0.0000
593 | vn 0.7243 -0.6894 0.0000
594 | vn -0.7243 0.6894 0.0000
595 | usemtl Material.001
596 | s 1
597 | f 110/147/88 112/148/88 113/149/88
598 | f 112/148/89 115/150/89 113/149/89
599 | f 111/151/90 114/152/90 112/153/90
600 | f 115/150/91 116/154/91 117/155/91
601 | f 116/154/92 110/156/92 117/155/92
602 | f 110/157/93 115/158/93 117/159/94
603 | f 110/147/88 111/160/88 112/148/88
604 | f 112/148/89 114/161/89 115/150/89
605 | f 111/151/90 116/162/95 114/152/90
606 | f 115/150/91 114/161/91 116/154/91
607 | f 116/154/92 111/163/92 110/156/92
608 | f 110/157/93 113/164/93 115/158/93
609 | o Cylinder.007_Cylinder.004
610 | v 0.060000 -1.895375 -1.757394
611 | v 0.060000 -0.229707 -0.007336
612 | v 0.000000 -0.273169 0.034029
613 | v 0.000000 -1.938837 -1.716029
614 | v -0.060000 -0.229707 -0.007336
615 | v -0.060000 -1.895375 -1.757394
616 | v 0.000000 -0.186246 -0.048702
617 | v 0.000000 -1.851914 -1.798760
618 | vt 0.171147 0.998942
619 | vt 0.150027 0.001058
620 | vt 0.171147 0.001058
621 | vt 0.150027 0.998942
622 | vt 0.128906 0.001058
623 | vt 0.751953 0.980234
624 | vt 0.751953 0.500234
625 | vt 0.991953 0.740234
626 | vt 0.107786 0.998942
627 | vt 0.107786 0.001058
628 | vt 0.086665 0.998942
629 | vt 0.086665 0.001058
630 | vt 0.990000 0.250000
631 | vt 0.510000 0.250000
632 | vt 0.750000 0.490000
633 | vt 0.128906 0.998942
634 | vt 0.511953 0.740234
635 | vt 0.750000 0.010000
636 | vn 0.7071 -0.5122 0.4875
637 | vn -0.7071 -0.5122 0.4875
638 | vn 0.0000 0.6894 0.7244
639 | vn -0.7071 0.5122 -0.4875
640 | vn 0.7071 0.5122 -0.4875
641 | vn 0.0000 -0.6894 -0.7244
642 | vn 0.0000 0.6894 0.7243
643 | usemtl Material.001
644 | s 1
645 | f 119/165/96 121/166/96 118/167/96
646 | f 120/168/97 123/169/97 121/166/97
647 | f 119/170/98 122/171/98 120/172/98
648 | f 123/169/99 124/173/99 125/174/99
649 | f 125/174/100 119/175/100 118/176/100
650 | f 121/177/101 125/178/101 118/179/101
651 | f 119/165/96 120/168/96 121/166/96
652 | f 120/168/97 122/180/97 123/169/97
653 | f 119/170/98 124/181/102 122/171/98
654 | f 123/169/99 122/180/99 124/173/99
655 | f 125/174/100 124/173/100 119/175/100
656 | f 121/177/101 123/182/101 125/178/101
657 | o Cylinder.008_Cylinder.005
658 | v 0.000000 -0.360062 -0.190000
659 | v 0.000000 0.069938 -0.190000
660 | v 0.134350 0.069938 -0.134350
661 | v 0.134350 -0.360062 -0.134350
662 | v 0.190000 0.069938 0.000000
663 | v 0.190000 -0.360062 -0.000000
664 | v 0.134350 0.069938 0.134350
665 | v 0.134350 -0.360062 0.134350
666 | v 0.000000 0.069938 0.190000
667 | v 0.000000 -0.360062 0.190000
668 | v -0.134350 0.069938 0.134350
669 | v -0.134350 -0.360062 0.134350
670 | v -0.190000 0.069938 0.000000
671 | v -0.190000 -0.360062 -0.000000
672 | v -0.134350 0.069938 -0.134350
673 | v -0.134350 -0.360062 -0.134350
674 | vt 0.749675 0.874838
675 | vt 0.687257 0.625162
676 | vt 0.749675 0.625162
677 | vt 0.687257 0.874838
678 | vt 0.624838 0.625162
679 | vt 0.624838 0.874838
680 | vt 0.562419 0.625162
681 | vt 0.562419 0.874838
682 | vt 0.500000 0.625162
683 | vt 0.500000 0.874838
684 | vt 0.437581 0.625162
685 | vt 0.437581 0.874838
686 | vt 0.375162 0.625162
687 | vt 0.721096 0.250000
688 | vt 0.612804 0.358292
689 | vt 0.504512 0.250000
690 | vt 0.375162 0.874838
691 | vt 0.312743 0.625162
692 | vt 0.312743 0.874838
693 | vt 0.250325 0.625162
694 | vt 0.310622 0.326574
695 | vt 0.463770 0.326574
696 | vt 0.463770 0.173426
697 | vt 0.536230 0.173426
698 | vt 0.612804 0.141708
699 | vt 0.689378 0.173426
700 | vt 0.689378 0.326574
701 | vt 0.536230 0.326574
702 | vt 0.387196 0.141708
703 | vt 0.310622 0.173426
704 | vt 0.278904 0.250000
705 | vt 0.387196 0.358292
706 | vt 0.495488 0.250000
707 | vt 0.250325 0.874838
708 | vn 0.3827 0.0000 -0.9239
709 | vn 0.9239 0.0000 -0.3827
710 | vn 0.9239 -0.0000 0.3827
711 | vn 0.3827 -0.0000 0.9239
712 | vn -0.3827 -0.0000 0.9239
713 | vn -0.9239 -0.0000 0.3827
714 | vn 0.0000 1.0000 0.0000
715 | vn -0.9239 0.0000 -0.3827
716 | vn -0.3827 0.0000 -0.9239
717 | vn 0.0000 -1.0000 -0.0000
718 | usemtl Material.001
719 | s 1
720 | f 127/183/103 129/184/103 126/185/103
721 | f 128/186/104 131/187/104 129/184/104
722 | f 130/188/105 133/189/105 131/187/105
723 | f 132/190/106 135/191/106 133/189/106
724 | f 134/192/107 137/193/107 135/191/107
725 | f 136/194/108 139/195/108 137/193/108
726 | f 138/196/109 134/197/109 130/198/109
727 | f 138/199/110 141/200/110 139/195/110
728 | f 140/201/111 126/202/111 141/200/111
729 | f 133/203/112 137/204/112 141/205/112
730 | f 130/198/109 128/206/109 127/207/109
731 | f 127/207/109 140/208/109 138/196/109
732 | f 138/196/109 136/209/109 134/197/109
733 | f 134/197/109 132/210/109 130/198/109
734 | f 130/198/109 127/207/109 138/196/109
735 | f 141/205/112 126/211/112 129/212/112
736 | f 129/212/112 131/213/112 133/203/112
737 | f 133/203/112 135/214/112 137/204/112
738 | f 137/204/112 139/215/112 141/205/112
739 | f 141/205/112 129/212/112 133/203/112
740 | f 127/183/103 128/186/103 129/184/103
741 | f 128/186/104 130/188/104 131/187/104
742 | f 130/188/105 132/190/105 133/189/105
743 | f 132/190/106 134/192/106 135/191/106
744 | f 134/192/107 136/194/107 137/193/107
745 | f 136/194/108 138/199/108 139/195/108
746 | f 138/199/110 140/201/110 141/200/110
747 | f 140/201/111 127/216/111 126/202/111
748 | o Cylinder.009_Cylinder.006
749 | v 0.000000 0.063290 -0.011143
750 | v 0.000000 0.288781 -0.011143
751 | v 0.011143 0.288781 0.000000
752 | v 0.011143 0.063290 0.000000
753 | v 0.000000 0.288781 0.011143
754 | v 0.000000 0.063290 0.011143
755 | v -0.011143 0.288781 0.000000
756 | v -0.011143 0.063290 0.000000
757 | vt 0.530396 0.854540
758 | vt 0.515198 0.645460
759 | vt 0.530396 0.645460
760 | vt 0.515198 0.854540
761 | vt 0.500000 0.645460
762 | vt 0.538416 0.213121
763 | vt 0.538416 0.286879
764 | vt 0.501537 0.250000
765 | vt 0.500000 0.854540
766 | vt 0.484802 0.645460
767 | vt 0.484802 0.854540
768 | vt 0.469604 0.645460
769 | vt 0.424705 0.250000
770 | vt 0.498463 0.250000
771 | vt 0.461584 0.213121
772 | vt 0.575295 0.250000
773 | vt 0.469604 0.854540
774 | vt 0.461584 0.286879
775 | vn 0.7071 0.0000 -0.7071
776 | vn 0.7071 -0.0000 0.7071
777 | vn 0.0000 1.0000 0.0000
778 | vn -0.7071 -0.0000 0.7071
779 | vn -0.7071 0.0000 -0.7071
780 | vn 0.0000 -1.0000 0.0000
781 | usemtl Material.001
782 | s 1
783 | f 143/217/113 145/218/113 142/219/113
784 | f 144/220/114 147/221/114 145/218/114
785 | f 143/222/115 146/223/115 144/224/115
786 | f 146/225/116 149/226/116 147/221/116
787 | f 148/227/117 142/228/117 149/226/117
788 | f 145/229/118 149/230/118 142/231/118
789 | f 143/217/113 144/220/113 145/218/113
790 | f 144/220/114 146/225/114 147/221/114
791 | f 143/222/115 148/232/115 146/223/115
792 | f 146/225/116 148/227/116 149/226/116
793 | f 148/227/117 143/233/117 142/228/117
794 | f 145/229/118 147/234/118 149/230/118
795 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/parabolic_antenna/parabolic_antenna_2.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'parabolic_antenna.blend'
2 | # Material Count: 1
3 |
4 | newmtl Material.001
5 | Ns 224.999983
6 | Ka 1.000000 1.000000 1.000000
7 | Kd 0.800000 0.800000 0.800000
8 | Ks 0.500000 0.500000 0.500000
9 | Ke 0.000000 0.000000 0.000000
10 | Ni 1.450000
11 | d 1.000000
12 | illum 2
13 | map_Kd item/apple
14 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/ring/ring.mtl:
--------------------------------------------------------------------------------
1 | # Blender 4.2.1 LTS MTL File: 'None'
2 | # www.blender.org
3 |
4 | newmtl test_material
5 | Ns 250.000000
6 | Ka 1.000000 1.000000 1.000000
7 | Ks 0.500000 0.500000 0.500000
8 | Ke 0.000000 0.000000 0.000000
9 | Ni 1.500000
10 | d 1.000000
11 | illum 2
12 | map_Kd #texture0
13 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/ring/ring.obj:
--------------------------------------------------------------------------------
1 | # Blender 4.2.1 LTS
2 | # www.blender.org
3 | mtllib ring.mtl
4 | o トーラス
5 | v 1.250000 0.000000 0.000000
6 | v 1.000000 0.250000 0.000000
7 | v 0.750000 0.000000 0.000000
8 | v 1.000000 -0.250000 0.000000
9 | v 0.957555 0.000000 -0.803485
10 | v 0.766044 0.250000 -0.642788
11 | v 0.574533 0.000000 -0.482091
12 | v 0.766044 -0.250000 -0.642788
13 | v 0.217060 0.000000 -1.231010
14 | v 0.173648 0.250000 -0.984808
15 | v 0.130236 0.000000 -0.738606
16 | v 0.173648 -0.250000 -0.984808
17 | v -0.625000 0.000000 -1.082532
18 | v -0.500000 0.250000 -0.866026
19 | v -0.375000 0.000000 -0.649519
20 | v -0.500000 -0.250000 -0.866026
21 | v -1.174616 0.000000 -0.427526
22 | v -0.939692 0.250000 -0.342020
23 | v -0.704769 0.000000 -0.256515
24 | v -0.939692 -0.250000 -0.342020
25 | v -1.174616 0.000000 0.427525
26 | v -0.939693 0.250000 0.342020
27 | v -0.704769 0.000000 0.256515
28 | v -0.939693 -0.250000 0.342020
29 | v -0.625000 0.000000 1.082532
30 | v -0.500000 0.250000 0.866026
31 | v -0.375000 0.000000 0.649519
32 | v -0.500000 -0.250000 0.866026
33 | v 0.217060 0.000000 1.231010
34 | v 0.173648 0.250000 0.984808
35 | v 0.130236 0.000000 0.738606
36 | v 0.173648 -0.250000 0.984808
37 | v 0.957555 0.000000 0.803485
38 | v 0.766044 0.250000 0.642788
39 | v 0.574533 0.000000 0.482091
40 | v 0.766044 -0.250000 0.642788
41 | vn 0.6848 0.6848 -0.2492
42 | vn -0.6848 0.6848 0.2492
43 | vn -0.6848 -0.6848 0.2492
44 | vn 0.6848 -0.6848 -0.2492
45 | vn 0.3644 0.6848 -0.6311
46 | vn -0.3644 0.6848 0.6311
47 | vn -0.3644 -0.6848 0.6311
48 | vn 0.3644 -0.6848 -0.6311
49 | vn -0.1265 0.6848 -0.7177
50 | vn 0.1265 0.6848 0.7177
51 | vn 0.1265 -0.6848 0.7177
52 | vn -0.1265 -0.6848 -0.7177
53 | vn -0.5582 0.6848 -0.4684
54 | vn 0.5582 0.6848 0.4684
55 | vn 0.5582 -0.6848 0.4684
56 | vn -0.5582 -0.6848 -0.4684
57 | vn -0.7287 0.6848 -0.0000
58 | vn 0.7287 0.6848 -0.0000
59 | vn 0.7287 -0.6848 -0.0000
60 | vn -0.7287 -0.6848 -0.0000
61 | vn -0.5582 0.6848 0.4684
62 | vn 0.5582 0.6848 -0.4684
63 | vn 0.5582 -0.6848 -0.4684
64 | vn -0.5582 -0.6848 0.4684
65 | vn -0.1265 0.6848 0.7177
66 | vn 0.1265 0.6848 -0.7177
67 | vn 0.1265 -0.6848 -0.7177
68 | vn -0.1265 -0.6848 0.7177
69 | vn 0.3644 0.6848 0.6311
70 | vn -0.3644 0.6848 -0.6311
71 | vn -0.3644 -0.6848 -0.6311
72 | vn 0.3644 -0.6848 0.6311
73 | vn 0.6848 0.6848 0.2492
74 | vn -0.6848 0.6848 -0.2492
75 | vn -0.6848 -0.6848 -0.2492
76 | vn 0.6848 -0.6848 0.2492
77 | vt 0.555556 0.500000
78 | vt 0.666667 0.500000
79 | vt 0.666667 0.750000
80 | vt 0.555556 0.750000
81 | vt 0.666667 1.000000
82 | vt 0.555556 1.000000
83 | vt 0.555556 0.000000
84 | vt 0.666667 0.000000
85 | vt 0.666667 0.250000
86 | vt 0.555556 0.250000
87 | vt 0.777778 0.500000
88 | vt 0.777778 0.750000
89 | vt 0.777778 1.000000
90 | vt 0.777778 0.000000
91 | vt 0.777778 0.250000
92 | vt 0.888889 0.500000
93 | vt 0.888889 0.750000
94 | vt 0.888889 1.000000
95 | vt 0.888889 0.000000
96 | vt 0.888889 0.250000
97 | vt 1.000000 0.500000
98 | vt 1.000000 0.750000
99 | vt 1.000000 1.000000
100 | vt 1.000000 0.000000
101 | vt 1.000000 0.250000
102 | vt 0.000000 0.500000
103 | vt 0.111111 0.500000
104 | vt 0.111111 0.750000
105 | vt 0.000000 0.750000
106 | vt 0.111111 1.000000
107 | vt 0.000000 1.000000
108 | vt 0.000000 0.000000
109 | vt 0.111111 0.000000
110 | vt 0.111111 0.250000
111 | vt 0.000000 0.250000
112 | vt 0.222222 0.500000
113 | vt 0.222222 0.750000
114 | vt 0.222222 1.000000
115 | vt 0.222222 0.000000
116 | vt 0.222222 0.250000
117 | vt 0.333333 0.500000
118 | vt 0.333333 0.750000
119 | vt 0.333333 1.000000
120 | vt 0.333333 0.000000
121 | vt 0.333333 0.250000
122 | vt 0.444444 0.500000
123 | vt 0.444444 0.750000
124 | vt 0.444444 1.000000
125 | vt 0.444444 0.000000
126 | vt 0.444444 0.250000
127 | s 0
128 | usemtl test_material
129 | f 1/1/1 5/2/1 6/3/1 2/4/1
130 | f 2/4/2 6/3/2 7/5/2 3/6/2
131 | f 3/7/3 7/8/3 8/9/3 4/10/3
132 | f 4/10/4 8/9/4 5/2/4 1/1/4
133 | f 5/2/5 9/11/5 10/12/5 6/3/5
134 | f 6/3/6 10/12/6 11/13/6 7/5/6
135 | f 7/8/7 11/14/7 12/15/7 8/9/7
136 | f 8/9/8 12/15/8 9/11/8 5/2/8
137 | f 9/11/9 13/16/9 14/17/9 10/12/9
138 | f 10/12/10 14/17/10 15/18/10 11/13/10
139 | f 11/14/11 15/19/11 16/20/11 12/15/11
140 | f 12/15/12 16/20/12 13/16/12 9/11/12
141 | f 13/16/13 17/21/13 18/22/13 14/17/13
142 | f 14/17/14 18/22/14 19/23/14 15/18/14
143 | f 15/19/15 19/24/15 20/25/15 16/20/15
144 | f 16/20/16 20/25/16 17/21/16 13/16/16
145 | f 17/26/17 21/27/17 22/28/17 18/29/17
146 | f 18/29/18 22/28/18 23/30/18 19/31/18
147 | f 19/32/19 23/33/19 24/34/19 20/35/19
148 | f 20/35/20 24/34/20 21/27/20 17/26/20
149 | f 21/27/21 25/36/21 26/37/21 22/28/21
150 | f 22/28/22 26/37/22 27/38/22 23/30/22
151 | f 23/33/23 27/39/23 28/40/23 24/34/23
152 | f 24/34/24 28/40/24 25/36/24 21/27/24
153 | f 25/36/25 29/41/25 30/42/25 26/37/25
154 | f 26/37/26 30/42/26 31/43/26 27/38/26
155 | f 27/39/27 31/44/27 32/45/27 28/40/27
156 | f 28/40/28 32/45/28 29/41/28 25/36/28
157 | f 29/41/29 33/46/29 34/47/29 30/42/29
158 | f 30/42/30 34/47/30 35/48/30 31/43/30
159 | f 31/44/31 35/49/31 36/50/31 32/45/31
160 | f 32/45/32 36/50/32 33/46/32 29/41/32
161 | f 33/46/33 1/1/33 2/4/33 34/47/33
162 | f 34/47/34 2/4/34 3/6/34 35/48/34
163 | f 35/49/35 3/7/35 4/10/35 36/50/35
164 | f 36/50/36 4/10/36 1/1/36 33/46/36
165 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/ring/ring_2.mtl:
--------------------------------------------------------------------------------
1 | # Blender 4.2.1 LTS MTL File: 'None'
2 | # www.blender.org
3 |
4 | newmtl test_material
5 | Ns 250.000000
6 | Ka 1.000000 1.000000 1.000000
7 | Ks 0.500000 0.500000 0.500000
8 | Ke 0.000000 0.000000 0.000000
9 | Ni 1.500000
10 | d 1.000000
11 | illum 2
12 | map_Kd item/apple
13 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/sea_cheken_pack/sea_chicken.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/test/resources/assets/special-model-loader-test/models/item/sea_cheken_pack/sea_chicken.blend
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/sea_cheken_pack/sea_chicken.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'sea_chicken.blend'
2 | # Material Count: 2
3 |
4 | newmtl chken
5 | Ns 225.000000
6 | Ka 1.000000 1.000000 1.000000
7 | Kd 0.800000 0.800000 0.800000
8 | Ks 0.500000 0.500000 0.500000
9 | Ke 0.000000 0.000000 0.000000
10 | Ni 1.450000
11 | d 1.000000
12 | illum 2
13 | map_Kd special-model-loader-test:item/cheken
14 |
15 | newmtl pack
16 | Ns 225.000000
17 | Ka 1.000000 1.000000 1.000000
18 | Kd 0.800000 0.800000 0.800000
19 | Ks 0.500000 0.500000 0.500000
20 | Ke 0.000000 0.000000 0.000000
21 | Ni 1.450000
22 | d 1.000000
23 | illum 2
24 | map_Kd special-model-loader-test:item/cheken_pack
25 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/sea_cheken_pack/sea_chicken.obj:
--------------------------------------------------------------------------------
1 | # Blender v3.0.0 OBJ File: 'sea_chicken.blend'
2 | # www.blender.org
3 | mtllib sea_chicken.mtl
4 | o pack_立方体
5 | v -0.985420 -1.167350 0.005905
6 | v -0.985420 1.167350 0.005905
7 | v -0.985420 -1.167350 -0.005905
8 | v -0.985420 1.167350 -0.005905
9 | v 0.985420 -1.167350 0.005905
10 | v 0.985420 1.167350 0.005905
11 | v 0.985420 -1.167350 -0.005905
12 | v 0.985420 1.167350 -0.005905
13 | vt 0.375000 0.000000
14 | vt 0.625000 0.000000
15 | vt 0.625000 0.250000
16 | vt 0.375000 0.250000
17 | vt 0.625000 0.500000
18 | vt 0.375000 0.500000
19 | vt 0.625000 0.750000
20 | vt 0.375000 0.750000
21 | vt 0.625000 1.000000
22 | vt 0.375000 1.000000
23 | vt 0.125000 0.500000
24 | vt 0.125000 0.750000
25 | vt 0.875000 0.500000
26 | vt 0.875000 0.750000
27 | vn -1.0000 0.0000 0.0000
28 | vn 0.0000 0.0000 -1.0000
29 | vn 1.0000 0.0000 0.0000
30 | vn 0.0000 0.0000 1.0000
31 | vn 0.0000 -1.0000 0.0000
32 | vn 0.0000 1.0000 0.0000
33 | usemtl pack
34 | s off
35 | f 1/1/1 2/2/1 4/3/1 3/4/1
36 | f 3/4/2 4/3/2 8/5/2 7/6/2
37 | f 7/6/3 8/5/3 6/7/3 5/8/3
38 | f 5/8/4 6/7/4 2/9/4 1/10/4
39 | f 3/11/5 7/6/5 5/8/5 1/12/5
40 | f 8/5/6 4/13/6 2/14/6 6/7/6
41 | o chken_cheken
42 | v -0.695974 -0.976651 -0.004122
43 | v -0.319695 -0.852625 -0.257067
44 | v 0.187396 0.269045 -0.004122
45 | v 0.155231 0.046654 -0.173164
46 | v 0.187396 0.269045 -0.004122
47 | v -0.009971 -0.026913 -0.158743
48 | v 0.463203 -0.976651 -0.004122
49 | v 0.549722 -0.890132 -0.004122
50 | v 0.508870 -0.767122 -0.223969
51 | v 0.321090 -0.880648 -0.240693
52 | v -0.439289 -0.359904 -0.004122
53 | v -0.695974 -0.976651 -0.004122
54 | v -0.433613 -0.694016 -0.237826
55 | v -0.326702 -0.355187 -0.163503
56 | v 0.549722 -0.423916 -0.004122
57 | v 0.315927 0.140514 -0.004122
58 | v 0.282023 -0.090947 -0.180036
59 | v 0.441779 -0.511728 -0.208948
60 | vt 0.697716 0.500000
61 | vt 0.697716 0.500000
62 | vt 0.697716 0.750000
63 | vt 0.697716 0.750000
64 | vt 0.375000 0.250000
65 | vt 0.375000 0.250000
66 | vt 0.498776 0.301514
67 | vt 0.625000 0.427284
68 | vt 0.625000 0.427284
69 | vt 0.599205 0.453080
70 | vt 0.485929 0.500000
71 | vt 0.392364 0.500000
72 | vt 0.375000 0.482636
73 | vt 0.125000 0.500000
74 | vt 0.357636 0.500000
75 | vt 0.357636 0.750000
76 | vt 0.125000 0.750000
77 | vt 0.485929 0.750000
78 | vt 0.392364 0.750000
79 | vt 0.375000 0.000000
80 | vt 0.375000 0.000000
81 | vt 0.375000 0.767364
82 | vt 0.599205 0.796920
83 | vt 0.625000 0.822716
84 | vt 0.625000 0.822716
85 | vt 0.498776 0.948486
86 | vt 0.375000 1.000000
87 | vt 0.375000 1.000000
88 | vt 0.498776 0.000000
89 | vt 0.498776 0.250000
90 | vt 0.625000 0.000000
91 | vt 0.625000 0.250000
92 | vt 0.646125 0.500000
93 | vt 0.646125 0.750000
94 | vn -0.3311 0.6009 -0.7275
95 | vn -0.0143 0.1070 -0.9942
96 | vn -0.0104 -0.9102 -0.4141
97 | vn 0.9420 0.0943 -0.3222
98 | vn -0.4838 -0.2455 -0.8400
99 | vn 0.5206 -0.6695 -0.5299
100 | vn 0.0000 0.0000 1.0000
101 | vn -0.7921 0.3408 -0.5064
102 | vn -0.6460 0.6387 -0.4180
103 | vn 0.7662 0.3224 -0.5558
104 | vn 0.4844 0.4836 -0.7290
105 | usemtl chken
106 | s off
107 | f 12/15/7 14/16/7 13/17/7 11/18/7
108 | f 10/19/8 21/20/8 22/21/8 14/22/8 12/23/8 25/24/8 26/25/8 17/26/8 18/27/8
109 | f 10/28/9 18/29/9 15/30/9 9/31/9
110 | f 17/26/10 26/25/10 23/32/10 16/33/10
111 | f 9/34/11 20/35/11 21/20/11 10/19/11
112 | f 15/30/12 18/29/12 17/26/12 16/33/12
113 | f 15/36/13 16/33/13 23/32/13 24/37/13 11/38/13 13/39/13 19/40/13 20/41/13 9/42/13
114 | f 21/20/14 20/35/14 19/43/14 22/44/14
115 | f 13/45/15 14/46/15 22/44/15 19/43/15
116 | f 23/32/16 26/25/16 25/47/16 24/48/16
117 | f 12/15/17 11/18/17 24/48/17 25/47/17
118 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/test/test.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'test.blend'
2 | # Material Count: 1
3 |
4 | newmtl tex
5 | Ns 250.000000
6 | Ka 1.000000 1.000000 1.000000
7 | Kd 0.800000 0.800000 0.800000
8 | Ks 0.500000 0.500000 0.500000
9 | Ke 0.000000 0.000000 0.000000
10 | Ni 1.450000
11 | d 1.000000
12 | illum 2
13 | map_Kd block/birch_planks
14 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/models/item/test/test.obj:
--------------------------------------------------------------------------------
1 | # Blender v3.2.2 OBJ File: 'test.blend'
2 | # www.blender.org
3 | mtllib test.mtl
4 | o 立方体
5 | v -0.051783 0.264556 0.391743
6 | v -0.051783 0.730501 0.391743
7 | v -0.051783 0.264556 0.239970
8 | v -0.051783 0.730501 0.239970
9 | v 0.099990 0.264556 0.391743
10 | v 0.099990 0.730501 0.391743
11 | v 0.099990 0.264556 0.239970
12 | v 0.099990 0.730501 0.239970
13 | vt 0.375000 0.000000
14 | vt 0.625000 0.000000
15 | vt 0.625000 0.250000
16 | vt 0.375000 0.250000
17 | vt 0.625000 0.500000
18 | vt 0.375000 0.500000
19 | vt 0.625000 0.750000
20 | vt 0.375000 0.750000
21 | vt 0.625000 1.000000
22 | vt 0.375000 1.000000
23 | vt 0.125000 0.500000
24 | vt 0.125000 0.750000
25 | vt 0.875000 0.500000
26 | vt 0.875000 0.750000
27 | vn -1.0000 0.0000 0.0000
28 | vn 0.0000 0.0000 -1.0000
29 | vn 1.0000 0.0000 0.0000
30 | vn 0.0000 0.0000 1.0000
31 | vn 0.0000 -1.0000 0.0000
32 | vn 0.0000 1.0000 0.0000
33 | usemtl tex
34 | s off
35 | f 1/1/1 2/2/1 4/3/1 3/4/1
36 | f 3/4/2 4/3/2 8/5/2 7/6/2
37 | f 7/6/3 8/5/3 6/7/3 5/8/3
38 | f 5/8/4 6/7/4 2/9/4 1/10/4
39 | f 3/11/5 7/6/5 5/8/5 1/12/5
40 | f 8/5/6 4/13/6 2/14/6 6/7/6
41 | o 立方体.001
42 | v -0.265246 0.709407 0.393838
43 | v -0.265246 0.860616 0.393838
44 | v -0.265246 0.709407 0.237875
45 | v -0.265246 0.860616 0.237875
46 | v 0.313453 0.709407 0.393838
47 | v 0.313453 0.860616 0.393838
48 | v 0.313453 0.709407 0.237875
49 | v 0.313453 0.860616 0.237875
50 | vt 0.375000 0.000000
51 | vt 0.625000 0.000000
52 | vt 0.625000 0.250000
53 | vt 0.375000 0.250000
54 | vt 0.625000 0.500000
55 | vt 0.375000 0.500000
56 | vt 0.625000 0.750000
57 | vt 0.375000 0.750000
58 | vt 0.625000 1.000000
59 | vt 0.375000 1.000000
60 | vt 0.125000 0.500000
61 | vt 0.125000 0.750000
62 | vt 0.875000 0.500000
63 | vt 0.875000 0.750000
64 | vn -1.0000 0.0000 0.0000
65 | vn 0.0000 0.0000 -1.0000
66 | vn 1.0000 0.0000 0.0000
67 | vn 0.0000 0.0000 1.0000
68 | vn 0.0000 -1.0000 0.0000
69 | vn 0.0000 1.0000 0.0000
70 | usemtl tex
71 | s off
72 | f 9/15/7 10/16/7 12/17/7 11/18/7
73 | f 11/18/8 12/17/8 16/19/8 15/20/8
74 | f 15/20/9 16/19/9 14/21/9 13/22/9
75 | f 13/22/10 14/21/10 10/23/10 9/24/10
76 | f 11/25/11 15/20/11 13/22/11 9/26/11
77 | f 16/19/12 12/27/12 10/28/12 14/21/12
78 | o 立方体.002
79 | v 0.397554 0.709407 0.393838
80 | v 0.397554 0.860616 0.393838
81 | v 0.397554 0.709407 0.237875
82 | v 0.397554 0.860616 0.237875
83 | v 0.976252 0.709407 0.393838
84 | v 0.976252 0.860616 0.393838
85 | v 0.976252 0.709407 0.237875
86 | v 0.976252 0.860616 0.237875
87 | vt 0.375000 0.000000
88 | vt 0.625000 0.000000
89 | vt 0.625000 0.250000
90 | vt 0.375000 0.250000
91 | vt 0.625000 0.500000
92 | vt 0.375000 0.500000
93 | vt 0.625000 0.750000
94 | vt 0.375000 0.750000
95 | vt 0.625000 1.000000
96 | vt 0.375000 1.000000
97 | vt 0.125000 0.500000
98 | vt 0.125000 0.750000
99 | vt 0.875000 0.500000
100 | vt 0.875000 0.750000
101 | vn -1.0000 0.0000 0.0000
102 | vn 0.0000 0.0000 -1.0000
103 | vn 1.0000 0.0000 0.0000
104 | vn 0.0000 0.0000 1.0000
105 | vn 0.0000 -1.0000 0.0000
106 | vn 0.0000 1.0000 0.0000
107 | usemtl tex
108 | s off
109 | f 17/29/13 18/30/13 20/31/13 19/32/13
110 | f 19/32/14 20/31/14 24/33/14 23/34/14
111 | f 23/34/15 24/33/15 22/35/15 21/36/15
112 | f 21/36/16 22/35/16 18/37/16 17/38/16
113 | f 19/39/17 23/34/17 21/36/17 17/40/17
114 | f 24/33/18 20/41/18 18/42/18 22/35/18
115 | o 立方体.003
116 | v 0.398178 0.264556 0.391743
117 | v 0.398178 0.730501 0.391743
118 | v 0.398178 0.264556 0.239970
119 | v 0.398178 0.730501 0.239970
120 | v 0.549951 0.264556 0.391743
121 | v 0.549951 0.730501 0.391743
122 | v 0.549951 0.264556 0.239970
123 | v 0.549951 0.730501 0.239970
124 | vt 0.375000 0.000000
125 | vt 0.625000 0.000000
126 | vt 0.625000 0.250000
127 | vt 0.375000 0.250000
128 | vt 0.625000 0.500000
129 | vt 0.375000 0.500000
130 | vt 0.625000 0.750000
131 | vt 0.375000 0.750000
132 | vt 0.625000 1.000000
133 | vt 0.375000 1.000000
134 | vt 0.125000 0.500000
135 | vt 0.125000 0.750000
136 | vt 0.875000 0.500000
137 | vt 0.875000 0.750000
138 | vn -1.0000 0.0000 0.0000
139 | vn 0.0000 0.0000 -1.0000
140 | vn 1.0000 0.0000 0.0000
141 | vn 0.0000 0.0000 1.0000
142 | vn 0.0000 -1.0000 0.0000
143 | vn 0.0000 1.0000 0.0000
144 | usemtl tex
145 | s off
146 | f 25/43/19 26/44/19 28/45/19 27/46/19
147 | f 27/46/20 28/45/20 32/47/20 31/48/20
148 | f 31/48/21 32/47/21 30/49/21 29/50/21
149 | f 29/50/22 30/49/22 26/51/22 25/52/22
150 | f 27/53/23 31/48/23 29/50/23 25/54/23
151 | f 32/47/24 28/55/24 26/56/24 30/49/24
152 | o 立方体.004
153 | v 0.397554 0.240207 0.393838
154 | v 0.397554 0.391415 0.393838
155 | v 0.397554 0.240207 0.237875
156 | v 0.397554 0.391415 0.237875
157 | v 0.976252 0.240207 0.393838
158 | v 0.976252 0.391415 0.393838
159 | v 0.976252 0.240207 0.237875
160 | v 0.976252 0.391415 0.237875
161 | vt 0.375000 0.000000
162 | vt 0.625000 0.000000
163 | vt 0.625000 0.250000
164 | vt 0.375000 0.250000
165 | vt 0.625000 0.500000
166 | vt 0.375000 0.500000
167 | vt 0.625000 0.750000
168 | vt 0.375000 0.750000
169 | vt 0.625000 1.000000
170 | vt 0.375000 1.000000
171 | vt 0.125000 0.500000
172 | vt 0.125000 0.750000
173 | vt 0.875000 0.500000
174 | vt 0.875000 0.750000
175 | vn -1.0000 0.0000 0.0000
176 | vn 0.0000 0.0000 -1.0000
177 | vn 1.0000 0.0000 0.0000
178 | vn 0.0000 0.0000 1.0000
179 | vn 0.0000 -1.0000 0.0000
180 | vn 0.0000 1.0000 0.0000
181 | usemtl tex
182 | s off
183 | f 33/57/25 34/58/25 36/59/25 35/60/25
184 | f 35/60/26 36/59/26 40/61/26 39/62/26
185 | f 39/62/27 40/61/27 38/63/27 37/64/27
186 | f 37/64/28 38/63/28 34/65/28 33/66/28
187 | f 35/67/29 39/62/29 37/64/29 33/68/29
188 | f 40/61/30 36/69/30 34/70/30 38/63/30
189 | o 立方体.005
190 | v 0.397554 0.487739 0.393838
191 | v 0.397554 0.638948 0.393838
192 | v 0.397554 0.487739 0.237875
193 | v 0.397554 0.638948 0.237875
194 | v 0.976252 0.487739 0.393838
195 | v 0.976252 0.638948 0.393838
196 | v 0.976252 0.487739 0.237875
197 | v 0.976252 0.638948 0.237875
198 | vt 0.375000 0.000000
199 | vt 0.625000 0.000000
200 | vt 0.625000 0.250000
201 | vt 0.375000 0.250000
202 | vt 0.625000 0.500000
203 | vt 0.375000 0.500000
204 | vt 0.625000 0.750000
205 | vt 0.375000 0.750000
206 | vt 0.625000 1.000000
207 | vt 0.375000 1.000000
208 | vt 0.125000 0.500000
209 | vt 0.125000 0.750000
210 | vt 0.875000 0.500000
211 | vt 0.875000 0.750000
212 | vn -1.0000 0.0000 0.0000
213 | vn 0.0000 0.0000 -1.0000
214 | vn 1.0000 0.0000 0.0000
215 | vn 0.0000 0.0000 1.0000
216 | vn 0.0000 -1.0000 0.0000
217 | vn 0.0000 1.0000 0.0000
218 | usemtl tex
219 | s off
220 | f 41/71/31 42/72/31 44/73/31 43/74/31
221 | f 43/74/32 44/73/32 48/75/32 47/76/32
222 | f 47/76/33 48/75/33 46/77/33 45/78/33
223 | f 45/78/34 46/77/34 42/79/34 41/80/34
224 | f 43/81/35 47/76/35 45/78/35 41/82/35
225 | f 48/75/36 44/83/36 42/84/36 46/77/36
226 | o 立方体.006
227 | v 1.094479 0.709407 0.393838
228 | v 1.094479 0.860616 0.393838
229 | v 1.094479 0.709407 0.237875
230 | v 1.094479 0.860616 0.237875
231 | v 1.673178 0.709407 0.393838
232 | v 1.673178 0.860616 0.393838
233 | v 1.673178 0.709407 0.237875
234 | v 1.673178 0.860616 0.237875
235 | vt 0.375000 0.000000
236 | vt 0.625000 0.000000
237 | vt 0.625000 0.250000
238 | vt 0.375000 0.250000
239 | vt 0.625000 0.500000
240 | vt 0.375000 0.500000
241 | vt 0.625000 0.750000
242 | vt 0.375000 0.750000
243 | vt 0.625000 1.000000
244 | vt 0.375000 1.000000
245 | vt 0.125000 0.500000
246 | vt 0.125000 0.750000
247 | vt 0.875000 0.500000
248 | vt 0.875000 0.750000
249 | vn -1.0000 0.0000 0.0000
250 | vn 0.0000 0.0000 -1.0000
251 | vn 1.0000 0.0000 0.0000
252 | vn 0.0000 0.0000 1.0000
253 | vn 0.0000 -1.0000 0.0000
254 | vn 0.0000 1.0000 0.0000
255 | usemtl tex
256 | s off
257 | f 49/85/37 50/86/37 52/87/37 51/88/37
258 | f 51/88/38 52/87/38 56/89/38 55/90/38
259 | f 55/90/39 56/89/39 54/91/39 53/92/39
260 | f 53/92/40 54/91/40 50/93/40 49/94/40
261 | f 51/95/41 55/90/41 53/92/41 49/96/41
262 | f 56/89/42 52/97/42 50/98/42 54/91/42
263 | o 立方体.007
264 | v 1.099454 0.537770 0.391743
265 | v 1.099454 0.723567 0.391743
266 | v 1.099454 0.537770 0.239970
267 | v 1.099454 0.723567 0.239970
268 | v 1.251227 0.537770 0.391743
269 | v 1.251227 0.723567 0.391743
270 | v 1.251227 0.537770 0.239970
271 | v 1.251227 0.723567 0.239970
272 | vt 0.375000 0.000000
273 | vt 0.625000 0.000000
274 | vt 0.625000 0.250000
275 | vt 0.375000 0.250000
276 | vt 0.625000 0.500000
277 | vt 0.375000 0.500000
278 | vt 0.625000 0.750000
279 | vt 0.375000 0.750000
280 | vt 0.625000 1.000000
281 | vt 0.375000 1.000000
282 | vt 0.125000 0.500000
283 | vt 0.125000 0.750000
284 | vt 0.875000 0.500000
285 | vt 0.875000 0.750000
286 | vn -1.0000 0.0000 0.0000
287 | vn 0.0000 0.0000 -1.0000
288 | vn 1.0000 0.0000 0.0000
289 | vn 0.0000 0.0000 1.0000
290 | vn 0.0000 -1.0000 0.0000
291 | vn 0.0000 1.0000 0.0000
292 | usemtl tex
293 | s off
294 | f 57/99/43 58/100/43 60/101/43 59/102/43
295 | f 59/102/44 60/101/44 64/103/44 63/104/44
296 | f 63/104/45 64/103/45 62/105/45 61/106/45
297 | f 61/106/46 62/105/46 58/107/46 57/108/46
298 | f 59/109/47 63/104/47 61/106/47 57/110/47
299 | f 64/103/48 60/111/48 58/112/48 62/105/48
300 | o 立方体.008
301 | v 1.094479 0.447644 0.393838
302 | v 1.094479 0.598853 0.393838
303 | v 1.094479 0.447644 0.237875
304 | v 1.094479 0.598853 0.237875
305 | v 1.673178 0.447644 0.393838
306 | v 1.673178 0.598853 0.393838
307 | v 1.673178 0.447644 0.237875
308 | v 1.673178 0.598853 0.237875
309 | vt 0.375000 0.000000
310 | vt 0.625000 0.000000
311 | vt 0.625000 0.250000
312 | vt 0.375000 0.250000
313 | vt 0.625000 0.500000
314 | vt 0.375000 0.500000
315 | vt 0.625000 0.750000
316 | vt 0.375000 0.750000
317 | vt 0.625000 1.000000
318 | vt 0.375000 1.000000
319 | vt 0.125000 0.500000
320 | vt 0.125000 0.750000
321 | vt 0.875000 0.500000
322 | vt 0.875000 0.750000
323 | vn -1.0000 0.0000 0.0000
324 | vn 0.0000 0.0000 -1.0000
325 | vn 1.0000 0.0000 0.0000
326 | vn 0.0000 0.0000 1.0000
327 | vn 0.0000 -1.0000 0.0000
328 | vn 0.0000 1.0000 0.0000
329 | usemtl tex
330 | s off
331 | f 65/113/49 66/114/49 68/115/49 67/116/49
332 | f 67/116/50 68/115/50 72/117/50 71/118/50
333 | f 71/118/51 72/117/51 70/119/51 69/120/51
334 | f 69/120/52 70/119/52 66/121/52 65/122/52
335 | f 67/123/53 71/118/53 69/120/53 65/124/53
336 | f 72/117/54 68/125/54 66/126/54 70/119/54
337 | o 立方体.009
338 | v 1.517694 0.271846 0.391743
339 | v 1.517694 0.457643 0.391743
340 | v 1.517694 0.271846 0.239970
341 | v 1.517694 0.457643 0.239970
342 | v 1.669467 0.271846 0.391743
343 | v 1.669467 0.457643 0.391743
344 | v 1.669467 0.271846 0.239970
345 | v 1.669467 0.457643 0.239970
346 | vt 0.375000 0.000000
347 | vt 0.625000 0.000000
348 | vt 0.625000 0.250000
349 | vt 0.375000 0.250000
350 | vt 0.625000 0.500000
351 | vt 0.375000 0.500000
352 | vt 0.625000 0.750000
353 | vt 0.375000 0.750000
354 | vt 0.625000 1.000000
355 | vt 0.375000 1.000000
356 | vt 0.125000 0.500000
357 | vt 0.125000 0.750000
358 | vt 0.875000 0.500000
359 | vt 0.875000 0.750000
360 | vn -1.0000 0.0000 0.0000
361 | vn 0.0000 0.0000 -1.0000
362 | vn 1.0000 0.0000 0.0000
363 | vn 0.0000 0.0000 1.0000
364 | vn 0.0000 -1.0000 0.0000
365 | vn 0.0000 1.0000 0.0000
366 | usemtl tex
367 | s off
368 | f 73/127/55 74/128/55 76/129/55 75/130/55
369 | f 75/130/56 76/129/56 80/131/56 79/132/56
370 | f 79/132/57 80/131/57 78/133/57 77/134/57
371 | f 77/134/58 78/133/58 74/135/58 73/136/58
372 | f 75/137/59 79/132/59 77/134/59 73/138/59
373 | f 80/131/60 76/139/60 74/140/60 78/133/60
374 | o 立方体.010
375 | v 1.094479 0.236851 0.393838
376 | v 1.094479 0.388060 0.393838
377 | v 1.094479 0.236851 0.237875
378 | v 1.094479 0.388060 0.237875
379 | v 1.673178 0.236851 0.393838
380 | v 1.673178 0.388060 0.393838
381 | v 1.673178 0.236851 0.237875
382 | v 1.673178 0.388060 0.237875
383 | vt 0.375000 0.000000
384 | vt 0.625000 0.000000
385 | vt 0.625000 0.250000
386 | vt 0.375000 0.250000
387 | vt 0.625000 0.500000
388 | vt 0.375000 0.500000
389 | vt 0.625000 0.750000
390 | vt 0.375000 0.750000
391 | vt 0.625000 1.000000
392 | vt 0.375000 1.000000
393 | vt 0.125000 0.500000
394 | vt 0.125000 0.750000
395 | vt 0.875000 0.500000
396 | vt 0.875000 0.750000
397 | vn -1.0000 0.0000 0.0000
398 | vn 0.0000 0.0000 -1.0000
399 | vn 1.0000 0.0000 0.0000
400 | vn 0.0000 0.0000 1.0000
401 | vn 0.0000 -1.0000 0.0000
402 | vn 0.0000 1.0000 0.0000
403 | usemtl tex
404 | s off
405 | f 81/141/61 82/142/61 84/143/61 83/144/61
406 | f 83/144/62 84/143/62 88/145/62 87/146/62
407 | f 87/146/63 88/145/63 86/147/63 85/148/63
408 | f 85/148/64 86/147/64 82/149/64 81/150/64
409 | f 83/151/65 87/146/65 85/148/65 81/152/65
410 | f 88/145/66 84/153/66 82/154/66 86/147/66
411 | o 立方体.011
412 | v 1.730660 0.709407 0.393838
413 | v 1.730660 0.860616 0.393838
414 | v 1.730660 0.709407 0.237875
415 | v 1.730660 0.860616 0.237875
416 | v 2.309359 0.709407 0.393838
417 | v 2.309359 0.860616 0.393838
418 | v 2.309359 0.709407 0.237875
419 | v 2.309359 0.860616 0.237875
420 | vt 0.375000 0.000000
421 | vt 0.625000 0.000000
422 | vt 0.625000 0.250000
423 | vt 0.375000 0.250000
424 | vt 0.625000 0.500000
425 | vt 0.375000 0.500000
426 | vt 0.625000 0.750000
427 | vt 0.375000 0.750000
428 | vt 0.625000 1.000000
429 | vt 0.375000 1.000000
430 | vt 0.125000 0.500000
431 | vt 0.125000 0.750000
432 | vt 0.875000 0.500000
433 | vt 0.875000 0.750000
434 | vn -1.0000 0.0000 0.0000
435 | vn 0.0000 0.0000 -1.0000
436 | vn 1.0000 0.0000 0.0000
437 | vn 0.0000 0.0000 1.0000
438 | vn 0.0000 -1.0000 0.0000
439 | vn 0.0000 1.0000 0.0000
440 | usemtl tex
441 | s off
442 | f 89/155/67 90/156/67 92/157/67 91/158/67
443 | f 91/158/68 92/157/68 96/159/68 95/160/68
444 | f 95/160/69 96/159/69 94/161/69 93/162/69
445 | f 93/162/70 94/161/70 90/163/70 89/164/70
446 | f 91/165/71 95/160/71 93/162/71 89/166/71
447 | f 96/159/72 92/167/72 90/168/72 94/161/72
448 | o 立方体.012
449 | v 1.944123 0.264556 0.391743
450 | v 1.944123 0.730501 0.391743
451 | v 1.944123 0.264556 0.239970
452 | v 1.944123 0.730501 0.239970
453 | v 2.095896 0.264556 0.391743
454 | v 2.095896 0.730501 0.391743
455 | v 2.095896 0.264556 0.239970
456 | v 2.095896 0.730501 0.239970
457 | vt 0.375000 0.000000
458 | vt 0.625000 0.000000
459 | vt 0.625000 0.250000
460 | vt 0.375000 0.250000
461 | vt 0.625000 0.500000
462 | vt 0.375000 0.500000
463 | vt 0.625000 0.750000
464 | vt 0.375000 0.750000
465 | vt 0.625000 1.000000
466 | vt 0.375000 1.000000
467 | vt 0.125000 0.500000
468 | vt 0.125000 0.750000
469 | vt 0.875000 0.500000
470 | vt 0.875000 0.750000
471 | vn -1.0000 0.0000 0.0000
472 | vn 0.0000 0.0000 -1.0000
473 | vn 1.0000 0.0000 0.0000
474 | vn 0.0000 0.0000 1.0000
475 | vn 0.0000 -1.0000 0.0000
476 | vn 0.0000 1.0000 0.0000
477 | usemtl tex
478 | s off
479 | f 97/169/73 98/170/73 100/171/73 99/172/73
480 | f 99/172/74 100/171/74 104/173/74 103/174/74
481 | f 103/174/75 104/173/75 102/175/75 101/176/75
482 | f 101/176/76 102/175/76 98/177/76 97/178/76
483 | f 99/179/77 103/174/77 101/176/77 97/180/77
484 | f 104/173/78 100/181/78 98/182/78 102/175/78
485 |
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/sml_load_scopes/test.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "entry": [
4 | "test:.*"
5 | ]
6 | }
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/textures/block/body.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/test/resources/assets/special-model-loader-test/textures/block/body.png
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/textures/block/eay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/test/resources/assets/special-model-loader-test/textures/block/eay.png
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/textures/block/facing_model_block_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/test/resources/assets/special-model-loader-test/textures/block/facing_model_block_front.png
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/textures/block/facing_model_block_side.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/test/resources/assets/special-model-loader-test/textures/block/facing_model_block_side.png
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/textures/block/facing_model_block_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/test/resources/assets/special-model-loader-test/textures/block/facing_model_block_top.png
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/textures/block/normal_model_block.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/test/resources/assets/special-model-loader-test/textures/block/normal_model_block.png
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/textures/item/cheken.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/test/resources/assets/special-model-loader-test/textures/item/cheken.png
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/textures/item/cheken_pack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/test/resources/assets/special-model-loader-test/textures/item/cheken_pack.png
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/textures/item/normal_model_item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/test/resources/assets/special-model-loader-test/textures/item/normal_model_item.png
--------------------------------------------------------------------------------
/src/test/resources/assets/special-model-loader-test/textures/item/parabolic_antenna.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/src/test/resources/assets/special-model-loader-test/textures/item/parabolic_antenna.png
--------------------------------------------------------------------------------
/src/test/resources/fabric.mod.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": 1,
3 | "id": "special-model-loader-test",
4 | "version": "1.0.0",
5 | "name": "Special Model Loader Test",
6 | "description": "The ikisugi test mod...",
7 | "authors": [
8 | "MORIMORI0317"
9 | ],
10 | "contact": {
11 | },
12 | "license": "IKISUGI",
13 | "environment": "*",
14 | "entrypoints": {
15 | "main": [
16 | "dev.felnull.smltest.SMLTest"
17 | ],
18 | "client": [
19 | "dev.felnull.smltest.client.SMLTestClient"
20 | ],
21 | "fabric-datagen": [
22 | "dev.felnull.smltest.data.SMLTestDataGenerator"
23 | ]
24 | },
25 | "depends": {
26 | "fabricloader": ">=0.16.9",
27 | "java": ">=21",
28 | "fabric-api": "*"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/test-resourcepacks/SMLTestPack.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/test-resourcepacks/SMLTestPack.zip
--------------------------------------------------------------------------------
/test-resourcepacks/SMLTestPack/assets/minecraft/models/item/3d_apple.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: '3d_apple.blend'
2 | # Material Count: 1
3 |
4 | newmtl マテリアル
5 | Ns 250.000000
6 | Ka 1.000000 1.000000 1.000000
7 | Kd 0.800000 0.800000 0.800000
8 | Ks 0.500000 0.500000 0.500000
9 | Ke 0.000000 0.000000 0.000000
10 | Ni 1.450000
11 | d 1.000000
12 | illum 2
13 | map_Kd item/3d_apple
14 |
--------------------------------------------------------------------------------
/test-resourcepacks/SMLTestPack/assets/minecraft/models/item/3d_apple.obj:
--------------------------------------------------------------------------------
1 | # Blender v3.2.2 OBJ File: '3d_apple.blend'
2 | # www.blender.org
3 | mtllib 3d_apple.mtl
4 | o 球
5 | v 0.500000 0.500000 0.000000
6 | v 0.500000 0.146447 0.146447
7 | v 0.853553 0.853553 0.500000
8 | v 1.000000 0.500000 0.500000
9 | v 0.853553 0.146447 0.500000
10 | v 0.500000 1.000000 0.500000
11 | v 0.500000 0.853553 0.853553
12 | v 0.500000 0.500000 1.000000
13 | v 0.500000 0.146447 0.853553
14 | v 0.500000 0.000000 0.500000
15 | v 0.146447 0.853553 0.500000
16 | v -0.000000 0.500000 0.500000
17 | v 0.146447 0.146447 0.500000
18 | v 0.500000 0.853553 0.146447
19 | v 0.505114 1.198274 0.499034
20 | v 0.505114 0.948205 0.499034
21 | v 0.517079 1.198274 0.507727
22 | v 0.517079 0.948205 0.507727
23 | v 0.512508 1.198274 0.521793
24 | v 0.512508 0.948205 0.521793
25 | v 0.497719 1.198274 0.521793
26 | v 0.497719 0.948205 0.521793
27 | v 0.493149 1.198274 0.507727
28 | v 0.493149 0.948205 0.507727
29 | v 0.501273 1.086047 0.424095
30 | v 0.522778 1.092430 0.503667
31 | v 0.492983 1.082099 0.548012
32 | v 0.477389 1.115799 0.431938
33 | v 0.497546 1.146957 0.315857
34 | v 0.525598 1.132514 0.360189
35 | v 0.512185 1.126127 0.560689
36 | v 0.484133 1.140570 0.516357
37 | v 0.486953 1.180654 0.372879
38 | v 0.516748 1.190984 0.328534
39 | v 0.532342 1.157285 0.444608
40 | v 0.508459 1.187037 0.452451
41 | vt 0.343535 0.280806
42 | vt 0.172382 0.328915
43 | vt 0.172382 0.000410
44 | vt 0.343535 0.048518
45 | vt 0.529655 0.659058
46 | vt 0.529655 0.836844
47 | vt 0.353786 0.810808
48 | vt 0.352967 0.836844
49 | vt 0.177098 0.810808
50 | vt 0.352967 0.659058
51 | vt 0.687479 0.328915
52 | vt 0.516326 0.280806
53 | vt 0.516326 0.048518
54 | vt 0.687479 0.000410
55 | vt 0.171563 0.280806
56 | vt 0.000410 0.328915
57 | vt 0.000410 0.000410
58 | vt 0.171563 0.048518
59 | vt 0.823721 0.026446
60 | vt 0.999590 0.000410
61 | vt 0.999590 0.178195
62 | vt 0.864167 0.507520
63 | vt 0.688298 0.481483
64 | vt 0.864167 0.329734
65 | vt 0.515507 0.328915
66 | vt 0.344354 0.280806
67 | vt 0.344354 0.048518
68 | vt 0.515507 0.000410
69 | vt 0.172382 0.377842
70 | vt 0.343535 0.329734
71 | vt 0.343535 0.658239
72 | vt 0.172382 0.610131
73 | vt 0.822902 0.232698
74 | vt 0.688298 0.116554
75 | vt 0.822902 0.000410
76 | vt 0.706343 0.659058
77 | vt 0.706343 0.836844
78 | vt 0.530474 0.685094
79 | vt 0.000410 0.329734
80 | vt 0.171563 0.377842
81 | vt 0.171563 0.610131
82 | vt 0.000410 0.658239
83 | vt 0.516326 0.377842
84 | vt 0.687479 0.329734
85 | vt 0.687479 0.658239
86 | vt 0.516326 0.610131
87 | vt 0.176279 0.659058
88 | vt 0.176279 0.836844
89 | vt 0.000410 0.810808
90 | vt 0.883031 0.659058
91 | vt 0.883031 0.836844
92 | vt 0.707162 0.685094
93 | vt 0.515507 0.658239
94 | vt 0.344354 0.610131
95 | vt 0.344354 0.377842
96 | vt 0.515507 0.329734
97 | vt 0.784786 0.508339
98 | vt 0.784786 0.624515
99 | vt 0.777915 0.624515
100 | vt 0.777915 0.508339
101 | vt 0.792476 0.508339
102 | vt 0.792476 0.624515
103 | vt 0.785605 0.624515
104 | vt 0.785605 0.508339
105 | vt 0.777096 0.508339
106 | vt 0.777096 0.624516
107 | vt 0.770226 0.624516
108 | vt 0.770226 0.508339
109 | vt 0.721656 0.574769
110 | vt 0.715121 0.576892
111 | vt 0.711083 0.571333
112 | vt 0.715121 0.565775
113 | vt 0.721656 0.567898
114 | vt 0.688298 0.651369
115 | vt 0.804475 0.651368
116 | vt 0.804475 0.658239
117 | vt 0.688298 0.658239
118 | vt 0.688298 0.643679
119 | vt 0.804475 0.643679
120 | vt 0.804475 0.650549
121 | vt 0.688298 0.650549
122 | vt 0.721656 0.299947
123 | vt 0.715121 0.302070
124 | vt 0.711083 0.296512
125 | vt 0.715121 0.290953
126 | vt 0.721656 0.293076
127 | vt 0.796897 0.291243
128 | vt 0.783798 0.255138
129 | vt 0.796897 0.233517
130 | vt 0.750579 0.577560
131 | vt 0.733927 0.542949
132 | vt 0.750579 0.508339
133 | vt 0.751398 0.563184
134 | vt 0.769406 0.508339
135 | vt 0.769406 0.564956
136 | vt 0.744643 0.303557
137 | vt 0.744643 0.321653
138 | vt 0.688298 0.316109
139 | vt 0.806394 0.508339
140 | vt 0.806394 0.566065
141 | vt 0.793295 0.544444
142 | vt 0.710263 0.508339
143 | vt 0.710263 0.577560
144 | vt 0.688298 0.542949
145 | vt 0.791752 0.303557
146 | vt 0.791752 0.328837
147 | vt 0.769017 0.307525
148 | vt 0.710323 0.578379
149 | vt 0.710323 0.634996
150 | vt 0.688298 0.612952
151 | vt 0.733167 0.578379
152 | vt 0.733167 0.634997
153 | vt 0.711142 0.600424
154 | vt 0.792571 0.307904
155 | vt 0.817474 0.303557
156 | vt 0.817474 0.326636
157 | vt 0.711083 0.542912
158 | vt 0.733108 0.508339
159 | vt 0.733108 0.564956
160 | vt 0.745462 0.307525
161 | vt 0.768198 0.303557
162 | vt 0.768198 0.328837
163 | vt 0.688298 0.268128
164 | vt 0.710264 0.233517
165 | vt 0.710264 0.302738
166 | vt 0.818198 0.589963
167 | vt 0.793295 0.571230
168 | vt 0.818198 0.566884
169 | vt 0.711083 0.255561
170 | vt 0.733108 0.233517
171 | vt 0.733108 0.290134
172 | vt 0.751649 0.636106
173 | vt 0.733986 0.582314
174 | vt 0.751649 0.578379
175 | vt 0.752468 0.600000
176 | vt 0.765567 0.578379
177 | vt 0.765567 0.636106
178 | vt 0.750579 0.233517
179 | vt 0.750579 0.302738
180 | vt 0.733927 0.268128
181 | vt 0.782979 0.291243
182 | vt 0.769880 0.269622
183 | vt 0.782979 0.233517
184 | vt 0.751398 0.287309
185 | vt 0.769061 0.233517
186 | vt 0.769061 0.291243
187 | vn 0.6786 -0.2811 -0.6786
188 | vn 0.3574 0.8629 -0.3574
189 | vn 0.3574 -0.8629 -0.3574
190 | vn 0.6786 0.2811 -0.6786
191 | vn 0.6786 -0.2811 0.6786
192 | vn 0.3574 0.8629 0.3574
193 | vn 0.3574 -0.8629 0.3574
194 | vn 0.6786 0.2811 0.6786
195 | vn -0.6786 -0.2811 0.6786
196 | vn -0.3574 0.8629 0.3574
197 | vn -0.3574 -0.8629 0.3574
198 | vn -0.6786 0.2811 0.6786
199 | vn -0.6786 -0.2811 -0.6786
200 | vn -0.3574 0.8629 -0.3574
201 | vn -0.3574 -0.8629 -0.3574
202 | vn -0.6786 0.2811 -0.6786
203 | vn -0.5878 0.0000 0.8090
204 | vn -0.9511 0.0000 -0.3090
205 | vn 0.0000 0.0000 -1.0000
206 | vn 0.0000 1.0000 0.0000
207 | vn 0.9511 0.0000 -0.3090
208 | vn 0.5878 0.0000 0.8090
209 | vn 0.0000 -1.0000 0.0000
210 | vn 0.3154 -0.9489 -0.0091
211 | vn 0.7687 -0.6198 -0.1580
212 | vn -0.7870 -0.6127 -0.0722
213 | vn -0.7828 -0.5534 -0.2845
214 | vn 0.3245 -0.8195 -0.4723
215 | vn 0.9848 -0.1712 -0.0285
216 | vn 0.7824 -0.4616 0.4181
217 | vn -0.9900 -0.0924 0.1062
218 | vn -0.9845 -0.0139 -0.1747
219 | vn 0.8017 -0.1861 -0.5679
220 | vn 0.9845 0.0139 0.1747
221 | vn -0.8017 0.1861 0.5680
222 | vn -0.9848 0.1712 0.0285
223 | vn -0.7824 0.4616 -0.4181
224 | vn 0.9900 0.0924 -0.1062
225 | vn 0.7828 0.5534 0.2845
226 | vn -0.3245 0.8195 0.4723
227 | vn -0.7687 0.6198 0.1580
228 | vn -0.3154 0.9489 0.0091
229 | vn 0.7870 0.6127 0.0722
230 | usemtl マテリアル
231 | s off
232 | f 2/1/1 1/2/1 4/3/1 5/4/1
233 | f 14/5/2 6/6/2 3/7/2
234 | f 10/8/3 2/9/3 5/10/3
235 | f 1/11/4 14/12/4 3/13/4 4/14/4
236 | f 5/15/5 4/16/5 8/17/5 9/18/5
237 | f 3/19/6 6/20/6 7/21/6
238 | f 10/22/7 5/23/7 9/24/7
239 | f 4/25/8 3/26/8 7/27/8 8/28/8
240 | f 9/29/9 8/30/9 12/31/9 13/32/9
241 | f 7/33/10 6/34/10 11/35/10
242 | f 10/36/11 9/37/11 13/38/11
243 | f 8/39/12 7/40/12 11/41/12 12/42/12
244 | f 13/43/13 12/44/13 1/45/13 2/46/13
245 | f 11/47/14 6/48/14 14/49/14
246 | f 10/50/15 13/51/15 2/52/15
247 | f 12/53/16 11/54/16 14/55/16 1/56/16
248 | f 15/57/17 16/58/17 18/59/17 17/60/17
249 | f 17/61/18 18/62/18 20/63/18 19/64/18
250 | f 19/65/19 20/66/19 22/67/19 21/68/19
251 | f 18/69/20 16/70/20 24/71/20 22/72/20 20/73/20
252 | f 21/74/21 22/75/21 24/76/21 23/77/21
253 | f 23/78/22 24/79/22 16/80/22 15/81/22
254 | f 15/82/23 17/83/23 19/84/23 21/85/23 23/86/23
255 | f 25/87/24 26/88/24 27/89/24
256 | f 26/90/25 25/91/25 30/92/25
257 | f 25/93/26 27/94/26 28/95/26
258 | f 25/96/27 28/97/27 29/98/27
259 | f 25/99/28 29/100/28 30/101/28
260 | f 26/102/29 30/103/29 35/104/29
261 | f 27/105/30 26/106/30 31/107/30
262 | f 28/108/31 27/109/31 32/110/31
263 | f 29/111/32 28/112/32 33/113/32
264 | f 30/114/33 29/115/33 34/116/33
265 | f 26/117/34 35/118/34 31/119/34
266 | f 27/120/35 31/121/35 32/122/35
267 | f 28/123/36 32/124/36 33/125/36
268 | f 29/126/37 33/127/37 34/128/37
269 | f 30/129/38 34/130/38 35/131/38
270 | f 31/132/39 35/133/39 36/134/39
271 | f 32/135/40 31/136/40 36/137/40
272 | f 33/138/41 32/139/41 36/140/41
273 | f 34/141/42 33/142/42 36/143/42
274 | f 35/144/43 34/145/43 36/146/43
275 |
--------------------------------------------------------------------------------
/test-resourcepacks/SMLTestPack/assets/minecraft/models/item/apple.json:
--------------------------------------------------------------------------------
1 | {
2 | "parent": "special-model-loader:builtin/obj",
3 | "ambientocclusion": true,
4 | "flip_v": true,
5 | "model": "minecraft:models/item/3d_apple.obj"
6 | }
--------------------------------------------------------------------------------
/test-resourcepacks/SMLTestPack/assets/minecraft/textures/item/3d_apple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/test-resourcepacks/SMLTestPack/assets/minecraft/textures/item/3d_apple.png
--------------------------------------------------------------------------------
/test-resourcepacks/SMLTestPack/assets/sml-test-pack/sml_load_scopes/test_scopes.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "entry": [
4 | "minecraft:item/apple"
5 | ]
6 | }
--------------------------------------------------------------------------------
/test-resourcepacks/SMLTestPack/pack.mcmeta:
--------------------------------------------------------------------------------
1 | {
2 | "pack": {
3 | "pack_format": 12,
4 | "description": "The SML Test Pack"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test-resourcepacks/SMLTestPack/pack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamFelNull/SpecialModelLoader/c7ad159a7232da77e43422e84a6f4b6a76a4ebd2/test-resourcepacks/SMLTestPack/pack.png
--------------------------------------------------------------------------------