mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
fbx loader improvements, test map
This commit is contained in:
Generated
+235
-241
@@ -5,16 +5,20 @@
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="1932b2c4-d6ff-413c-9558-19959667326b" name="Default Changelist" comment="scene graph">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Cargo.lock" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.lock" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.toml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/engine/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/engine/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/main.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/math/mat4.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/math/mat4.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/math/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/math/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/math/quat.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/math/quat.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/math/triangulator.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/math/triangulator.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/math/vec2.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/math/vec2.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/math/vec3.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/math/vec3.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/math/vec4.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/math/vec4.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/renderer/renderer.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/renderer/renderer.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/renderer/surface.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/renderer/surface.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/resource/fbx/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/resource/fbx/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/scene/node.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/scene/node.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/utils/pool.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/pool.rs" afterDir="false" />
|
||||
</list>
|
||||
<ignored path="$PROJECT_DIR$/target/" />
|
||||
@@ -28,64 +32,10 @@
|
||||
<component name="FileEditorManager">
|
||||
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/math/vec3.rs">
|
||||
<entry file="file://$PROJECT_DIR$/src/resource/fbx/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="294">
|
||||
<caret line="56" column="11" selection-start-line="56" selection-start-column="11" selection-end-line="56" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/src/math/triangulator.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="340">
|
||||
<caret line="115" column="51" selection-start-line="115" selection-start-column="51" selection-end-line="115" selection-end-column="51" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libstd/macros.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="387">
|
||||
<caret line="844" column="17" selection-start-line="844" selection-start-column="17" selection-end-line="844" selection-end-column="17" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/fmt/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="315">
|
||||
<caret line="67" column="29" lean-forward="true" selection-start-line="67" selection-start-column="29" selection-end-line="67" selection-end-column="29" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/result.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="322">
|
||||
<caret line="245" column="9" selection-start-line="245" selection-start-column="9" selection-end-line="245" selection-end-column="9" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="17">
|
||||
<caret line="1" column="20" selection-start-line="1" selection-start-column="20" selection-end-line="1" selection-end-column="20" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/math/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="330">
|
||||
<caret line="63" selection-start-line="63" selection-end-line="63" />
|
||||
<state relative-caret-position="515">
|
||||
<caret line="320" column="31" selection-start-line="320" selection-start-column="31" selection-end-line="320" selection-end-column="31" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
@@ -93,8 +43,53 @@
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/math/mat4.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="530">
|
||||
<caret line="201" column="11" selection-start-line="201" selection-start-column="11" selection-end-line="201" selection-end-column="11" />
|
||||
<state relative-caret-position="357">
|
||||
<caret line="136" selection-start-line="136" selection-end-line="136" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/resource/texture.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="527">
|
||||
<caret line="31" selection-start-line="31" selection-end-line="31" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/scene/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="884">
|
||||
<caret line="52" column="11" selection-start-line="52" selection-start-column="11" selection-end-line="52" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/renderer/surface.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="972">
|
||||
<caret line="338" column="13" selection-start-line="338" selection-start-column="13" selection-end-line="338" selection-end-column="13" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/math/vec3.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="629">
|
||||
<caret line="42" column="30" lean-forward="true" selection-start-line="42" selection-start-column="30" selection-end-line="42" selection-end-column="30" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/src/renderer/renderer.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="422">
|
||||
<caret line="125" column="41" selection-start-line="125" selection-start-column="41" selection-end-line="125" selection-end-column="41" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
@@ -103,16 +98,25 @@
|
||||
<entry file="file://$PROJECT_DIR$/src/math/vec2.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="34">
|
||||
<caret line="2" column="27" selection-start-line="2" selection-start-column="27" selection-end-line="2" selection-end-column="27" />
|
||||
<caret line="2" column="38" selection-start-line="2" selection-start-column="38" selection-end-line="2" selection-end-column="38" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/resource/mod.rs">
|
||||
<entry file="file://$PROJECT_DIR$/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="17">
|
||||
<caret line="1" column="10" selection-start-line="1" selection-start-column="10" selection-end-line="1" selection-end-column="10" />
|
||||
<state relative-caret-position="565">
|
||||
<caret line="264" column="29" lean-forward="true" selection-start-line="264" selection-start-column="29" selection-end-line="264" selection-end-column="29" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/engine/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="864">
|
||||
<caret line="109" column="11" selection-start-line="109" selection-start-column="11" selection-end-line="109" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
@@ -128,16 +132,21 @@
|
||||
</component>
|
||||
<component name="FindInProjectRecents">
|
||||
<findStrings>
|
||||
<find>b-></find>
|
||||
<find>a-></find>
|
||||
<find>cursorst</find>
|
||||
<find>find_node</find>
|
||||
<find>Handle</find>
|
||||
<find>type_id</find>
|
||||
<find>b-></find>
|
||||
<find>borrow</find>
|
||||
<find>materials</find>
|
||||
</findStrings>
|
||||
<replaceStrings>
|
||||
<replace>b.</replace>
|
||||
</replaceStrings>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="ROOT_SYNC" value="DONT_SYNC" />
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="IdeDocumentHistory">
|
||||
@@ -145,28 +154,29 @@
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/src/pool.rs" />
|
||||
<option value="$PROJECT_DIR$/src/vec3.rs" />
|
||||
<option value="$PROJECT_DIR$/src/math/vec4.rs" />
|
||||
<option value="$PROJECT_DIR$/src/core/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/src/core/pool.rs" />
|
||||
<option value="$PROJECT_DIR$/src/scene/scene.rs" />
|
||||
<option value="$PROJECT_DIR$/src/renderer/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/src/resource/texture.rs" />
|
||||
<option value="$PROJECT_DIR$/src/resource/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/src/math/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/src/utils/persistent_pool.rs" />
|
||||
<option value="$PROJECT_DIR$/src/utils/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/src/math/quat.rs" />
|
||||
<option value="$PROJECT_DIR$/src/renderer/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/src/scene/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/src/resource/texture.rs" />
|
||||
<option value="$PROJECT_DIR$/src/renderer/renderer.rs" />
|
||||
<option value="$PROJECT_DIR$/src/math/vec2.rs" />
|
||||
<option value="$PROJECT_DIR$/src/math/triangulator.rs" />
|
||||
<option value="$PROJECT_DIR$/src/scene/node.rs" />
|
||||
<option value="$PROJECT_DIR$/src/math/vec4.rs" />
|
||||
<option value="$PROJECT_DIR$/src/renderer/surface.rs" />
|
||||
<option value="$PROJECT_DIR$/src/engine/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/src/resource/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/src/utils/pool.rs" />
|
||||
<option value="$PROJECT_DIR$/src/scene/node.rs" />
|
||||
<option value="$PROJECT_DIR$/src/resource/fbx/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/src/math/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/src/math/vec2.rs" />
|
||||
<option value="$PROJECT_DIR$/src/main.rs" />
|
||||
<option value="$PROJECT_DIR$/src/math/vec3.rs" />
|
||||
<option value="$PROJECT_DIR$/src/math/mat4.rs" />
|
||||
<option value="$PROJECT_DIR$/src/math/triangulator.rs" />
|
||||
<option value="$PROJECT_DIR$/src/math/vec3.rs" />
|
||||
<option value="$PROJECT_DIR$/src/main.rs" />
|
||||
<option value="$PROJECT_DIR$/src/renderer/renderer.rs" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
@@ -188,6 +198,8 @@
|
||||
<foldersAlwaysOnTop value="true" />
|
||||
</navigator>
|
||||
<panes>
|
||||
<pane id="PackagesPane" />
|
||||
<pane id="Scope" />
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<expand>
|
||||
@@ -252,18 +264,17 @@
|
||||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="PackagesPane" />
|
||||
<pane id="Scope" />
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1559414534374" />
|
||||
<property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1560693432309" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/../Program Files/Git/bin/git.exe" />
|
||||
<property name="org.rust.cargo.project.model.PROJECT_DISCOVERY" value="true" />
|
||||
<property name="project.structure.last.edited" value="Project" />
|
||||
<property name="project.structure.proportion" value="0.0" />
|
||||
<property name="project.structure.side.proportion" value="0.0" />
|
||||
<property name="project.structure.side.proportion" value="0.2" />
|
||||
<property name="run.code.analysis.last.selected.profile" value="pProject Default" />
|
||||
<property name="settings.editor.selected.configurable" value="reference.settingsdialog.IDE.editor.colors.Language Defaults" />
|
||||
<property name="settings.editor.selected.configurable" value="vcs.Git" />
|
||||
<property name="settings.editor.splitter.proportion" value="0.23435949" />
|
||||
</component>
|
||||
<component name="RunDashboard">
|
||||
@@ -278,7 +289,7 @@
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="RunManager" selected="Cargo Command.Test">
|
||||
<component name="RunManager" selected="Cargo Command.Release">
|
||||
<configuration name="Debug" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="command" value="run --package rg3d --bin rg3d" />
|
||||
@@ -309,11 +320,6 @@
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<list>
|
||||
<item itemvalue="Cargo Command.Release" />
|
||||
<item itemvalue="Cargo Command.Test" />
|
||||
<item itemvalue="Cargo Command.Debug" />
|
||||
</list>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Cargo Command.Debug" />
|
||||
@@ -383,7 +389,7 @@
|
||||
<frame x="0" y="0" width="1280" height="1400" extended-state="0" />
|
||||
<editor active="true" />
|
||||
<layout>
|
||||
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.15081967" />
|
||||
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.17295082" />
|
||||
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
|
||||
<window_info id="Image Layers" order="2" />
|
||||
<window_info id="Designer" order="3" />
|
||||
@@ -392,7 +398,7 @@
|
||||
<window_info id="Favorites" order="6" side_tool="true" />
|
||||
<window_info anchor="bottom" id="Message" order="0" />
|
||||
<window_info anchor="bottom" id="Find" order="1" weight="0.23264985" />
|
||||
<window_info active="true" anchor="bottom" id="Run" order="2" sideWeight="0.49925372" visible="true" weight="0.2626183" />
|
||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49925372" visible="true" weight="0.18690851" />
|
||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||
@@ -422,39 +428,6 @@
|
||||
<option name="FILTER_TARGETS" value="false" />
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$USER_HOME$/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.19.0/src/lib.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="5576">
|
||||
<caret line="344" column="11" selection-start-line="344" selection-start-column="11" selection-end-line="344" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/liballoc/macros.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="731">
|
||||
<caret line="43" column="17" lean-forward="true" selection-start-line="43" selection-start-column="17" selection-end-line="43" selection-end-column="17" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.19.0/src/window.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="309">
|
||||
<caret line="250" column="11" selection-start-line="250" selection-start-column="11" selection-end-line="250" selection-end-column="11" />
|
||||
<folding>
|
||||
<element signature="e#8111#8112#0" expanded="true" />
|
||||
<element signature="e#8154#8155#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/num/f32.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="309">
|
||||
<caret line="356" column="11" selection-start-line="356" selection-start-column="11" selection-end-line="356" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/vec3.rs" />
|
||||
<entry file="file://$PROJECT_DIR$/src/core/mod.rs" />
|
||||
<entry file="file://$PROJECT_DIR$/src/core/pool.rs" />
|
||||
<entry file="file://$PROJECT_DIR$/src/scene/scene.rs" />
|
||||
@@ -487,13 +460,6 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/math/vec4.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="34">
|
||||
<caret line="2" column="4" selection-start-line="2" selection-start-column="4" selection-end-line="2" selection-end-column="4" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.cargo/registry/src/github.com-1ecc6299db9ec823/image-0.21.0/src/lib.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="527">
|
||||
@@ -530,17 +496,6 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/clone.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="3400">
|
||||
<caret line="208" column="11" selection-start-line="208" selection-start-column="11" selection-end-line="208" selection-end-column="11" />
|
||||
<folding>
|
||||
<element signature="e#7200#7201#0" expanded="true" />
|
||||
<element signature="e#7228#7229#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.19.0/src/events.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1428">
|
||||
@@ -548,13 +503,6 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/renderer/surface.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="5304">
|
||||
<caret line="312" column="67" selection-start-line="312" selection-start-column="67" selection-end-line="312" selection-end-column="67" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libstd/io/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="479">
|
||||
@@ -595,31 +543,6 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/engine/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1309">
|
||||
<caret line="81" column="45" selection-start-line="81" selection-start-column="45" selection-end-line="81" selection-end-column="45" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/str/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1326">
|
||||
<caret line="78" column="9" selection-start-line="78" selection-start-column="9" selection-end-line="78" selection-end-column="9" />
|
||||
<folding>
|
||||
<element signature="e#126234#126235#0" expanded="true" />
|
||||
<element signature="e#126272#126273#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/slice/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="39780">
|
||||
<caret line="2405" column="14" selection-start-line="2405" selection-start-column="14" selection-end-line="2405" selection-end-column="14" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/liballoc/collections/linked_list.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="3519">
|
||||
@@ -627,13 +550,6 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/scene/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="493">
|
||||
<caret line="29" selection-start-line="29" selection-end-line="29" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/macros.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="731">
|
||||
@@ -655,17 +571,77 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/resource/texture.rs">
|
||||
<entry file="file://$PROJECT_DIR$/src/math/plane.rs">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libstd/macros.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="408">
|
||||
<caret line="24" column="36" selection-start-line="24" selection-start-column="36" selection-end-line="24" selection-end-column="36" />
|
||||
<state relative-caret-position="14348">
|
||||
<caret line="844" column="17" selection-start-line="844" selection-start-column="17" selection-end-line="844" selection-end-column="17" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/renderer/renderer.rs">
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/fmt/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="340">
|
||||
<caret line="20" column="5" selection-start-line="20" selection-start-column="5" selection-end-line="20" selection-end-column="5" />
|
||||
<state relative-caret-position="1139">
|
||||
<caret line="67" column="29" selection-start-line="67" selection-start-column="29" selection-end-line="67" selection-end-column="29" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/result.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="4165">
|
||||
<caret line="245" column="9" selection-start-line="245" selection-start-column="9" selection-end-line="245" selection-end-column="9" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/liballoc/macros.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1087">
|
||||
<caret line="100" column="13" selection-start-line="100" selection-start-column="13" selection-end-line="100" selection-end-column="13" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/str/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="581">
|
||||
<caret line="74" column="9" selection-start-line="74" selection-start-column="9" selection-end-line="74" selection-end-column="9" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/math/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="309">
|
||||
<caret line="38" column="33" selection-start-line="38" selection-start-column="33" selection-end-line="38" selection-end-column="33" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/utils/persistent_pool.rs" />
|
||||
<entry file="file://$PROJECT_DIR$/src/math/quat.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="850">
|
||||
<caret line="50" column="21" selection-start-line="50" selection-start-column="11" selection-end-line="50" selection-end-column="21" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/ops/index.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1020">
|
||||
<caret line="60" column="10" selection-start-line="60" selection-start-column="10" selection-end-line="60" selection-end-column="10" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/clone.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="2057">
|
||||
<caret line="121" column="7" selection-start-line="121" selection-start-column="7" selection-end-line="121" selection-end-column="7" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/slice/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="641">
|
||||
<caret line="324" column="23" lean-forward="true" selection-start-line="324" selection-start-column="23" selection-end-line="324" selection-end-column="23" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
@@ -676,34 +652,17 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/math/plane.rs">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/math/quat.rs">
|
||||
<entry file="file://$PROJECT_DIR$/src/math/triangulator.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="340">
|
||||
<caret line="20" column="11" selection-start-line="20" selection-start-column="11" selection-end-line="20" selection-end-column="11" />
|
||||
<state relative-caret-position="666">
|
||||
<caret line="58" selection-start-line="58" selection-end-line="72" selection-end-column="1" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/utils/pool.rs">
|
||||
<entry file="file://$PROJECT_DIR$/src/math/vec4.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1649">
|
||||
<caret line="97" column="17" selection-start-line="97" selection-start-column="17" selection-end-line="97" selection-end-column="17" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/scene/node.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="1683">
|
||||
<caret line="99" column="9" selection-start-line="99" selection-start-column="9" selection-end-line="99" selection-end-column="9" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/resource/fbx/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="187">
|
||||
<caret line="11" column="4" selection-start-line="11" selection-start-column="4" selection-end-line="11" selection-end-column="4" />
|
||||
<state>
|
||||
<caret column="38" selection-start-column="38" selection-end-column="38" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
@@ -714,66 +673,101 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/math/mod.rs">
|
||||
<entry file="file://$PROJECT_DIR$/src/scene/node.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="330">
|
||||
<caret line="63" selection-start-line="63" selection-end-line="63" />
|
||||
<state relative-caret-position="813">
|
||||
<caret line="128" column="11" selection-start-line="128" selection-start-column="11" selection-end-line="128" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/result.rs">
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/cmp.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="322">
|
||||
<caret line="245" column="9" selection-start-line="245" selection-start-column="9" selection-end-line="245" selection-end-column="9" />
|
||||
<state relative-caret-position="335">
|
||||
<caret line="244" column="10" selection-start-line="244" selection-start-column="10" selection-end-line="244" selection-end-column="10" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/fmt/mod.rs">
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libcore/hash/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="315">
|
||||
<caret line="67" column="29" lean-forward="true" selection-start-line="67" selection-start-column="29" selection-end-line="67" selection-end-column="29" />
|
||||
<state relative-caret-position="335">
|
||||
<caret line="174" column="7" selection-start-line="174" selection-start-column="7" selection-end-line="174" selection-end-column="7" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/utils/pool.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="714">
|
||||
<caret line="52" column="31" selection-start-line="52" selection-start-column="31" selection-end-line="52" selection-end-column="31" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/scene/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="884">
|
||||
<caret line="52" column="11" selection-start-line="52" selection-start-column="11" selection-end-line="52" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/resource/texture.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="527">
|
||||
<caret line="31" selection-start-line="31" selection-end-line="31" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/renderer/surface.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="972">
|
||||
<caret line="338" column="13" selection-start-line="338" selection-start-column="13" selection-end-line="338" selection-end-column="13" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/math/mat4.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="530">
|
||||
<caret line="201" column="11" selection-start-line="201" selection-start-column="11" selection-end-line="201" selection-end-column="11" />
|
||||
<state relative-caret-position="357">
|
||||
<caret line="136" selection-start-line="136" selection-end-line="136" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/math/vec2.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="34">
|
||||
<caret line="2" column="27" selection-start-line="2" selection-start-column="27" selection-end-line="2" selection-end-column="27" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libstd/macros.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="387">
|
||||
<caret line="844" column="17" selection-start-line="844" selection-start-column="17" selection-end-line="844" selection-end-column="17" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="17">
|
||||
<caret line="1" column="20" selection-start-line="1" selection-start-column="20" selection-end-line="1" selection-end-column="20" />
|
||||
<caret line="2" column="38" selection-start-line="2" selection-start-column="38" selection-end-line="2" selection-end-column="38" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/math/vec3.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="294">
|
||||
<caret line="56" column="11" selection-start-line="56" selection-start-column="11" selection-end-line="56" selection-end-column="11" />
|
||||
<state relative-caret-position="629">
|
||||
<caret line="42" column="30" lean-forward="true" selection-start-line="42" selection-start-column="30" selection-end-line="42" selection-end-column="30" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/math/triangulator.rs">
|
||||
<entry file="file://$PROJECT_DIR$/src/resource/fbx/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="340">
|
||||
<caret line="115" column="51" selection-start-line="115" selection-start-column="51" selection-end-line="115" selection-end-column="51" />
|
||||
<state relative-caret-position="515">
|
||||
<caret line="320" column="31" selection-start-line="320" selection-start-column="31" selection-end-line="320" selection-end-column="31" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="565">
|
||||
<caret line="264" column="29" lean-forward="true" selection-start-line="264" selection-start-column="29" selection-end-line="264" selection-end-column="29" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/engine/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="864">
|
||||
<caret line="109" column="11" selection-start-line="109" selection-start-column="11" selection-end-line="109" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/renderer/renderer.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="422">
|
||||
<caret line="125" column="41" selection-start-line="125" selection-start-column="41" selection-end-line="125" selection-end-column="41" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
||||
+7957
File diff suppressed because it is too large
Load Diff
+20841
File diff suppressed because it is too large
Load Diff
+59
-35
@@ -7,47 +7,17 @@ use std::cell::*;
|
||||
use std::path::*;
|
||||
use crate::resource::texture::*;
|
||||
|
||||
pub struct Engine {
|
||||
renderer: Renderer,
|
||||
scenes: Pool<Scene>,
|
||||
events: Vec<glutin::Event>,
|
||||
running: bool,
|
||||
pub struct ResourceManager {
|
||||
resources: Vec<Rc<RefCell<Resource>>>
|
||||
}
|
||||
|
||||
impl Engine {
|
||||
pub fn new() -> Engine {
|
||||
Engine {
|
||||
scenes: Pool::new(),
|
||||
renderer: Renderer::new(),
|
||||
events: Vec::new(),
|
||||
running: true,
|
||||
impl ResourceManager {
|
||||
pub fn new() -> ResourceManager {
|
||||
ResourceManager {
|
||||
resources: Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_scene(&mut self, scene: Scene) -> Handle<Scene> {
|
||||
self.scenes.spawn(scene)
|
||||
}
|
||||
|
||||
pub fn borrow_scene(&self, handle: &Handle<Scene>) -> Option<&Scene> {
|
||||
if let Some(scene) = self.scenes.borrow(handle) {
|
||||
return Some(scene);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn borrow_scene_mut(&mut self, handle: &Handle<Scene>) -> Option<&mut Scene> {
|
||||
if let Some(scene) = self.scenes.borrow_mut(handle) {
|
||||
return Some(scene);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn is_running(&self) -> bool {
|
||||
self.running
|
||||
}
|
||||
|
||||
pub fn request_texture(&mut self, path: &Path) -> Option<Rc<RefCell<Resource>>> {
|
||||
for existing in self.resources.iter() {
|
||||
let resource = existing.borrow_mut();
|
||||
@@ -73,6 +43,58 @@ impl Engine {
|
||||
// Fail
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Engine {
|
||||
renderer: Renderer,
|
||||
scenes: Pool<Scene>,
|
||||
events: Vec<glutin::Event>,
|
||||
running: bool,
|
||||
resource_manager: ResourceManager,
|
||||
}
|
||||
|
||||
impl Engine {
|
||||
#[inline]
|
||||
pub fn new() -> Engine {
|
||||
Engine {
|
||||
scenes: Pool::new(),
|
||||
renderer: Renderer::new(),
|
||||
events: Vec::new(),
|
||||
running: true,
|
||||
resource_manager: ResourceManager::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn add_scene(&mut self, scene: Scene) -> Handle<Scene> {
|
||||
self.scenes.spawn(scene)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn borrow_scene(&self, handle: &Handle<Scene>) -> Option<&Scene> {
|
||||
if let Some(scene) = self.scenes.borrow(handle) {
|
||||
return Some(scene);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn borrow_scene_mut(&mut self, handle: &Handle<Scene>) -> Option<&mut Scene> {
|
||||
if let Some(scene) = self.scenes.borrow_mut(handle) {
|
||||
return Some(scene);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_running(&self) -> bool {
|
||||
self.running
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_resource_manager(&mut self) -> &mut ResourceManager {
|
||||
&mut self.resource_manager
|
||||
}
|
||||
|
||||
pub fn update(&mut self) {
|
||||
let client_size = self.renderer.context.get_inner_size().unwrap();
|
||||
@@ -95,7 +117,7 @@ impl Engine {
|
||||
}
|
||||
|
||||
pub fn render(&mut self) {
|
||||
self.renderer.upload_resources(&mut self.resources);
|
||||
self.renderer.upload_resources(&mut self.resource_manager.resources);
|
||||
|
||||
let mut alive_scenes: Vec<&Scene> = Vec::new();
|
||||
for i in 0..self.scenes.capacity() {
|
||||
@@ -106,10 +128,12 @@ impl Engine {
|
||||
self.renderer.render(alive_scenes.as_slice());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn stop(&mut self) {
|
||||
self.running = false;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn pop_event(&mut self) -> Option<glutin::Event> {
|
||||
self.events.pop()
|
||||
}
|
||||
|
||||
+34
-29
@@ -1,23 +1,29 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
extern crate image;
|
||||
extern crate glutin;
|
||||
|
||||
|
||||
use std::path::*;
|
||||
|
||||
mod utils;
|
||||
|
||||
use utils::pool::*;
|
||||
|
||||
mod math;
|
||||
|
||||
use math::vec2::*;
|
||||
use math::vec3::*;
|
||||
use math::quat::*;
|
||||
|
||||
mod scene;
|
||||
|
||||
use scene::node::*;
|
||||
use scene::*;
|
||||
|
||||
mod renderer;
|
||||
|
||||
mod engine;
|
||||
|
||||
use engine::*;
|
||||
|
||||
mod resource;
|
||||
@@ -44,7 +50,7 @@ impl Player {
|
||||
camera.set_local_position(Vec3 { x: 0.0, y: 2.0, z: 0.0 });
|
||||
|
||||
let mut pivot = Node::new(NodeKind::Base);
|
||||
pivot.set_local_position(Vec3 { x: 0.0, y: 0.0, z: 20.0 });
|
||||
pivot.set_local_position(Vec3 { x: -1.0, y: 0.0, z: 1.0 });
|
||||
|
||||
let camera_handle = scene.add_node(camera);
|
||||
let pivot_handle = scene.add_node(pivot);
|
||||
@@ -61,7 +67,7 @@ impl Player {
|
||||
},
|
||||
yaw: 0.0,
|
||||
pitch: 0.0,
|
||||
last_mouse_pos: Vec2::new()
|
||||
last_mouse_pos: Vec2::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,20 +78,20 @@ impl Player {
|
||||
|
||||
let mut velocity = Vec3::new();
|
||||
if self.controller.move_forward {
|
||||
velocity -= look;
|
||||
}
|
||||
if self.controller.move_backward {
|
||||
velocity += look;
|
||||
}
|
||||
if self.controller.move_backward {
|
||||
velocity -= look;
|
||||
}
|
||||
if self.controller.move_left {
|
||||
velocity -= side;
|
||||
velocity += side;
|
||||
}
|
||||
if self.controller.move_right {
|
||||
velocity += side;
|
||||
velocity -= side;
|
||||
}
|
||||
|
||||
if let Ok(normalized_velocity) = velocity.normalized() {
|
||||
pivot_node.offset(normalized_velocity);
|
||||
pivot_node.offset(normalized_velocity.scale(0.2));
|
||||
}
|
||||
|
||||
pivot_node.set_local_rotation(Quat::from_axis_angle(Vec3::up(), self.yaw.to_radians()));
|
||||
@@ -100,7 +106,6 @@ impl Player {
|
||||
use glutin::*;
|
||||
|
||||
match event {
|
||||
|
||||
WindowEvent::CursorMoved { position, .. } => {
|
||||
let mouse_velocity = Vec2 {
|
||||
x: position.x as f32 - self.last_mouse_pos.x,
|
||||
@@ -109,10 +114,10 @@ impl Player {
|
||||
|
||||
let sens: f32 = 0.3;
|
||||
|
||||
self.pitch -= mouse_velocity.y * sens;
|
||||
self.pitch += mouse_velocity.y * sens;
|
||||
self.yaw -= mouse_velocity.x * sens;
|
||||
|
||||
if self.pitch > 90.0 {
|
||||
if self.pitch > 90.0 {
|
||||
self.pitch = 90.0;
|
||||
} else if self.pitch < -90.0 {
|
||||
self.pitch = -90.0;
|
||||
@@ -120,9 +125,9 @@ impl Player {
|
||||
|
||||
self.last_mouse_pos = Vec2 {
|
||||
x: position.x as f32,
|
||||
y: position.y as f32
|
||||
y: position.y as f32,
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
WindowEvent::KeyboardInput { input, .. } => {
|
||||
match input.state {
|
||||
@@ -136,7 +141,7 @@ impl Player {
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
ElementState::Released => {
|
||||
if let Some(key) = input.virtual_keycode {
|
||||
match key {
|
||||
@@ -173,21 +178,21 @@ impl Level {
|
||||
let mut scene = Scene::new();
|
||||
|
||||
// Load some test models
|
||||
resource::fbx::load_to_scene(&mut scene, Path::new("data/models/cube.fbx"));
|
||||
|
||||
// Create floor
|
||||
{
|
||||
let mut floor_mesh = Mesh::default();
|
||||
floor_mesh.make_cube();
|
||||
if let Some(floor_tex) = engine.request_texture(Path::new("data/textures/floor.png")) {
|
||||
floor_mesh.apply_texture(floor_tex);
|
||||
}
|
||||
let mut floor_node = Node::new(NodeKind::Mesh(floor_mesh));
|
||||
floor_node.set_local_scale(Vec3 { x: 100.0, y: 0.1, z: 100.0 });
|
||||
scene.add_node(floor_node);
|
||||
if let Err(err_msg) = resource::fbx::load_to_scene(
|
||||
&mut scene, engine.get_resource_manager(), Path::new("data/models/map.fbx")) {
|
||||
println!("{}", err_msg);
|
||||
} else {
|
||||
println!("Map loaded!");
|
||||
}
|
||||
|
||||
|
||||
match resource::fbx::load_to_scene(&mut scene, engine.get_resource_manager(), Path::new("data/models/ripper.fbx")) {
|
||||
Ok(node_handle) => {
|
||||
if let Some(node) = scene.borrow_node_mut(&node_handle) {
|
||||
node.set_local_position(Vec3::make(-1.0, 0.0, -1.0));
|
||||
}
|
||||
}
|
||||
Err(err_msg) => println!("{}", err_msg)
|
||||
}
|
||||
|
||||
// Create cubes
|
||||
for i in 0..3 {
|
||||
@@ -195,7 +200,7 @@ impl Level {
|
||||
for k in 0..3 {
|
||||
let mut cube_mesh = Mesh::default();
|
||||
cube_mesh.make_cube();
|
||||
if let Some(ref cube_t) = engine.request_texture(Path::new("data/textures/box.png")) {
|
||||
if let Some(ref cube_t) = engine.get_resource_manager().request_texture(Path::new("data/textures/box.png")) {
|
||||
cube_mesh.apply_texture(cube_t.clone());
|
||||
}
|
||||
let mut cube_node = Node::new(NodeKind::Mesh(cube_mesh));
|
||||
|
||||
+10
-2
@@ -136,7 +136,7 @@ impl Mat4 {
|
||||
}
|
||||
|
||||
pub fn look_at(eye: Vec3, at: Vec3, up: Vec3) -> Result<Mat4, &'static str> {
|
||||
let zaxis = (at - eye).normalized()?;
|
||||
let zaxis = (eye - at).normalized()?;
|
||||
let xaxis = up.cross(&zaxis).normalized()?;
|
||||
let yaxis = zaxis.cross(&xaxis).normalized()?;
|
||||
|
||||
@@ -159,7 +159,7 @@ impl Mat4 {
|
||||
|
||||
-xaxis.dot(&eye),
|
||||
-yaxis.dot(&eye),
|
||||
-zaxis.dot(&eye), // ????????????
|
||||
-zaxis.dot(&eye),
|
||||
1.0,
|
||||
]
|
||||
})
|
||||
@@ -206,6 +206,14 @@ impl Mat4 {
|
||||
z: v.x * self.f[2] + v.y * self.f[6] + v.z * self.f[10] + self.f[14]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_vector_normal(&self, v: Vec3) -> Vec3 {
|
||||
Vec3 {
|
||||
x: v.x * self.f[0] + v.y * self.f[4] + v.z * self.f[8],
|
||||
y: v.x * self.f[1] + v.y * self.f[5] + v.z * self.f[9],
|
||||
z: v.x * self.f[2] + v.y * self.f[6] + v.z * self.f[10]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Mul<Self> for Mat4 {
|
||||
|
||||
+10
-11
@@ -17,28 +17,27 @@ pub struct Rect<T> {
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum PlaneClass {
|
||||
oXY,
|
||||
oYZ,
|
||||
oXZ,
|
||||
XY,
|
||||
YZ,
|
||||
XZ,
|
||||
}
|
||||
|
||||
pub fn classify_plane(normal: Vec3) -> PlaneClass {
|
||||
let mut longest = 0.0f32;
|
||||
let mut class = PlaneClass::oXY;
|
||||
let mut class = PlaneClass::XY;
|
||||
|
||||
if normal.x.abs() > longest {
|
||||
longest = normal.x.abs();
|
||||
class = PlaneClass::oYZ;
|
||||
class = PlaneClass::YZ;
|
||||
}
|
||||
|
||||
if normal.y.abs() > longest {
|
||||
longest = normal.y.abs();
|
||||
class = PlaneClass::oXZ;
|
||||
class = PlaneClass::XZ;
|
||||
}
|
||||
|
||||
if normal.z.abs() > longest {
|
||||
longest = normal.z.abs();
|
||||
class = PlaneClass::oXY;
|
||||
class = PlaneClass::XY;
|
||||
}
|
||||
|
||||
class
|
||||
@@ -67,9 +66,9 @@ pub fn get_signed_triangle_area(v1: Vec2, v2: Vec2, v3: Vec2) -> f32 {
|
||||
|
||||
pub fn vec3_to_vec2_by_plane(plane_class: PlaneClass, normal: Vec3, point: Vec3) -> Vec2 {
|
||||
match plane_class {
|
||||
PlaneClass::oXY => if normal.z < 0.0 { Vec2::make(point.y, point.x) } else { Vec2::make(point.x, point.y) }
|
||||
PlaneClass::oXZ => if normal.y < 0.0 { Vec2::make(point.x, point.z) } else { Vec2::make(point.z, point.x) }
|
||||
PlaneClass::oYZ => if normal.x < 0.0 { Vec2::make(point.z, point.y) } else { Vec2::make(point.y, point.z) }
|
||||
PlaneClass::XY => if normal.z < 0.0 { Vec2::make(point.y, point.x) } else { Vec2::make(point.x, point.y) }
|
||||
PlaneClass::XZ => if normal.y < 0.0 { Vec2::make(point.x, point.z) } else { Vec2::make(point.z, point.x) }
|
||||
PlaneClass::YZ => if normal.x < 0.0 { Vec2::make(point.z, point.y) } else { Vec2::make(point.y, point.z) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+37
-1
@@ -1,4 +1,5 @@
|
||||
use crate::math::vec3::*;
|
||||
use std::ops;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Quat {
|
||||
@@ -8,6 +9,15 @@ pub struct Quat {
|
||||
pub w: f32,
|
||||
}
|
||||
|
||||
pub enum RotationOrder {
|
||||
XYZ,
|
||||
XZY,
|
||||
YZX,
|
||||
YXZ,
|
||||
ZXY,
|
||||
ZYX,
|
||||
}
|
||||
|
||||
impl Quat {
|
||||
pub fn new() -> Self {
|
||||
Quat {
|
||||
@@ -37,4 +47,30 @@ impl Quat {
|
||||
w: half_angle.cos(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_euler(euler_radians: Vec3, order: RotationOrder) -> Self {
|
||||
let qx: Quat = Quat::from_axis_angle(Vec3::make(1.0, 0.0, 0.0), euler_radians.x);
|
||||
let qy: Quat = Quat::from_axis_angle(Vec3::make(0.0, 1.0, 0.0), euler_radians.y);
|
||||
let qz: Quat = Quat::from_axis_angle(Vec3::make(0.0, 0.0, 1.0), euler_radians.z);
|
||||
match order {
|
||||
RotationOrder::XYZ => qz * qy * qx,
|
||||
RotationOrder::XZY => qy * qz * qx,
|
||||
RotationOrder::YZX => qx * qz * qy,
|
||||
RotationOrder::YXZ => qz * qx * qy,
|
||||
RotationOrder::ZXY => qy * qx * qz,
|
||||
RotationOrder::ZYX => qx * qy * qz,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Mul<Self> for Quat {
|
||||
type Output = Self;
|
||||
fn mul(self, b: Self) -> Self {
|
||||
Self {
|
||||
x: self.w * b.x + self.x * b.w + self.y * b.z - self.z * b.y,
|
||||
y: self.w * b.y + self.y * b.w + self.z * b.x - self.x * b.z,
|
||||
z: self.w * b.z + self.z * b.w + self.x * b.y - self.y * b.x,
|
||||
w: self.w * b.w - self.x * b.x - self.y * b.y - self.z * b.z,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
use super::vec2::*;
|
||||
use super::vec3::*;
|
||||
use super::mat4::*;
|
||||
use super::quat::*;
|
||||
use crate::math;
|
||||
use std::fmt;
|
||||
use crate::math::quat::Quat;
|
||||
|
||||
///
|
||||
/// Polygon vertex
|
||||
@@ -62,7 +62,7 @@ impl fmt::Debug for Polygon {
|
||||
let mut i = self.head;
|
||||
loop {
|
||||
let vertex = &self.vertices[i];
|
||||
writeln!(f, "Vertex {:?}; {} {} {}", vertex.position, vertex.prev, vertex.index, vertex.next);
|
||||
writeln!(f, "Vertex {:?}; {} {} {}", vertex.position, vertex.prev, vertex.index, vertex.next)?;
|
||||
i = self.vertices[i].next;
|
||||
if i == self.head {
|
||||
break;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
use std::ops;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct Vec2 {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
|
||||
+8
-2
@@ -1,7 +1,6 @@
|
||||
use std::ops;
|
||||
use super::mat4::*;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct Vec3 {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
@@ -37,6 +36,13 @@ impl Vec3 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scale(&self, scalar: f32) -> Self {
|
||||
Vec3 {
|
||||
x: self.x * scalar,
|
||||
y: self.y * scalar,
|
||||
z: self.z * scalar
|
||||
}
|
||||
}
|
||||
|
||||
pub fn right() -> Self {
|
||||
Vec3 {
|
||||
|
||||
+5
-5
@@ -1,9 +1,9 @@
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub struct Vec4 {
|
||||
x: f32,
|
||||
y: f32,
|
||||
z: f32,
|
||||
w: f32,
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
pub z: f32,
|
||||
pub w: f32,
|
||||
}
|
||||
|
||||
impl Vec4 {
|
||||
|
||||
+14
-16
@@ -9,7 +9,7 @@ use crate::scene::node::*;
|
||||
use crate::renderer::surface::*;
|
||||
use crate::resource::*;
|
||||
use std::rc::*;
|
||||
use std::ffi::{c_void};
|
||||
use std::ffi::c_void;
|
||||
use std::cell::*;
|
||||
|
||||
pub fn check_gl_error() {
|
||||
@@ -172,7 +172,7 @@ impl Renderer {
|
||||
).unwrap();
|
||||
|
||||
Self {
|
||||
context: context,
|
||||
context,
|
||||
events_loop: el,
|
||||
flat_shader: GpuProgram::from_source(&vertex_source, &fragment_source).unwrap(),
|
||||
traversal_stack: Vec::new(),
|
||||
@@ -239,19 +239,17 @@ impl Renderer {
|
||||
self.cameras.clear();
|
||||
self.traversal_stack.clear();
|
||||
self.traversal_stack.push(scene.root.clone());
|
||||
while !self.traversal_stack.is_empty() {
|
||||
if let Some(node_handle) = self.traversal_stack.pop() {
|
||||
if let Some(node) = scene.borrow_node(&node_handle) {
|
||||
match node.borrow_kind() {
|
||||
NodeKind::Mesh(_) => self.meshes.push(node_handle),
|
||||
NodeKind::Light(_) => self.lights.push(node_handle),
|
||||
NodeKind::Camera(_) => self.cameras.push(node_handle),
|
||||
_ => ()
|
||||
}
|
||||
// Queue children for render
|
||||
for child_handle in node.children.iter() {
|
||||
self.traversal_stack.push(child_handle.clone());
|
||||
}
|
||||
while let Some(node_handle) = self.traversal_stack.pop() {
|
||||
if let Some(node) = scene.borrow_node(&node_handle) {
|
||||
match node.borrow_kind() {
|
||||
NodeKind::Mesh(_) => self.meshes.push(node_handle),
|
||||
NodeKind::Light(_) => self.lights.push(node_handle),
|
||||
NodeKind::Camera(_) => self.cameras.push(node_handle),
|
||||
_ => ()
|
||||
}
|
||||
// Queue children for render
|
||||
for child_handle in node.children.iter() {
|
||||
self.traversal_stack.push(child_handle.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -289,7 +287,7 @@ impl Renderer {
|
||||
}
|
||||
|
||||
if let NodeKind::Mesh(mesh) = node.borrow_kind() {
|
||||
for surface in mesh.surfaces.iter() {
|
||||
for surface in mesh.get_surfaces().iter() {
|
||||
surface.draw();
|
||||
}
|
||||
}
|
||||
|
||||
+203
-183
@@ -1,57 +1,71 @@
|
||||
use crate::math::vec3::*;
|
||||
use crate::math::vec2::*;
|
||||
use crate::math::vec4::*;
|
||||
use crate::math::{vec2::*, vec3::*, vec4::*};
|
||||
use crate::renderer::renderer::*;
|
||||
use crate::renderer::gl;
|
||||
use crate::renderer::gl::types::*;
|
||||
use std::ffi::c_void;
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use std::{ffi::c_void, rc::Rc, cell::RefCell, mem::size_of, fmt};
|
||||
use crate::resource::*;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Vertex {
|
||||
pub position: Vec3,
|
||||
pub tex_coord: Vec2,
|
||||
pub normal: Vec3,
|
||||
pub tangent: Vec4,
|
||||
}
|
||||
|
||||
pub struct SurfaceSharedData {
|
||||
need_upload: bool,
|
||||
vbo: GLuint,
|
||||
vao: GLuint,
|
||||
ebo: GLuint,
|
||||
positions: Vec<Vec3>,
|
||||
normals: Vec<Vec3>,
|
||||
tex_coords: Vec<Vec2>,
|
||||
tangents: Vec<Vec4>,
|
||||
vertices: Vec<Vertex>,
|
||||
indices: Vec<i32>,
|
||||
}
|
||||
|
||||
impl SurfaceSharedData {
|
||||
fn new() -> Self {
|
||||
pub fn new() -> Self {
|
||||
let mut vbo: GLuint = 0;
|
||||
let mut ebo: GLuint = 0;
|
||||
let mut vao: GLuint = 0;
|
||||
|
||||
unsafe {
|
||||
gl::GenBuffers(1, &mut vbo);
|
||||
gl::GenBuffers(1, &mut ebo);
|
||||
gl::GenVertexArrays(1, &mut vao);
|
||||
}
|
||||
|
||||
Self {
|
||||
need_upload: true,
|
||||
vbo,
|
||||
vao,
|
||||
ebo,
|
||||
positions: Vec::new(),
|
||||
normals: Vec::new(),
|
||||
tex_coords: Vec::new(),
|
||||
tangents: Vec::new(),
|
||||
vbo, vao, ebo,
|
||||
vertices: Vec::new(),
|
||||
indices: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_vertex(&mut self, vertex: Vertex) {
|
||||
self.vertices.push(vertex);
|
||||
}
|
||||
|
||||
/// Inserts vertex or its index. Performs optimizing insertion with checking if such
|
||||
/// vertex already exists.
|
||||
pub fn insert_vertex(&mut self, vertex: Vertex) {
|
||||
// Reverse search is much faster because it is most likely that we'll find identic
|
||||
// vertex at the end of the array.
|
||||
self.indices.push(match self.vertices.iter().rposition(|v| {
|
||||
v.position == vertex.position && v.normal == vertex.normal && v.tex_coord == vertex.tex_coord
|
||||
}) {
|
||||
Some(exisiting_index) => exisiting_index as i32, // Already have such vertex
|
||||
None => { // No such vertex, add it
|
||||
let index = self.vertices.len() as i32;
|
||||
self.vertices.push(vertex);
|
||||
index
|
||||
}
|
||||
});
|
||||
self.need_upload = true;
|
||||
}
|
||||
|
||||
pub fn upload(&mut self) {
|
||||
let positions_bytes = self.positions.len() * std::mem::size_of::<Vec3>();
|
||||
let tex_coords_bytes = self.tex_coords.len() * std::mem::size_of::<Vec2>();
|
||||
let normals_bytes = self.normals.len() * std::mem::size_of::<Vec3>();
|
||||
let tangents_bytes = self.tangents.len() * std::mem::size_of::<Vec4>();
|
||||
|
||||
|
||||
let total_size_bytes = positions_bytes + normals_bytes + tex_coords_bytes + tangents_bytes;
|
||||
let total_size_bytes = self.vertices.len() * std::mem::size_of::<Vertex>();
|
||||
|
||||
unsafe {
|
||||
gl::BindVertexArray(self.vao);
|
||||
@@ -67,68 +81,32 @@ impl SurfaceSharedData {
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, self.vbo);
|
||||
gl::BufferData(gl::ARRAY_BUFFER,
|
||||
total_size_bytes as GLsizeiptr,
|
||||
std::ptr::null(),
|
||||
self.vertices.as_ptr() as *const GLvoid,
|
||||
gl::STATIC_DRAW);
|
||||
|
||||
let pos_offset = 0;
|
||||
let mut size = positions_bytes;
|
||||
gl::BufferSubData(gl::ARRAY_BUFFER,
|
||||
pos_offset as GLsizeiptr,
|
||||
size as GLsizeiptr,
|
||||
self.positions.as_ptr() as *const c_void);
|
||||
let mut offset = 0;
|
||||
|
||||
let tex_coord_offset = pos_offset + size;
|
||||
size = tex_coords_bytes;
|
||||
gl::BufferSubData(gl::ARRAY_BUFFER,
|
||||
tex_coord_offset as GLsizeiptr,
|
||||
size as GLsizeiptr,
|
||||
self.tex_coords.as_ptr() as *const c_void);
|
||||
|
||||
let normals_offset = tex_coord_offset + size;
|
||||
size = normals_bytes;
|
||||
gl::BufferSubData(gl::ARRAY_BUFFER,
|
||||
normals_offset as GLsizeiptr,
|
||||
size as GLsizeiptr,
|
||||
self.normals.as_ptr() as *const c_void);
|
||||
|
||||
let tangents_offset = normals_offset + size;
|
||||
size = tangents_bytes;
|
||||
gl::BufferSubData(gl::ARRAY_BUFFER,
|
||||
tangents_offset as GLsizeiptr,
|
||||
size as GLsizeiptr,
|
||||
self.tangents.as_ptr() as *const c_void);
|
||||
|
||||
// Setup attribute locations
|
||||
gl::VertexAttribPointer(0,
|
||||
3,
|
||||
gl::FLOAT,
|
||||
gl::FALSE,
|
||||
std::mem::size_of::<Vec3>() as GLint,
|
||||
pos_offset as *const c_void);
|
||||
// Positions
|
||||
gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE,
|
||||
size_of::<Vertex>() as GLint, offset as *const c_void);
|
||||
gl::EnableVertexAttribArray(0);
|
||||
offset += size_of::<Vec3>();
|
||||
|
||||
gl::VertexAttribPointer(1,
|
||||
2,
|
||||
gl::FLOAT,
|
||||
gl::FALSE,
|
||||
std::mem::size_of::<Vec2>() as GLint,
|
||||
tex_coord_offset as *const c_void);
|
||||
// Texture coordinates
|
||||
gl::VertexAttribPointer(1, 2, gl::FLOAT, gl::FALSE,
|
||||
size_of::<Vertex>() as GLint, offset as *const c_void);
|
||||
gl::EnableVertexAttribArray(1);
|
||||
offset += size_of::<Vec2>();
|
||||
|
||||
gl::VertexAttribPointer(2,
|
||||
3,
|
||||
gl::FLOAT,
|
||||
gl::FALSE,
|
||||
std::mem::size_of::<Vec3>() as GLint,
|
||||
normals_offset as *const c_void);
|
||||
// Normals
|
||||
gl::VertexAttribPointer(2, 3, gl::FLOAT, gl::FALSE,
|
||||
size_of::<Vertex>() as GLint, offset as *const c_void);
|
||||
gl::EnableVertexAttribArray(2);
|
||||
offset += size_of::<Vec3>();
|
||||
|
||||
gl::VertexAttribPointer(2,
|
||||
3,
|
||||
gl::FLOAT,
|
||||
gl::FALSE,
|
||||
std::mem::size_of::<Vec4>() as GLint,
|
||||
tangents_offset as *const c_void);
|
||||
// Tangents
|
||||
gl::VertexAttribPointer(3, 4, gl::FLOAT, gl::FALSE,
|
||||
size_of::<Vertex>() as GLint, offset as *const c_void);
|
||||
gl::EnableVertexAttribArray(3);
|
||||
|
||||
gl::BindVertexArray(0);
|
||||
@@ -144,118 +122,162 @@ impl SurfaceSharedData {
|
||||
pub fn make_cube() -> Self {
|
||||
let mut data = Self::new();
|
||||
|
||||
data.positions = vec![
|
||||
data.vertices = vec![
|
||||
// Front
|
||||
Vec3 { x: -0.5, y: -0.5, z: 0.5 },
|
||||
Vec3 { x: -0.5, y: 0.5, z: 0.5 },
|
||||
Vec3 { x: 0.5, y: 0.5, z: 0.5 },
|
||||
Vec3 { x: 0.5, y: -0.5, z: 0.5 },
|
||||
Vertex {
|
||||
position: Vec3 { x: -0.5, y: -0.5, z: 0.5 },
|
||||
normal: Vec3 { x: 0.0, y: 0.0, z: 1.0 },
|
||||
tex_coord: Vec2 { x: 0.0, y: 0.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: -0.5, y: 0.5, z: 0.5 },
|
||||
normal: Vec3 { x: 0.0, y: 0.0, z: 1.0 },
|
||||
tex_coord: Vec2 { x: 0.0, y: 1.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: 0.5, y: 0.5, z: 0.5 },
|
||||
normal: Vec3 { x: 0.0, y: 0.0, z: 1.0 },
|
||||
tex_coord: Vec2 { x: 1.0, y: 1.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: 0.5, y: -0.5, z: 0.5 },
|
||||
normal: Vec3 { x: 0.0, y: 0.0, z: 1.0 },
|
||||
tex_coord: Vec2 { x: 1.0, y: 0.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
|
||||
// Back
|
||||
Vec3 { x: -0.5, y: -0.5, z: -0.5 },
|
||||
Vec3 { x: -0.5, y: 0.5, z: -0.5 },
|
||||
Vec3 { x: 0.5, y: 0.5, z: -0.5 },
|
||||
Vec3 { x: 0.5, y: -0.5, z: -0.5 },
|
||||
Vertex {
|
||||
position: Vec3 { x: -0.5, y: -0.5, z: -0.5 },
|
||||
normal: Vec3 { x: 0.0, y: 0.0, z: -1.0 },
|
||||
tex_coord: Vec2 { x: 0.0, y: 0.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: -0.5, y: 0.5, z: -0.5 },
|
||||
normal: Vec3 { x: 0.0, y: 0.0, z: -1.0 },
|
||||
tex_coord: Vec2 { x: 0.0, y: 1.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: 0.5, y: 0.5, z: -0.5 },
|
||||
normal: Vec3 { x: 0.0, y: 0.0, z: -1.0 },
|
||||
tex_coord: Vec2 { x: 1.0, y: 1.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: 0.5, y: -0.5, z: -0.5 },
|
||||
normal: Vec3 { x: 0.0, y: 0.0, z: -1.0 },
|
||||
tex_coord: Vec2 { x: 1.0, y: 0.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
|
||||
// Left
|
||||
Vec3 { x: -0.5, y: -0.5, z: -0.5 },
|
||||
Vec3 { x: -0.5, y: 0.5, z: -0.5 },
|
||||
Vec3 { x: -0.5, y: 0.5, z: 0.5 },
|
||||
Vec3 { x: -0.5, y: -0.5, z: 0.5 },
|
||||
Vertex {
|
||||
position: Vec3 { x: -0.5, y: -0.5, z: -0.5 },
|
||||
normal: Vec3 { x: -1.0, y: 0.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 0.0, y: 0.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: -0.5, y: 0.5, z: -0.5 },
|
||||
normal: Vec3 { x: -1.0, y: 0.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 0.0, y: 1.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: -0.5, y: 0.5, z: 0.5 },
|
||||
normal: Vec3 { x: -1.0, y: 0.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 1.0, y: 1.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: -0.5, y: -0.5, z: 0.5 },
|
||||
normal: Vec3 { x: -1.0, y: 0.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 1.0, y: 0.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
|
||||
// Right
|
||||
Vec3 { x: 0.5, y: -0.5, z: -0.5 },
|
||||
Vec3 { x: 0.5, y: 0.5, z: -0.5 },
|
||||
Vec3 { x: 0.5, y: 0.5, z: 0.5 },
|
||||
Vec3 { x: 0.5, y: -0.5, z: 0.5 },
|
||||
Vertex {
|
||||
position: Vec3 { x: 0.5, y: -0.5, z: -0.5 },
|
||||
normal: Vec3 { x: 1.0, y: 0.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 0.0, y: 0.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: 0.5, y: 0.5, z: -0.5 },
|
||||
normal: Vec3 { x: 1.0, y: 0.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 0.0, y: 1.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: 0.5, y: 0.5, z: 0.5 },
|
||||
normal: Vec3 { x: 1.0, y: 0.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 1.0, y: 1.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: 0.5, y: -0.5, z: 0.5 },
|
||||
normal: Vec3 { x: 1.0, y: 0.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 1.0, y: 0.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
|
||||
// Top
|
||||
Vec3 { x: -0.5, y: 0.5, z: 0.5 },
|
||||
Vec3 { x: -0.5, y: 0.5, z: -0.5 },
|
||||
Vec3 { x: 0.5, y: 0.5, z: -0.5 },
|
||||
Vec3 { x: 0.5, y: 0.5, z: 0.5 },
|
||||
Vertex {
|
||||
position: Vec3 { x: -0.5, y: 0.5, z: 0.5 },
|
||||
normal: Vec3 { x: 0.0, y: 1.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 0.0, y: 0.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: -0.5, y: 0.5, z: -0.5 },
|
||||
normal: Vec3 { x: 0.0, y: 1.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 0.0, y: 1.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: 0.5, y: 0.5, z: -0.5 },
|
||||
normal: Vec3 { x: 0.0, y: 1.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 1.0, y: 1.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: 0.5, y: 0.5, z: 0.5 },
|
||||
normal: Vec3 { x: 0.0, y: 1.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 1.0, y: 0.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
|
||||
// Bottom
|
||||
Vec3 { x: -0.5, y: -0.5, z: 0.5 },
|
||||
Vec3 { x: -0.5, y: -0.5, z: -0.5 },
|
||||
Vec3 { x: 0.5, y: -0.5, z: -0.5 },
|
||||
Vec3 { x: 0.5, y: -0.5, z: 0.5 },
|
||||
];
|
||||
|
||||
data.normals = vec![
|
||||
// Front
|
||||
Vec3 { x: 0.0, y: 0.0, z: 1.0 },
|
||||
Vec3 { x: 0.0, y: 0.0, z: 1.0 },
|
||||
Vec3 { x: 0.0, y: 0.0, z: 1.0 },
|
||||
Vec3 { x: 0.0, y: 0.0, z: 1.0 },
|
||||
|
||||
// Back
|
||||
Vec3 { x: 0.0, y: 0.0, z: -1.0 },
|
||||
Vec3 { x: 0.0, y: 0.0, z: -1.0 },
|
||||
Vec3 { x: 0.0, y: 0.0, z: -1.0 },
|
||||
Vec3 { x: 0.0, y: 0.0, z: -1.0 },
|
||||
|
||||
// Left
|
||||
Vec3 { x: -1.0, y: 0.0, z: 0.0 },
|
||||
Vec3 { x: -1.0, y: 0.0, z: 0.0 },
|
||||
Vec3 { x: -1.0, y: 0.0, z: 0.0 },
|
||||
Vec3 { x: -1.0, y: 0.0, z: 0.0 },
|
||||
|
||||
// Right
|
||||
Vec3 { x: 1.0, y: 0.0, z: 0.0 },
|
||||
Vec3 { x: 1.0, y: 0.0, z: 0.0 },
|
||||
Vec3 { x: 1.0, y: 0.0, z: 0.0 },
|
||||
Vec3 { x: 1.0, y: 0.0, z: 0.0 },
|
||||
|
||||
// Top
|
||||
Vec3 { x: 0.0, y: 1.0, z: 0.0 },
|
||||
Vec3 { x: 0.0, y: 1.0, z: 0.0 },
|
||||
Vec3 { x: 0.0, y: 1.0, z: 0.0 },
|
||||
Vec3 { x: 0.0, y: 1.0, z: 0.0 },
|
||||
|
||||
// Bottom
|
||||
Vec3 { x: 0.0, y: -1.0, z: 0.0 },
|
||||
Vec3 { x: 0.0, y: -1.0, z: 0.0 },
|
||||
Vec3 { x: 0.0, y: -1.0, z: 0.0 },
|
||||
Vec3 { x: 0.0, y: -1.0, z: 0.0 },
|
||||
];
|
||||
|
||||
data.tex_coords = vec![
|
||||
// Front
|
||||
Vec2 { x: 0.0, y: 0.0 },
|
||||
Vec2 { x: 0.0, y: 1.0 },
|
||||
Vec2 { x: 1.0, y: 1.0 },
|
||||
Vec2 { x: 1.0, y: 0.0 },
|
||||
|
||||
// Back
|
||||
Vec2 { x: 0.0, y: 0.0 },
|
||||
Vec2 { x: 0.0, y: 1.0 },
|
||||
Vec2 { x: 1.0, y: 1.0 },
|
||||
Vec2 { x: 1.0, y: 0.0 },
|
||||
|
||||
// Left
|
||||
Vec2 { x: 0.0, y: 0.0 },
|
||||
Vec2 { x: 0.0, y: 1.0 },
|
||||
Vec2 { x: 1.0, y: 1.0 },
|
||||
Vec2 { x: 1.0, y: 0.0 },
|
||||
|
||||
// Right
|
||||
Vec2 { x: 0.0, y: 0.0 },
|
||||
Vec2 { x: 0.0, y: 1.0 },
|
||||
Vec2 { x: 1.0, y: 1.0 },
|
||||
Vec2 { x: 1.0, y: 0.0 },
|
||||
|
||||
// Top
|
||||
Vec2 { x: 0.0, y: 0.0 },
|
||||
Vec2 { x: 0.0, y: 1.0 },
|
||||
Vec2 { x: 1.0, y: 1.0 },
|
||||
Vec2 { x: 1.0, y: 0.0 },
|
||||
|
||||
// Bottom
|
||||
Vec2 { x: 0.0, y: 0.0 },
|
||||
Vec2 { x: 0.0, y: 1.0 },
|
||||
Vec2 { x: 1.0, y: 1.0 },
|
||||
Vec2 { x: 1.0, y: 0.0 },
|
||||
Vertex {
|
||||
position: Vec3 { x: -0.5, y: -0.5, z: 0.5 },
|
||||
normal: Vec3 { x: 0.0, y: -1.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 0.0, y: 0.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: -0.5, y: -0.5, z: -0.5 },
|
||||
normal: Vec3 { x: 0.0, y: -1.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 0.0, y: 1.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: 0.5, y: -0.5, z: -0.5 },
|
||||
normal: Vec3 { x: 0.0, y: -1.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 1.0, y: 1.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
Vertex {
|
||||
position: Vec3 { x: 0.5, y: -0.5, z: 0.5 },
|
||||
normal: Vec3 { x: 0.0, y: -1.0, z: 0.0 },
|
||||
tex_coord: Vec2 { x: 1.0, y: 0.0 },
|
||||
tangent: Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 },
|
||||
},
|
||||
];
|
||||
|
||||
data.indices = vec![
|
||||
@@ -287,15 +309,13 @@ impl Drop for SurfaceSharedData {
|
||||
}
|
||||
}
|
||||
|
||||
type SurfaceSharedDataRef = Rc<RefCell<SurfaceSharedData>>;
|
||||
|
||||
pub struct Surface {
|
||||
pub(crate) data: SurfaceSharedDataRef,
|
||||
pub(crate) data: Rc<RefCell<SurfaceSharedData>>,
|
||||
pub(crate) texture: Option<Rc<RefCell<Resource>>>,
|
||||
}
|
||||
|
||||
impl Surface {
|
||||
pub fn new(data: &SurfaceSharedDataRef) -> Self {
|
||||
pub fn new(data: &Rc<RefCell<SurfaceSharedData>>) -> Self {
|
||||
Self {
|
||||
data: data.clone(),
|
||||
texture: Option::None,
|
||||
|
||||
+527
-235
@@ -1,12 +1,12 @@
|
||||
use std::{rc::Rc, path::*, fs::File, io::Read, cell::RefCell, collections::HashMap};
|
||||
use crate::utils::pool::*;
|
||||
use std::path::*;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use crate::math::vec3::*;
|
||||
use crate::math::vec2::*;
|
||||
use crate::math::mat4::*;
|
||||
use std::collections::HashMap;
|
||||
use crate::scene::*;
|
||||
use crate::math::{vec4::*, vec3::*, vec2::*, mat4::*, quat::*};
|
||||
use crate::scene::{*, node::*};
|
||||
use crate::resource::fbx::FbxAnimationCurveNodeType::Rotation;
|
||||
use crate::renderer::surface::{SurfaceSharedData, Surface, Vertex};
|
||||
use crate::math::triangulator::triangulate;
|
||||
use crate::engine::ResourceManager;
|
||||
use core::borrow::Borrow;
|
||||
|
||||
pub enum FbxAttribute {
|
||||
Double(f64),
|
||||
@@ -18,47 +18,67 @@ pub enum FbxAttribute {
|
||||
}
|
||||
|
||||
impl FbxAttribute {
|
||||
pub fn as_int(&self) -> i32 {
|
||||
pub fn as_int(&self) -> Result<i32, String> {
|
||||
match self {
|
||||
FbxAttribute::Double(val) => *val as i32,
|
||||
FbxAttribute::Float(val) => *val as i32,
|
||||
FbxAttribute::Integer(val) => *val,
|
||||
FbxAttribute::Long(val) => *val as i32,
|
||||
FbxAttribute::Bool(val) => *val as i32,
|
||||
FbxAttribute::String(val) => val.parse::<i32>().unwrap(),
|
||||
FbxAttribute::Double(val) => Ok(*val as i32),
|
||||
FbxAttribute::Float(val) => Ok(*val as i32),
|
||||
FbxAttribute::Integer(val) => Ok(*val),
|
||||
FbxAttribute::Long(val) => Ok(*val as i32),
|
||||
FbxAttribute::Bool(val) => Ok(*val as i32),
|
||||
FbxAttribute::String(val) => {
|
||||
match val.parse::<i32>() {
|
||||
Ok(i) => Ok(i),
|
||||
Err(_) => Err(format!("Unable to convert string {} to i32", val))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_int64(&self) -> i64 {
|
||||
pub fn as_int64(&self) -> Result<i64, String> {
|
||||
match self {
|
||||
FbxAttribute::Double(val) => *val as i64,
|
||||
FbxAttribute::Float(val) => *val as i64,
|
||||
FbxAttribute::Integer(val) => *val as i64,
|
||||
FbxAttribute::Long(val) => *val as i64,
|
||||
FbxAttribute::Bool(val) => *val as i64,
|
||||
FbxAttribute::String(val) => val.parse::<i64>().unwrap(),
|
||||
FbxAttribute::Double(val) => Ok(*val as i64),
|
||||
FbxAttribute::Float(val) => Ok(*val as i64),
|
||||
FbxAttribute::Integer(val) => Ok(*val as i64),
|
||||
FbxAttribute::Long(val) => Ok(*val as i64),
|
||||
FbxAttribute::Bool(val) => Ok(*val as i64),
|
||||
FbxAttribute::String(val) => {
|
||||
match val.parse::<i64>() {
|
||||
Ok(i) => Ok(i),
|
||||
Err(_) => Err(format!("Unable to convert string {} to i64", val))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_double(&self) -> f64 {
|
||||
pub fn as_double(&self) -> Result<f64, String> {
|
||||
match self {
|
||||
FbxAttribute::Double(val) => *val,
|
||||
FbxAttribute::Float(val) => *val as f64,
|
||||
FbxAttribute::Integer(val) => *val as f64,
|
||||
FbxAttribute::Long(val) => *val as f64,
|
||||
FbxAttribute::Bool(val) => (*val as i64) as f64,
|
||||
FbxAttribute::String(val) => val.parse::<f64>().unwrap(),
|
||||
FbxAttribute::Double(val) => Ok(*val),
|
||||
FbxAttribute::Float(val) => Ok(*val as f64),
|
||||
FbxAttribute::Integer(val) => Ok(*val as f64),
|
||||
FbxAttribute::Long(val) => Ok(*val as f64),
|
||||
FbxAttribute::Bool(val) => Ok((*val as i64) as f64),
|
||||
FbxAttribute::String(val) => {
|
||||
match val.parse::<f64>() {
|
||||
Ok(i) => Ok(i),
|
||||
Err(_) => Err(format!("Unable to convert string {} to f64", val))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_float(&self) -> f32 {
|
||||
pub fn as_float(&self) -> Result<f32, String> {
|
||||
match self {
|
||||
FbxAttribute::Double(val) => *val as f32,
|
||||
FbxAttribute::Float(val) => *val,
|
||||
FbxAttribute::Integer(val) => *val as f32,
|
||||
FbxAttribute::Long(val) => *val as f32,
|
||||
FbxAttribute::Bool(val) => (*val as i32) as f32,
|
||||
FbxAttribute::String(val) => val.parse::<f32>().unwrap(),
|
||||
FbxAttribute::Double(val) => Ok(*val as f32),
|
||||
FbxAttribute::Float(val) => Ok(*val),
|
||||
FbxAttribute::Integer(val) => Ok(*val as f32),
|
||||
FbxAttribute::Long(val) => Ok(*val as f32),
|
||||
FbxAttribute::Bool(val) => Ok((*val as i32) as f32),
|
||||
FbxAttribute::String(val) => {
|
||||
match val.parse::<f32>() {
|
||||
Ok(i) => Ok(i),
|
||||
Err(_) => Err(format!("Unable to convert string {} to f32", val))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,10 +118,32 @@ struct FbxTexture {
|
||||
filename: String,
|
||||
}
|
||||
|
||||
impl FbxTexture {
|
||||
fn read(texture_node_hanle: &Handle<FbxNode>, nodes: &Pool<FbxNode>,
|
||||
stack: &mut Vec<Handle<FbxNode>>) -> Result<FbxTexture, String> {
|
||||
let mut texture = FbxTexture {
|
||||
filename: String::new()
|
||||
};
|
||||
if let Ok(relative_file_name_node) = find_and_borrow_node(nodes, stack, texture_node_hanle, "RelativeFilename") {
|
||||
texture.filename = relative_file_name_node.get_attrib(0)?.as_string();
|
||||
println!("{}", texture.filename);
|
||||
}
|
||||
Ok(texture)
|
||||
}
|
||||
}
|
||||
|
||||
struct FbxMaterial {
|
||||
diffuse_texture: Handle<FbxComponent>
|
||||
}
|
||||
|
||||
impl FbxMaterial {
|
||||
fn read(material_node_hanle: &Handle<FbxNode>) -> Result<FbxMaterial, String> {
|
||||
Ok(FbxMaterial {
|
||||
diffuse_texture: Handle::none()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct FbxDeformer {
|
||||
sub_deformers: Vec<Handle<FbxComponent>>
|
||||
}
|
||||
@@ -122,6 +164,7 @@ struct FbxAnimationCurveNode {
|
||||
curves: Vec<Handle<FbxComponent>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
enum FbxMapping {
|
||||
Unknown,
|
||||
ByPolygon,
|
||||
@@ -131,6 +174,7 @@ enum FbxMapping {
|
||||
AllSame,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
enum FbxReference {
|
||||
Unknown,
|
||||
Direct,
|
||||
@@ -139,30 +183,37 @@ enum FbxReference {
|
||||
|
||||
struct FbxNode {
|
||||
name: String,
|
||||
attributes: Vec<FbxAttribute>,
|
||||
attribs: Vec<FbxAttribute>,
|
||||
parent: Handle<FbxNode>,
|
||||
children: Vec<Handle<FbxNode>>,
|
||||
}
|
||||
|
||||
impl FbxNode {
|
||||
fn get_vec3_at(&self, n: usize) -> Result<Vec3, &'static str> {
|
||||
if n + 3 <= self.attributes.len() {
|
||||
return Ok(Vec3 {
|
||||
x: self.attributes[n].as_float(),
|
||||
y: self.attributes[n + 1].as_float(),
|
||||
z: self.attributes[n + 2].as_float(),
|
||||
});
|
||||
}
|
||||
return Err("FBX: Attribute index out of bounds");
|
||||
fn get_vec3_at(&self, n: usize) -> Result<Vec3, String> {
|
||||
return Ok(Vec3 {
|
||||
x: self.get_attrib(n)?.as_float()?,
|
||||
y: self.get_attrib(n + 1)?.as_float()?,
|
||||
z: self.get_attrib(n + 2)?.as_float()?,
|
||||
});
|
||||
}
|
||||
|
||||
fn get_vec3_at_unchecked(&self, n: usize) -> Vec3 {
|
||||
Vec3 {
|
||||
x: self.attributes[n].as_float(),
|
||||
y: self.attributes[n + 1].as_float(),
|
||||
z: self.attributes[n + 2].as_float(),
|
||||
fn get_vec2_at(&self, n: usize) -> Result<Vec2, String> {
|
||||
return Ok(Vec2 {
|
||||
x: self.get_attrib(n)?.as_float()?,
|
||||
y: self.get_attrib(n + 1)?.as_float()?,
|
||||
});
|
||||
}
|
||||
|
||||
fn get_attrib(&self, n: usize) -> Result<&FbxAttribute, String> {
|
||||
match self.attribs.get(n) {
|
||||
Some(attrib) => Ok(attrib),
|
||||
None => Err(format!("Unable to get {} attribute because index out of bounds.", n))
|
||||
}
|
||||
}
|
||||
|
||||
fn attrib_count(&self) -> usize {
|
||||
self.attribs.len()
|
||||
}
|
||||
}
|
||||
|
||||
struct FbxGeometry {
|
||||
@@ -196,7 +247,7 @@ struct FbxGeometry {
|
||||
impl FbxGeometry {
|
||||
pub fn read(geom_node_handle: &Handle<FbxNode>,
|
||||
nodes: &Pool<FbxNode>,
|
||||
stack: &mut Vec<Handle<FbxNode>>) -> Result<FbxGeometry, &'static str> {
|
||||
stack: &mut Vec<Handle<FbxNode>>) -> Result<FbxGeometry, String> {
|
||||
let mut geom = FbxGeometry {
|
||||
vertices: Vec::new(),
|
||||
indices: Vec::new(),
|
||||
@@ -220,59 +271,81 @@ impl FbxGeometry {
|
||||
};
|
||||
|
||||
// Read vertices
|
||||
if let Some(vertices_node_handle) = find_node(nodes, stack, geom_node_handle, "Vertices") {
|
||||
if let Some(vertices_array_node) = find_and_borrow_node(nodes, stack, &vertices_node_handle, "a") {
|
||||
let vertex_count = vertices_array_node.attributes.len() / 3;
|
||||
geom.vertices = Vec::with_capacity(vertex_count);
|
||||
for i in 0..vertex_count {
|
||||
geom.vertices.push(vertices_array_node.get_vec3_at_unchecked(i * 3));
|
||||
}
|
||||
} else {
|
||||
return Err("FBX: Unable to find array node of vertices");
|
||||
}
|
||||
} else {
|
||||
return Err("FBX: Unable to find vertices node");
|
||||
let vertices_node_handle = find_node(nodes, stack, geom_node_handle, "Vertices")?;
|
||||
let vertices_array_node = find_and_borrow_node(nodes, stack, &vertices_node_handle, "a")?;
|
||||
let vertex_count = vertices_array_node.attrib_count() / 3;
|
||||
geom.vertices = Vec::with_capacity(vertex_count);
|
||||
for i in 0..vertex_count {
|
||||
geom.vertices.push(vertices_array_node.get_vec3_at(i * 3)?);
|
||||
}
|
||||
|
||||
// Read faces
|
||||
if let Some(indices_node_handle) = find_node(nodes, stack, geom_node_handle, "PolygonVertexIndex") {
|
||||
if let Some(indices_array_node) = find_and_borrow_node(nodes, stack, &indices_node_handle, "a") {
|
||||
let index_count = indices_array_node.attributes.len();
|
||||
geom.indices = Vec::with_capacity(index_count);
|
||||
for i in 0..index_count {
|
||||
geom.indices.push(indices_array_node.attributes[i].as_int());
|
||||
}
|
||||
} else {
|
||||
return Err("FBX: Unable to find array node of indices");
|
||||
}
|
||||
} else {
|
||||
return Err("FBX: Unable to find indices node");
|
||||
let indices_node_handle = find_node(nodes, stack, geom_node_handle, "PolygonVertexIndex")?;
|
||||
let indices_array_node = find_and_borrow_node(nodes, stack, &indices_node_handle, "a")?;
|
||||
let index_count = indices_array_node.attrib_count();
|
||||
geom.indices = Vec::with_capacity(index_count);
|
||||
for i in 0..index_count {
|
||||
let index = indices_array_node.get_attrib(i)?.as_int()?;
|
||||
geom.indices.push(index);
|
||||
}
|
||||
|
||||
// read normals
|
||||
if let Some(layer_element_normal_node_handle) = find_node(nodes, stack, geom_node_handle, "LayerElementNormal") {
|
||||
if let Some(map_type_node) = find_and_borrow_node(nodes, stack, &layer_element_normal_node_handle, "MappingInformationType") {
|
||||
geom.normal_mapping = string_to_mapping(&map_type_node.attributes[0].as_string());
|
||||
}
|
||||
if let Some(ref_type_node) = find_and_borrow_node(nodes, stack, &layer_element_normal_node_handle, "ReferenceInformationType") {
|
||||
geom.normal_reference = string_to_reference(&ref_type_node.attributes[0].as_string());
|
||||
}
|
||||
// finally read normals
|
||||
if let Some(normals_node_handle) = find_node(nodes, stack, &layer_element_normal_node_handle, "Normals") {
|
||||
if let Some(normals_array_node) = find_and_borrow_node(nodes, stack, &normals_node_handle, "a") {
|
||||
let count = normals_array_node.attributes.len() / 3;
|
||||
for i in 0..count {
|
||||
geom.normals.push(normals_array_node.get_vec3_at_unchecked(i * 3));
|
||||
}
|
||||
}
|
||||
// Read normals (normals can not exist)
|
||||
if let Ok(layer_element_normal_node_handle) = find_node(nodes, stack, geom_node_handle, "LayerElementNormal") {
|
||||
let map_type_node = find_and_borrow_node(nodes, stack, &layer_element_normal_node_handle, "MappingInformationType")?;
|
||||
geom.normal_mapping = string_to_mapping(&map_type_node.get_attrib(0)?.as_string());
|
||||
|
||||
let ref_type_node = find_and_borrow_node(nodes, stack, &layer_element_normal_node_handle, "ReferenceInformationType")?;
|
||||
geom.normal_reference = string_to_reference(&ref_type_node.get_attrib(0)?.as_string());
|
||||
|
||||
let normals_node_handle = find_node(nodes, stack, &layer_element_normal_node_handle, "Normals")?;
|
||||
let normals_array_node = find_and_borrow_node(nodes, stack, &normals_node_handle, "a")?;
|
||||
let count = normals_array_node.attrib_count() / 3;
|
||||
for i in 0..count {
|
||||
geom.normals.push(normals_array_node.get_vec3_at(i * 3)?);
|
||||
}
|
||||
}
|
||||
|
||||
// todo: read tangents
|
||||
|
||||
// todo: read uvs
|
||||
// Read UVs
|
||||
if let Ok(layer_element_uv_node_handle) = find_node(nodes, stack, geom_node_handle, "LayerElementUV") {
|
||||
let map_type_node = find_and_borrow_node(nodes, stack, &layer_element_uv_node_handle, "MappingInformationType")?;
|
||||
geom.uv_mapping = string_to_mapping(&map_type_node.get_attrib(0)?.as_string());
|
||||
|
||||
// todo: read materials
|
||||
let ref_type_node = find_and_borrow_node(nodes, stack, &layer_element_uv_node_handle, "ReferenceInformationType")?;
|
||||
geom.uv_reference = string_to_reference(&ref_type_node.get_attrib(0)?.as_string());
|
||||
|
||||
let uvs_node_handle = find_node(nodes, stack, &layer_element_uv_node_handle, "UV")?;
|
||||
let uvs_array_node = find_and_borrow_node(nodes, stack, &uvs_node_handle, "a")?;
|
||||
let count = uvs_array_node.attrib_count() / 2;
|
||||
for i in 0..count {
|
||||
let uv = uvs_array_node.get_vec2_at(i * 2)?;
|
||||
geom.uvs.push(Vec2{x:uv.x, y: -uv.y}); // Hack
|
||||
}
|
||||
|
||||
if geom.uv_reference == FbxReference::IndexToDirect {
|
||||
let uv_index_node = find_node(nodes,stack, &layer_element_uv_node_handle, "UVIndex")?;
|
||||
let uv_index_array_node = find_and_borrow_node(nodes, stack, &uv_index_node, "a")?;
|
||||
for i in 0..uv_index_array_node.attrib_count() {
|
||||
geom.uv_index.push(uv_index_array_node.get_attrib(i)?.as_int()?);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read materials
|
||||
if let Ok(layer_element_material_node_handle) = find_node(nodes, stack, geom_node_handle, "LayerElementMaterial") {
|
||||
let map_type_node = find_and_borrow_node(nodes, stack, &layer_element_material_node_handle, "MappingInformationType")?;
|
||||
geom.material_mapping = string_to_mapping(&map_type_node.get_attrib(0)?.as_string());
|
||||
|
||||
let ref_type_node = find_and_borrow_node(nodes, stack, &layer_element_material_node_handle, "ReferenceInformationType")?;
|
||||
geom.material_reference = string_to_reference(&ref_type_node.get_attrib(0)?.as_string());
|
||||
|
||||
let materials_node_handle = find_node(nodes, stack, &layer_element_material_node_handle, "Materials")?;
|
||||
let materials_array_node = find_and_borrow_node(nodes, stack, &materials_node_handle, "a")?;
|
||||
for i in 0..materials_array_node.attrib_count() {
|
||||
geom.materials.push(materials_array_node.get_attrib(i)?.as_int()?);
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(geom);
|
||||
}
|
||||
@@ -329,12 +402,12 @@ struct FbxModel {
|
||||
impl FbxModel {
|
||||
pub fn read(model_node_handle: &Handle<FbxNode>,
|
||||
nodes: &Pool<FbxNode>,
|
||||
stack: &mut Vec<Handle<FbxNode>>) -> Result<FbxModel, &'static str> {
|
||||
stack: &mut Vec<Handle<FbxNode>>) -> Result<FbxModel, String> {
|
||||
let mut name = String::from("Unnamed");
|
||||
if let Some(model_node) = nodes.borrow(&model_node_handle) {
|
||||
if let Some(name_attrib) = model_node.attributes.get(1) {
|
||||
name = name_attrib.as_string();
|
||||
}
|
||||
|
||||
let model_node = nodes.borrow(&model_node_handle).unwrap();
|
||||
if let Ok(name_attrib) = model_node.get_attrib(1) {
|
||||
name = name_attrib.as_string();
|
||||
}
|
||||
|
||||
// Remove prefix
|
||||
@@ -364,40 +437,27 @@ impl FbxModel {
|
||||
light: Handle::none(),
|
||||
};
|
||||
|
||||
if let Some(properties70_node_handle) = find_node(nodes, stack, model_node_handle, "Properties70") {
|
||||
if let Some(properties70_node) = nodes.borrow(&properties70_node_handle) {
|
||||
for property_handle in properties70_node.children.iter() {
|
||||
if let Some(property_node) = nodes.borrow(&property_handle) {
|
||||
if let Some(name_attrib) = property_node.attributes.get(0) {
|
||||
if let FbxAttribute::String(name) = &name_attrib {
|
||||
match name.as_str() {
|
||||
"Lcl Translation" => model.translation = property_node.get_vec3_at(4)?,
|
||||
"Lcl Rotation" => model.rotation = property_node.get_vec3_at(4)?,
|
||||
"Lcl Scaling" => model.scale = property_node.get_vec3_at(4)?,
|
||||
"PreRotation" => model.pre_rotation = property_node.get_vec3_at(4)?,
|
||||
"PostRotation" => model.post_rotation = property_node.get_vec3_at(4)?,
|
||||
"RotationOffset" => model.rotation_offset = property_node.get_vec3_at(4)?,
|
||||
"RotationPivot" => model.rotation_pivot = property_node.get_vec3_at(4)?,
|
||||
"ScalingOffset" => model.scaling_offset = property_node.get_vec3_at(4)?,
|
||||
"ScalingPivot" => model.scaling_pivot = property_node.get_vec3_at(4)?,
|
||||
"GeometricTranslation" => model.geometric_translation = property_node.get_vec3_at(4)?,
|
||||
"GeometricScaling" => model.geometric_scale = property_node.get_vec3_at(4)?,
|
||||
"GeometricRotation" => model.geometric_rotation = property_node.get_vec3_at(4)?,
|
||||
_ => () // Unused properties
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err("FBX: Invalid property handle");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err("FBX: Invalid fbx node handle");
|
||||
let properties70_node_handle = find_node(nodes, stack, model_node_handle, "Properties70")?;
|
||||
let properties70_node = nodes.borrow(&properties70_node_handle).unwrap();
|
||||
for property_handle in properties70_node.children.iter() {
|
||||
let property_node = nodes.borrow(&property_handle).unwrap();
|
||||
let name_attrib = property_node.get_attrib(0)?;
|
||||
match name_attrib.as_string().as_str() {
|
||||
"Lcl Translation" => model.translation = property_node.get_vec3_at(4)?,
|
||||
"Lcl Rotation" => model.rotation = property_node.get_vec3_at(4)?,
|
||||
"Lcl Scaling" => model.scale = property_node.get_vec3_at(4)?,
|
||||
"PreRotation" => model.pre_rotation = property_node.get_vec3_at(4)?,
|
||||
"PostRotation" => model.post_rotation = property_node.get_vec3_at(4)?,
|
||||
"RotationOffset" => model.rotation_offset = property_node.get_vec3_at(4)?,
|
||||
"RotationPivot" => model.rotation_pivot = property_node.get_vec3_at(4)?,
|
||||
"ScalingOffset" => model.scaling_offset = property_node.get_vec3_at(4)?,
|
||||
"ScalingPivot" => model.scaling_pivot = property_node.get_vec3_at(4)?,
|
||||
"GeometricTranslation" => model.geometric_translation = property_node.get_vec3_at(4)?,
|
||||
"GeometricScaling" => model.geometric_scale = property_node.get_vec3_at(4)?,
|
||||
"GeometricRotation" => model.geometric_rotation = property_node.get_vec3_at(4)?,
|
||||
_ => () // Unused properties
|
||||
}
|
||||
} else {
|
||||
return Err("FBX: Properties70 not found!");
|
||||
}
|
||||
|
||||
return Ok(model);
|
||||
}
|
||||
}
|
||||
@@ -449,46 +509,48 @@ pub struct Fbx {
|
||||
/// borrow references to actual nodes.
|
||||
nodes: Pool<FbxNode>,
|
||||
/// Pool for FBX components, filled in "prepare" method
|
||||
components: Pool<FbxComponent>,
|
||||
component_pool: Pool<FbxComponent>,
|
||||
root: Handle<FbxNode>,
|
||||
/// Map used for fast look up of components by their fbx-indices
|
||||
index_to_component: HashMap<i64, Handle<FbxComponent>>,
|
||||
/// Actual list of created components
|
||||
components: Vec<Handle<FbxComponent>>
|
||||
}
|
||||
|
||||
/// Searches node by specified name and returns its handle if found
|
||||
/// Uses provided stack to do depth search
|
||||
fn find_node(pool: &Pool<FbxNode>, stack: &mut Vec<Handle<FbxNode>>, root: &Handle<FbxNode>, name: &str) -> Option<Handle<FbxNode>> {
|
||||
fn find_node(pool: &Pool<FbxNode>, stack: &mut Vec<Handle<FbxNode>>, root: &Handle<FbxNode>, name: &str) -> Result<Handle<FbxNode>, String> {
|
||||
stack.clear();
|
||||
stack.push(root.clone());
|
||||
while let Some(handle) = stack.pop() {
|
||||
if let Some(node) = pool.borrow(&handle) {
|
||||
if node.name == name {
|
||||
return Some(handle);
|
||||
return Ok(handle);
|
||||
}
|
||||
for child_handle in node.children.iter() {
|
||||
stack.push(child_handle.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
Err(format!("Unable to find {} node", name))
|
||||
}
|
||||
|
||||
/// Searches node by specified name and borrows a reference to it
|
||||
/// Uses provided stack to do depth search
|
||||
fn find_and_borrow_node<'a>(pool: &'a Pool<FbxNode>, stack: &mut Vec<Handle<FbxNode>>, root: &Handle<FbxNode>, name: &str) -> Option<&'a FbxNode> {
|
||||
fn find_and_borrow_node<'a>(pool: &'a Pool<FbxNode>, stack: &mut Vec<Handle<FbxNode>>, root: &Handle<FbxNode>, name: &str) -> Result<&'a FbxNode, String> {
|
||||
stack.clear();
|
||||
stack.push(root.clone());
|
||||
while let Some(handle) = stack.pop() {
|
||||
if let Some(node) = pool.borrow(&handle) {
|
||||
if node.name == name {
|
||||
return Some(node);
|
||||
return Ok(node);
|
||||
}
|
||||
for child_handle in node.children.iter() {
|
||||
stack.push(child_handle.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
Err(format!("Unable to find {} node", name))
|
||||
}
|
||||
|
||||
/// Links child component with parent component so parent will know about child
|
||||
@@ -540,13 +602,13 @@ fn link_child_with_parent_component(parent: &mut FbxComponent, child_handle: &Ha
|
||||
}
|
||||
}
|
||||
|
||||
fn read_ascii(path: &Path) -> Result<Fbx, &'static str> {
|
||||
fn read_ascii(path: &Path) -> Result<Fbx, String> {
|
||||
let mut nodes: Pool<FbxNode> = Pool::new();
|
||||
let root_handle = nodes.spawn(FbxNode {
|
||||
name: String::from("__ROOT__"),
|
||||
children: Vec::new(),
|
||||
parent: Handle::none(),
|
||||
attributes: Vec::new(),
|
||||
attribs: Vec::new(),
|
||||
});
|
||||
let mut parent_handle: Handle<FbxNode> = root_handle.clone();
|
||||
let mut node_handle: Handle<FbxNode> = Handle::none();
|
||||
@@ -579,7 +641,7 @@ fn read_ascii(path: &Path) -> Result<Fbx, &'static str> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err("unexpected end of file");
|
||||
return Err(String::from("unexpected end of file"));
|
||||
}
|
||||
}
|
||||
if end {
|
||||
@@ -605,9 +667,9 @@ fn read_ascii(path: &Path) -> Result<Fbx, &'static str> {
|
||||
}
|
||||
if symbol == ':' && !read_value {
|
||||
read_value = true;
|
||||
let mut node = FbxNode {
|
||||
let node = FbxNode {
|
||||
name: name.iter().collect(),
|
||||
attributes: Vec::new(),
|
||||
attribs: Vec::new(),
|
||||
parent: parent_handle.clone(),
|
||||
children: Vec::new(),
|
||||
};
|
||||
@@ -623,9 +685,9 @@ fn read_ascii(path: &Path) -> Result<Fbx, &'static str> {
|
||||
if value.len() > 0 {
|
||||
if let Some(node) = nodes.borrow_mut(&node_handle) {
|
||||
let attrib = FbxAttribute::String(value.iter().collect());
|
||||
node.attributes.push(attrib);
|
||||
node.attribs.push(attrib);
|
||||
} else {
|
||||
return Err("FBX: Failed to fetch node by handle when entering child scope");
|
||||
return Err(String::from("FBX: Failed to fetch node by handle when entering child scope"));
|
||||
}
|
||||
value.clear();
|
||||
}
|
||||
@@ -642,9 +704,9 @@ fn read_ascii(path: &Path) -> Result<Fbx, &'static str> {
|
||||
|
||||
if let Some(node) = nodes.borrow_mut(&node_handle) {
|
||||
let attrib = FbxAttribute::String(value.iter().collect());
|
||||
node.attributes.push(attrib);
|
||||
node.attribs.push(attrib);
|
||||
} else {
|
||||
return Err("FBX: Failed to fetch node by handle when committing attribute");
|
||||
return Err(String::from("FBX: Failed to fetch node by handle when committing attribute"));
|
||||
}
|
||||
value.clear();
|
||||
} else {
|
||||
@@ -661,7 +723,8 @@ fn read_ascii(path: &Path) -> Result<Fbx, &'static str> {
|
||||
Ok(Fbx {
|
||||
nodes,
|
||||
root: root_handle,
|
||||
components: Pool::new(),
|
||||
component_pool: Pool::new(),
|
||||
components: Vec::new(),
|
||||
index_to_component: HashMap::new(),
|
||||
})
|
||||
}
|
||||
@@ -687,94 +750,189 @@ fn string_to_reference(value: &String) -> FbxReference {
|
||||
}
|
||||
}
|
||||
|
||||
/// Input angles in degrees
|
||||
fn quat_from_euler(euler: Vec3) -> Quat {
|
||||
Quat::from_euler(
|
||||
Vec3::make(euler.x.to_radians(), euler.y.to_radians(), euler.z.to_radians()),
|
||||
RotationOrder::XYZ)
|
||||
}
|
||||
|
||||
/// Fixes index that is used as indicator of end of a polygon
|
||||
/// FBX stores array of indices like so 0,1,2,1,2,-4,... where -4
|
||||
/// is actually index 3 but it xor'ed using -1.
|
||||
fn fix_index(index: i32) -> usize {
|
||||
if index < 0 {
|
||||
(-index - 1) as usize
|
||||
} else {
|
||||
index as usize
|
||||
}
|
||||
}
|
||||
|
||||
/// Triangulates polygon face if needed.
|
||||
/// Returns number of processed indices.
|
||||
fn prepare_next_face(geom: &FbxGeometry,
|
||||
start: usize,
|
||||
temp_vertices: &mut Vec<Vec3>,
|
||||
out_triangles: &mut Vec<(usize, usize, usize)>,
|
||||
out_relative_triangles: &mut Vec<(usize, usize, usize)>) -> usize {
|
||||
out_triangles.clear();
|
||||
out_relative_triangles.clear();
|
||||
|
||||
// Find out how much vertices do we have per face.
|
||||
let mut vertex_per_face = 0;
|
||||
for i in start..geom.indices.len() {
|
||||
vertex_per_face += 1;
|
||||
if geom.indices[i] < 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if vertex_per_face == 3 {
|
||||
let a = fix_index(geom.indices[start]);
|
||||
let b = fix_index(geom.indices[start + 1]);
|
||||
let c = fix_index(geom.indices[start + 2]);
|
||||
|
||||
// Ensure that we have valid indices here. Some exporters may fuck up indices
|
||||
// and they'll blow up loader.
|
||||
if a < geom.vertices.len() && b < geom.vertices.len() && c < geom.vertices.len() {
|
||||
// We have a triangle
|
||||
out_triangles.push((a, b, c));
|
||||
out_relative_triangles.push((0, 1, 2));
|
||||
}
|
||||
} else if vertex_per_face > 3 {
|
||||
// Triangulate a polygon. Triangulate it!
|
||||
temp_vertices.clear();
|
||||
for i in 0..vertex_per_face {
|
||||
temp_vertices.push(geom.vertices[fix_index(geom.indices[start + i])]);
|
||||
}
|
||||
triangulate(&temp_vertices.as_slice(), out_relative_triangles);
|
||||
for triangle in out_relative_triangles.iter() {
|
||||
out_triangles.push((
|
||||
fix_index(geom.indices[start + triangle.0]),
|
||||
fix_index(geom.indices[start + triangle.1]),
|
||||
fix_index(geom.indices[start + triangle.2])));
|
||||
}
|
||||
}
|
||||
|
||||
return vertex_per_face;
|
||||
}
|
||||
|
||||
fn convert_vertex(geom: &FbxGeometry,
|
||||
mesh: &mut Mesh,
|
||||
geometric_transform: &Mat4,
|
||||
material_index: usize,
|
||||
origin: usize,
|
||||
index: usize,
|
||||
relative_index: usize) {
|
||||
let position = geometric_transform.transform_vector(geom.vertices[index]);
|
||||
|
||||
let normal = geometric_transform.transform_vector_normal(match geom.normal_mapping {
|
||||
FbxMapping::ByPolygonVertex => geom.normals[origin + relative_index],
|
||||
FbxMapping::ByVertex => geom.normals[index],
|
||||
_ => Vec3 { x: 0.0, y: 1.0, z: 0.0 }
|
||||
});
|
||||
|
||||
let tangent = geometric_transform.transform_vector_normal(match geom.tangent_mapping {
|
||||
FbxMapping::ByPolygonVertex => geom.tangents[origin + relative_index],
|
||||
FbxMapping::ByVertex => geom.tangents[index],
|
||||
_ => Vec3 { x: 0.0, y: 1.0, z: 0.0 }
|
||||
});
|
||||
|
||||
let uv = match geom.uv_mapping {
|
||||
FbxMapping::ByPolygonVertex => {
|
||||
match geom.uv_reference {
|
||||
FbxReference::Direct => geom.uvs[origin + relative_index],
|
||||
FbxReference::IndexToDirect => geom.uvs[geom.uv_index[origin + relative_index] as usize],
|
||||
_ => Vec2 { x: 0.0, y: 0.0 }
|
||||
}
|
||||
}
|
||||
_ => Vec2 { x: 0.0, y: 0.0 }
|
||||
};
|
||||
|
||||
let material = match geom.material_mapping {
|
||||
FbxMapping::AllSame => geom.materials[0] as usize,
|
||||
FbxMapping::ByPolygon => geom.materials[material_index] as usize,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
let surface = mesh.get_surfaces_mut().get_mut(material).unwrap();
|
||||
surface.data.borrow_mut().insert_vertex(Vertex {
|
||||
position,
|
||||
normal,
|
||||
tex_coord: uv,
|
||||
tangent: Vec4 { x: tangent.x, y: tangent.y, z: tangent.z, w: 1.0 },
|
||||
})
|
||||
}
|
||||
|
||||
impl Fbx {
|
||||
/// Parses FBX DOM and filling internal lists to prepare
|
||||
/// for conversion to engine format
|
||||
fn prepare(&mut self) -> Result<(), &'static str> {
|
||||
fn prepare(&mut self) -> Result<(), String> {
|
||||
// Search-stack for internal routines
|
||||
let mut traversal_stack: Vec<Handle<FbxNode>> = Vec::new();
|
||||
|
||||
// Check version
|
||||
if let Some(header_handle) = find_node(&self.nodes, &mut traversal_stack, &self.root, "FBXHeaderExtension") {
|
||||
if let Some(version) = find_and_borrow_node(&self.nodes, &mut traversal_stack, &header_handle, "FBXVersion") {
|
||||
if let Some(version_attrib) = version.attributes.get(0) {
|
||||
if version_attrib.as_int() < 7100 {
|
||||
return Err("FBX: Unsupported version. Version must be >= 7100");
|
||||
}
|
||||
} else {
|
||||
return Err("FBX: Version attribute not found");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err("FBX: Unable to find header");
|
||||
let header_handle = find_node(&self.nodes, &mut traversal_stack, &self.root, "FBXHeaderExtension")?;
|
||||
let version = find_and_borrow_node(&self.nodes, &mut traversal_stack, &header_handle, "FBXVersion")?;
|
||||
let version = version.get_attrib(0)?.as_int()?;
|
||||
if version < 7100 {
|
||||
return Err(format!("FBX: Unsupported {} version. Version must be >= 7100", version));
|
||||
}
|
||||
|
||||
// Read objects
|
||||
if let Some(objects_node) = find_and_borrow_node(&self.nodes, &mut traversal_stack, &self.root, "Objects") {
|
||||
for object_handle in objects_node.children.iter() {
|
||||
if let Some(object) = self.nodes.borrow(&object_handle) {
|
||||
let index: i64 = object.attributes[0].as_int64();
|
||||
let mut component_handle: Handle<FbxComponent> = Handle::none();
|
||||
match object.name.as_str() {
|
||||
"Geometry" => {
|
||||
component_handle = self.components.spawn(FbxComponent::Geometry(
|
||||
FbxGeometry::read(object_handle, &self.nodes, &mut traversal_stack)?))
|
||||
}
|
||||
"Model" => {
|
||||
component_handle = self.components.spawn(FbxComponent::Model(
|
||||
FbxModel::read(object_handle, &self.nodes, &mut traversal_stack)?))
|
||||
}
|
||||
"Material" => {
|
||||
println!("reading a Material");
|
||||
}
|
||||
"Texture" => {
|
||||
println!("reading a Texture");
|
||||
}
|
||||
"NodeAttribute" => {
|
||||
println!("reading a NodeAttribute");
|
||||
}
|
||||
"AnimationCurve" => {
|
||||
println!("reading a AnimationCurve");
|
||||
}
|
||||
"AnimationCurveNode" => {
|
||||
println!("reading a AnimationCurveNode");
|
||||
}
|
||||
"Deformer" => {
|
||||
println!("reading a Deformer");
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
if !component_handle.is_none() {
|
||||
self.index_to_component.insert(index, component_handle);
|
||||
}
|
||||
let objects_node = find_and_borrow_node(&self.nodes, &mut traversal_stack, &self.root, "Objects")?;
|
||||
for object_handle in objects_node.children.iter() {
|
||||
let object = self.nodes.borrow(&object_handle).unwrap();
|
||||
let index: i64 = object.get_attrib(0)?.as_int64()?;
|
||||
let mut component_handle: Handle<FbxComponent> = Handle::none();
|
||||
match object.name.as_str() {
|
||||
"Geometry" => {
|
||||
component_handle = self.component_pool.spawn(FbxComponent::Geometry(
|
||||
FbxGeometry::read(object_handle, &self.nodes, &mut traversal_stack)?));
|
||||
}
|
||||
"Model" => {
|
||||
component_handle = self.component_pool.spawn(FbxComponent::Model(
|
||||
FbxModel::read(object_handle, &self.nodes, &mut traversal_stack)?));
|
||||
}
|
||||
"Material" => {
|
||||
component_handle = self.component_pool.spawn(FbxComponent::Material(
|
||||
FbxMaterial::read(object_handle)?));
|
||||
}
|
||||
"Texture" => {
|
||||
component_handle = self.component_pool.spawn(FbxComponent::Texture(
|
||||
FbxTexture::read(object_handle, &self.nodes, &mut traversal_stack)?));
|
||||
}
|
||||
"NodeAttribute" => {
|
||||
//println!("reading a NodeAttribute");
|
||||
}
|
||||
"AnimationCurve" => {
|
||||
//println!("reading a AnimationCurve");
|
||||
}
|
||||
"AnimationCurveNode" => {
|
||||
//println!("reading a AnimationCurveNode");
|
||||
}
|
||||
"Deformer" => {
|
||||
//println!("reading a Deformer");
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
if !component_handle.is_none() {
|
||||
self.index_to_component.insert(index, component_handle.clone());
|
||||
self.components.push(component_handle.clone());
|
||||
}
|
||||
} else {
|
||||
return Err("FBX: Objects missing");
|
||||
}
|
||||
|
||||
// Read connections
|
||||
if let Some(connections_node) = find_and_borrow_node(&self.nodes, &mut traversal_stack, &self.root, "Connections") {
|
||||
for connection_handle in connections_node.children.iter() {
|
||||
if let Some(connection) = self.nodes.borrow(&connection_handle) {
|
||||
if connection.attributes.len() < 3 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let child_index = connection.attributes[1].as_int64();
|
||||
let parent_index = connection.attributes[2].as_int64();
|
||||
|
||||
if let Some(parent_handle) = self.index_to_component.get(&parent_index) {
|
||||
if let Some(child_handle) = self.index_to_component.get(&child_index) {
|
||||
let mut child_type_id = FbxComponentTypeId::Unknown;
|
||||
if let Some(child) = self.components.borrow(child_handle) {
|
||||
child_type_id = child.type_id();
|
||||
}
|
||||
if let Some(parent) = self.components.borrow_mut(parent_handle) {
|
||||
link_child_with_parent_component(parent, child_handle, child_type_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
let connections_node = find_and_borrow_node(&self.nodes, &mut traversal_stack, &self.root, "Connections")?;
|
||||
for connection_handle in connections_node.children.iter() {
|
||||
let connection = self.nodes.borrow(&connection_handle).unwrap();
|
||||
let child_index = connection.get_attrib(1)?.as_int64()?;
|
||||
let parent_index = connection.get_attrib(2)?.as_int64()?;
|
||||
if let Some(parent_handle) = self.index_to_component.get(&parent_index) {
|
||||
if let Some(child_handle) = self.index_to_component.get(&child_index) {
|
||||
let child_type_id = self.component_pool.borrow(child_handle).unwrap().type_id();
|
||||
let parent = self.component_pool.borrow_mut(parent_handle).unwrap();
|
||||
link_child_with_parent_component(parent, child_handle, child_type_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -782,28 +940,162 @@ impl Fbx {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn convert_light(&self, light: &mut Light, fbx_light: &FbxLight) {
|
||||
light.set_color(Vec3::make(fbx_light.color.r as f32 / 255.0,
|
||||
fbx_light.color.g as f32 / 255.0,
|
||||
fbx_light.color.b as f32 / 255.0));
|
||||
light.set_radius(fbx_light.radius);
|
||||
}
|
||||
|
||||
fn create_surfaces(&self, mesh: &mut Mesh, model: &FbxModel, resource_manager: &mut ResourceManager) {
|
||||
// Create surfaces per material
|
||||
if model.materials.is_empty() {
|
||||
let surface_data = SurfaceSharedData::new();
|
||||
mesh.add_surface(Surface::new(&Rc::new(RefCell::new(surface_data))));
|
||||
} else {
|
||||
for material_handle in model.materials.iter() {
|
||||
let surface_data = SurfaceSharedData::new();
|
||||
let mut surface = Surface::new(&Rc::new(RefCell::new(surface_data)));
|
||||
if let FbxComponent::Material(material) = self.component_pool.borrow(&material_handle).unwrap() {
|
||||
if let Some(texture_handle) = self.component_pool.borrow(&material.diffuse_texture) {
|
||||
if let FbxComponent::Texture(texture) = texture_handle {
|
||||
if !texture.filename.is_empty() {
|
||||
if let Some(texture_resource) =resource_manager.request_texture(Path::new(texture.filename.as_str())) {
|
||||
println!("here 1");
|
||||
surface.set_texture(texture_resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mesh.add_surface(surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_mesh(&self, mesh: &mut Mesh, model: &FbxModel, scene: &mut Scene, resource_manager: &mut ResourceManager) {
|
||||
let geometric_transform = Mat4::translate(model.geometric_translation) *
|
||||
Mat4::from_quat(quat_from_euler(model.geometric_rotation)) *
|
||||
Mat4::scale(model.geometric_scale);
|
||||
|
||||
let mut temp_vertices: Vec<Vec3> = Vec::new();
|
||||
let mut triangles: Vec<(usize, usize, usize)> = Vec::new();
|
||||
let mut relative_triangles: Vec<(usize, usize, usize)> = Vec::new();
|
||||
|
||||
for geom_handle in &model.geoms {
|
||||
let geom_component = self.component_pool.borrow(&geom_handle).unwrap();
|
||||
if let FbxComponent::Geometry(geom) = geom_component {
|
||||
self.create_surfaces(mesh, model, resource_manager);
|
||||
|
||||
let mut material_index = 0;
|
||||
let mut n = 0;
|
||||
while n < geom.indices.len() {
|
||||
let origin = n;
|
||||
n += prepare_next_face(geom, n, &mut temp_vertices, &mut triangles, &mut relative_triangles);
|
||||
for i in 0..triangles.len() {
|
||||
let triangle = &triangles[i];
|
||||
let relative_triangle = &relative_triangles[i];
|
||||
|
||||
convert_vertex(geom, mesh, &geometric_transform, material_index, origin, triangle.0, relative_triangle.0);
|
||||
convert_vertex(geom, mesh, &geometric_transform, material_index, origin, triangle.1, relative_triangle.1);
|
||||
convert_vertex(geom, mesh, &geometric_transform, material_index, origin, triangle.2, relative_triangle.2);
|
||||
}
|
||||
if geom.material_mapping == FbxMapping::ByPolygon {
|
||||
material_index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_model(&self, model: &FbxModel, scene: &mut Scene, resource_manager: &mut ResourceManager) ->
|
||||
Result<Handle<Node>, String> {
|
||||
// Create node with of correct kind.
|
||||
let mut node =
|
||||
if model.geoms.len() != 0 {
|
||||
Node::new(NodeKind::Mesh(Mesh::default()))
|
||||
} else if !model.light.is_none() {
|
||||
Node::new(NodeKind::Light(Light::default()))
|
||||
} else {
|
||||
Node::new(NodeKind::Base)
|
||||
};
|
||||
|
||||
node.set_name(model.name.clone());
|
||||
node.set_local_rotation(quat_from_euler(model.rotation));
|
||||
node.set_local_scale(model.scale);
|
||||
node.set_local_position(model.translation);
|
||||
node.set_post_rotation(quat_from_euler(model.post_rotation));
|
||||
node.set_pre_rotation(quat_from_euler(model.pre_rotation));
|
||||
node.set_rotation_offset(model.rotation_offset);
|
||||
node.set_rotation_pivot(model.rotation_pivot);
|
||||
node.set_scaling_offset(model.scaling_offset);
|
||||
node.set_scaling_pivot(model.scaling_pivot);
|
||||
|
||||
match node.borrow_kind_mut() {
|
||||
NodeKind::Light(light) => {
|
||||
let fbx_light_component = self.component_pool.borrow(&model.light).unwrap();
|
||||
if let FbxComponent::Light(fbx_light) = fbx_light_component {
|
||||
self.convert_light(light, fbx_light);
|
||||
}
|
||||
}
|
||||
NodeKind::Mesh(mesh) => {
|
||||
self.convert_mesh(mesh, model, scene, resource_manager);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
Ok(scene.add_node(node))
|
||||
}
|
||||
|
||||
///
|
||||
/// Converts FBX DOM to native engine representation.
|
||||
///
|
||||
pub fn convert(&self, scene: &mut Scene, resource_manager: &mut ResourceManager)
|
||||
-> Result<Handle<Node>, String> {
|
||||
let root = scene.add_node(Node::new(NodeKind::Base));
|
||||
let mut fbx_model_to_node_map: HashMap<Handle<FbxComponent>, Handle<Node>> = HashMap::new();
|
||||
for component_handle in self.components.iter() {
|
||||
if let Some(component) = self.component_pool.borrow(&component_handle) {
|
||||
if let FbxComponent::Model(model) = component {
|
||||
if let Ok(node) = self.convert_model(model, scene, resource_manager) {
|
||||
scene.link_nodes(&node, &root);
|
||||
fbx_model_to_node_map.insert(component_handle.clone(), node.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Link according to hierarchy
|
||||
for (fbx_model_handle, node_handle) in fbx_model_to_node_map.iter() {
|
||||
if let FbxComponent::Model(fbx_model) = self.component_pool.borrow(&fbx_model_handle).unwrap() {
|
||||
for fbx_child_handle in fbx_model.children.iter() {
|
||||
if let Some(child_handle) = fbx_model_to_node_map.get(fbx_child_handle) {
|
||||
scene.link_nodes(&child_handle, &node_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(root)
|
||||
}
|
||||
|
||||
/// TODO: format trait maybe?
|
||||
pub fn print(&mut self) {
|
||||
|
||||
|
||||
let mut stack: Vec<Handle<FbxNode>> = Vec::new();
|
||||
stack.push(self.root.clone());
|
||||
while let Some(handle) = stack.pop() {
|
||||
if let Some(node) = self.nodes.borrow(&handle) {
|
||||
println!("{}", node.name);
|
||||
let node = self.nodes.borrow(&handle).unwrap();
|
||||
println!("{}", node.name);
|
||||
|
||||
// Continue printing children
|
||||
for child_handle in node.children.iter() {
|
||||
stack.push(child_handle.clone());
|
||||
}
|
||||
// Continue printing children
|
||||
for child_handle in node.children.iter() {
|
||||
stack.push(child_handle.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_to_scene(scene: &mut Scene, path: &Path) {
|
||||
if let Ok(ref mut fbx) = read_ascii(path) {
|
||||
if let Ok(_) = fbx.prepare() {
|
||||
|
||||
}
|
||||
}
|
||||
pub fn load_to_scene(scene: &mut Scene, resource_manager: &mut ResourceManager, path: &Path)
|
||||
-> Result<Handle<Node>, String> {
|
||||
let ref mut fbx = read_ascii(path)?;
|
||||
fbx.prepare()?;
|
||||
fbx.convert(scene, resource_manager)
|
||||
}
|
||||
+71
-1
@@ -22,6 +22,14 @@ impl Light {
|
||||
color: Vec3 { x: 1.0, y: 1.0, z: 1.0 },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_radius(&mut self, radius: f32) {
|
||||
self.radius = radius;
|
||||
}
|
||||
|
||||
pub fn set_color(&mut self, color: Vec3) {
|
||||
self.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Camera {
|
||||
@@ -73,7 +81,7 @@ impl Camera {
|
||||
}
|
||||
|
||||
pub struct Mesh {
|
||||
pub(crate) surfaces: Vec<Surface>
|
||||
surfaces: Vec<Surface>
|
||||
}
|
||||
|
||||
impl Mesh {
|
||||
@@ -94,6 +102,18 @@ impl Mesh {
|
||||
surface.set_texture(tex.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_surfaces(&self) -> &Vec<Surface> {
|
||||
&self.surfaces
|
||||
}
|
||||
|
||||
pub fn get_surfaces_mut(&mut self) -> &mut Vec<Surface> {
|
||||
&mut self.surfaces
|
||||
}
|
||||
|
||||
pub fn add_surface(&mut self, surface: Surface) {
|
||||
self.surfaces.push(surface);
|
||||
}
|
||||
}
|
||||
|
||||
pub enum NodeKind {
|
||||
@@ -163,30 +183,77 @@ impl Node {
|
||||
scale_offset * scale_pivot * scale * scale_pivot_inv;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn borrow_kind(&self) -> &NodeKind {
|
||||
&self.kind
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn borrow_kind_mut(&mut self) -> &mut NodeKind {
|
||||
&mut self.kind
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_local_position(&mut self, pos: Vec3) {
|
||||
self.local_position = pos;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_local_rotation(&mut self, rot: Quat) {
|
||||
self.local_rotation = rot;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_pre_rotation(&mut self, pre_rotation: Quat) {
|
||||
self.pre_rotation = pre_rotation;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_post_rotation(&mut self, post_rotation: Quat) {
|
||||
self.post_rotation = post_rotation;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_rotation_offset(&mut self, rotation_offset: Vec3) {
|
||||
self.rotation_offset = rotation_offset;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_rotation_pivot(&mut self, rotation_pivot: Vec3) {
|
||||
self.rotation_pivot = rotation_pivot;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_scaling_offset(&mut self, scaling_offset: Vec3) {
|
||||
self.scaling_offset = scaling_offset;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_scaling_pivot(&mut self, scaling_pivot: Vec3) {
|
||||
self.scaling_pivot = scaling_pivot;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_name(&mut self, name: String) {
|
||||
self.name = name;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_name(&self) -> &str {
|
||||
self.name.as_str()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_local_scale(&mut self, scl: Vec3) {
|
||||
self.local_scale = scl;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn offset(&mut self, vec: Vec3) {
|
||||
self.local_position += vec;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_global_position(&self) -> Vec3 {
|
||||
Vec3 {
|
||||
x: self.global_transform.f[12],
|
||||
@@ -195,6 +262,7 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_look_vector(&self) -> Vec3 {
|
||||
Vec3 {
|
||||
x: self.global_transform.f[8],
|
||||
@@ -203,6 +271,7 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_side_vector(&self) -> Vec3 {
|
||||
Vec3 {
|
||||
x: self.global_transform.f[0],
|
||||
@@ -211,6 +280,7 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_up_vector(&self) -> Vec3 {
|
||||
Vec3 {
|
||||
x: self.global_transform.f[4],
|
||||
|
||||
+50
-29
@@ -1,22 +1,32 @@
|
||||
use std::marker::PhantomData;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
struct PoolRecord<T: Sized> {
|
||||
stamp: u32,
|
||||
generation: u32,
|
||||
payload: Option<T>,
|
||||
}
|
||||
|
||||
///
|
||||
/// Pool allows to create as many objects as you want in contiguous memory
|
||||
/// block. It allows to create and delete objects very fast.
|
||||
///
|
||||
pub struct Pool<T: Sized> {
|
||||
records: Vec<PoolRecord<T>>,
|
||||
free_stack: Vec<u32>
|
||||
}
|
||||
|
||||
///
|
||||
/// Handle is some sort of non-owning reference to content in a pool.
|
||||
/// It stores index of object and additional information that
|
||||
/// allows to ensure that handle is still valid.
|
||||
///
|
||||
pub struct Handle<T> {
|
||||
pub(crate) index: u32,
|
||||
index: u32,
|
||||
stamp: u32,
|
||||
type_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
struct PoolRecord<T: Sized> {
|
||||
stamp: u32,
|
||||
generation: u32,
|
||||
payload: Option<T>,
|
||||
}
|
||||
|
||||
impl<T> Clone for Handle<T> {
|
||||
fn clone(&self) -> Handle<T> {
|
||||
Handle {
|
||||
@@ -33,7 +43,19 @@ impl<T> PartialEq for Handle<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Eq for Handle<T> {
|
||||
|
||||
}
|
||||
|
||||
impl<T> Hash for Handle<T> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.index.hash(state);
|
||||
self.stamp.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Handle<T> {
|
||||
#[inline]
|
||||
pub fn none() -> Self {
|
||||
Handle {
|
||||
index: 0,
|
||||
@@ -42,12 +64,14 @@ impl<T> Handle<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_none(&self) -> bool {
|
||||
self.index == 0 && self.stamp == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Pool<T> {
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
Pool {
|
||||
records: Vec::<PoolRecord<T>>::new(),
|
||||
@@ -55,6 +79,7 @@ impl<T> Pool<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn spawn(&mut self, payload: T) -> Handle<T> {
|
||||
if let Some(free_index) = self.free_stack.pop() {
|
||||
let record = &mut self.records[free_index as usize];
|
||||
@@ -85,38 +110,31 @@ impl<T> Pool<T> {
|
||||
handle
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn borrow(&self, handle: &Handle<T>) -> Option<&T> {
|
||||
let index = handle.index as usize;
|
||||
if index < self.records.len() {
|
||||
unsafe {
|
||||
// _unchecked here because we already checked index
|
||||
let record = self.records.get_unchecked(index);
|
||||
if record.stamp == handle.stamp {
|
||||
if let Some(payload) = &record.payload {
|
||||
return Some(payload);
|
||||
}
|
||||
if let Some(record) = self.records.get(handle.index as usize) {
|
||||
if record.stamp == handle.stamp {
|
||||
if let Some(payload) = &record.payload {
|
||||
return Some(payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn borrow_mut(&mut self, handle: &Handle<T>) -> Option<&mut T> {
|
||||
let index = handle.index as usize;
|
||||
if index < self.records.len() {
|
||||
unsafe {
|
||||
// _unchecked here because we already checked index
|
||||
let record = self.records.get_unchecked_mut(index);
|
||||
if record.stamp == handle.stamp {
|
||||
if let Some(payload) = &mut record.payload {
|
||||
return Some(payload);
|
||||
}
|
||||
if let Some(record) = self.records.get_mut(handle.index as usize) {
|
||||
if record.stamp == handle.stamp {
|
||||
if let Some(payload) = &mut record.payload {
|
||||
return Some(payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn free(&mut self, handle: Handle<T>) {
|
||||
let index = handle.index as usize;
|
||||
if index < self.records.len() {
|
||||
@@ -126,22 +144,25 @@ impl<T> Pool<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.records.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn at_mut(&mut self, n: usize) -> Option<&mut T> {
|
||||
if n < self.records.len() {
|
||||
if let Some(payload) = &mut self.records[n].payload {
|
||||
if let Some(record) = self.records.get_mut(n) {
|
||||
if let Some(ref mut payload) = record.payload {
|
||||
return Some(payload);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn at(&self, n: usize) -> Option<&T> {
|
||||
if n < self.records.len() {
|
||||
if let Some(payload) = &self.records[n].payload {
|
||||
if let Some(record) = self.records.get(n) {
|
||||
if let Some(ref payload) = record.payload {
|
||||
return Some(payload);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user