├── .gitignore ├── Assets ├── Example.meta ├── Example │ ├── Materials.meta │ ├── Materials │ │ ├── Firework.mat │ │ ├── Firework.mat.meta │ │ ├── Material.mat │ │ ├── Material.mat.meta │ │ ├── No Name.mat │ │ ├── No Name.mat.meta │ │ ├── Skybox.mat │ │ ├── Skybox.mat.meta │ │ ├── Textures.meta │ │ ├── Textures │ │ │ ├── Blue.png │ │ │ ├── Blue.png.meta │ │ │ ├── Green.png │ │ │ ├── Green.png.meta │ │ │ ├── IR.png │ │ │ ├── IR.png.meta │ │ │ ├── Red.png │ │ │ ├── Red.png.meta │ │ │ ├── Teal.png │ │ │ ├── Teal.png.meta │ │ │ ├── UV.png │ │ │ ├── UV.png.meta │ │ │ ├── UV2.PNG │ │ │ ├── UV2.PNG.meta │ │ │ ├── UVCube.PNG │ │ │ ├── UVCube.PNG.meta │ │ │ ├── UVCubeIR.PNG │ │ │ ├── UVCubeIR.PNG.meta │ │ │ ├── UVCubeUV.PNG │ │ │ ├── UVCubeUV.PNG.meta │ │ │ ├── UVMAP.PNG │ │ │ └── UVMAP.PNG.meta │ │ ├── UV2.mat │ │ ├── UV2.mat.meta │ │ ├── UVCube.mat │ │ ├── UVCube.mat.meta │ │ ├── UVMAP.mat │ │ ├── UVMAP.mat.meta │ │ ├── relativity.mat │ │ ├── relativity.mat.meta │ │ ├── relativity2.mat │ │ └── relativity2.mat.meta │ ├── Models.meta │ ├── Models │ │ ├── cube.fbx │ │ ├── cube.fbx.meta │ │ ├── relativityTEXT.fbx │ │ ├── relativityTEXT.fbx.meta │ │ ├── relativitylogo.fbx │ │ ├── relativitylogo.fbx.meta │ │ ├── sphereTEx.fbx │ │ └── sphereTEx.fbx.meta │ ├── PrefabScripts.meta │ ├── PrefabScripts │ │ ├── Receiver2Script.cs │ │ ├── Receiver2Script.cs.meta │ │ ├── ReceiverScript.cs │ │ ├── ReceiverScript.cs.meta │ │ ├── SenderScript.cs │ │ └── SenderScript.cs.meta │ ├── Resources.meta │ ├── Resources │ │ ├── GameObjects.meta │ │ └── GameObjects │ │ │ ├── Firework.prefab │ │ │ ├── Firework.prefab.meta │ │ │ ├── InfoPanel.prefab │ │ │ ├── InfoPanel.prefab.meta │ │ │ ├── Moving Person.prefab │ │ │ ├── Moving Person.prefab.meta │ │ │ ├── Particle.prefab │ │ │ ├── Particle.prefab.meta │ │ │ ├── PlayerMesh.prefab │ │ │ ├── PlayerMesh.prefab.meta │ │ │ ├── Receiver.prefab │ │ │ ├── Receiver.prefab.meta │ │ │ ├── Sender.prefab │ │ │ └── Sender.prefab.meta │ ├── Scenes.meta │ ├── Scenes │ │ ├── displayLevel.unity │ │ └── displayLevel.unity.meta │ ├── Scripts.meta │ └── Scripts │ │ ├── InfoScript.cs │ │ ├── InfoScript.cs.meta │ │ ├── RelativisticParent.cs │ │ ├── RelativisticParent.cs.meta │ │ ├── Tags.cs │ │ └── Tags.cs.meta ├── OpenRelativity.meta └── OpenRelativity │ ├── Scripts.meta │ ├── Scripts │ ├── Firework.cs │ ├── Firework.cs.meta │ ├── GameState.cs │ ├── GameState.cs.meta │ ├── MovementScripts.cs │ ├── MovementScripts.cs.meta │ ├── ObjectMeshDensity.cs │ ├── ObjectMeshDensity.cs.meta │ ├── RelativisticObject.cs │ └── RelativisticObject.cs.meta │ ├── Shaders.meta │ └── Shaders │ ├── ColorCorrectionEffect.cs │ ├── ColorCorrectionEffect.cs.meta │ ├── ImageEffectBase.cs │ ├── ImageEffectBase.cs.meta │ ├── desaturateShader.shader │ ├── desaturateShader.shader.meta │ ├── relativity.shader │ ├── relativity.shader.meta │ ├── skybox.shader │ └── skybox.shader.meta ├── InputManager - OSXPS3.asset ├── InputManager - WindowsXBOX.asset ├── MITLicense.md ├── Packages └── manifest.json ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NavMeshLayers.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── PresetManager.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset └── UnityConnectSettings.asset └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | 6 | # Autogenerated VS/MD solution and project files 7 | *.csproj 8 | *.unityproj 9 | *.sln 10 | *.suo 11 | *.tmp 12 | *.user 13 | *.userprefs 14 | *.pidb 15 | *.booproj 16 | *.DS_Store 17 | 18 | # Unity3D generated meta files 19 | *.pidb.meta 20 | 21 | # Unity3D Generated File On Crash Reports 22 | sysinfo.txt -------------------------------------------------------------------------------- /Assets/Example.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0e2725e9152ce474b8a6bf6d8ec9662a 3 | folderAsset: yes 4 | timeCreated: 1456244262 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Example/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41532f9f562424c4b9d94185ea0e86a5 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Firework.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Firework.mat -------------------------------------------------------------------------------- /Assets/Example/Materials/Firework.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b61e70c7d4d299d40bc9155ce353c710 3 | timeCreated: 1456164927 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Material.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Material.mat -------------------------------------------------------------------------------- /Assets/Example/Materials/Material.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a1b859f7d8f9384ab526d28a0346012 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Materials/No Name.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/No Name.mat -------------------------------------------------------------------------------- /Assets/Example/Materials/No Name.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: af9a1c507c5d4484fa81558fef42124f 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Skybox.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Skybox.mat -------------------------------------------------------------------------------- /Assets/Example/Materials/Skybox.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 290ff36d29c1e9146be8ccd428f16595 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 01e4cc77674260742ac65dbdb2d65cc8 3 | folderAsset: yes 4 | timeCreated: 1456164077 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/Blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Textures/Blue.png -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/Blue.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 53075cb0a7669364d8083cc11407f117 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | textureType: -1 34 | buildTargetSettings: [] 35 | userData: 36 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/Green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Textures/Green.png -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/Green.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1bf62eb53145a6d48b84e2a2ce407a9b 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | textureType: -1 34 | buildTargetSettings: [] 35 | userData: 36 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/IR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Textures/IR.png -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/IR.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f021347a4c6e18748b2628309bab57cd 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | textureType: -1 34 | buildTargetSettings: [] 35 | userData: 36 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/Red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Textures/Red.png -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/Red.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5191354591dd00d47a22dc2ab917f507 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | textureType: -1 34 | buildTargetSettings: [] 35 | userData: 36 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/Teal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Textures/Teal.png -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/Teal.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ec001dfafb93de3419ba484ba6fac082 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | textureType: -1 34 | buildTargetSettings: [] 35 | userData: 36 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/UV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Textures/UV.png -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/UV.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b2161d4ce54bd5a449257182fc1bad2c 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | textureType: -1 34 | buildTargetSettings: [] 35 | userData: 36 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/UV2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Textures/UV2.PNG -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/UV2.PNG.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ff9623c6dfbfd74faf1d46a47c2d396 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | textureType: -1 34 | buildTargetSettings: [] 35 | userData: 36 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/UVCube.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Textures/UVCube.PNG -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/UVCube.PNG.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b737de5bd171aba448e3722f2fb1f355 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | textureType: -1 34 | buildTargetSettings: [] 35 | userData: 36 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/UVCubeIR.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Textures/UVCubeIR.PNG -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/UVCubeIR.PNG.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f27fe42b9399022438e84e04a0bf9f7d 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | textureType: -1 34 | buildTargetSettings: [] 35 | userData: 36 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/UVCubeUV.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Textures/UVCubeUV.PNG -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/UVCubeUV.PNG.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5fcb170f12a4b4844af24eefdf1ec1f3 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | textureType: -1 34 | buildTargetSettings: [] 35 | userData: 36 | -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/UVMAP.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/Textures/UVMAP.PNG -------------------------------------------------------------------------------- /Assets/Example/Materials/Textures/UVMAP.PNG.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: df79ea5e016e57f4486a948fc55197e1 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 4096 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | textureType: -1 34 | buildTargetSettings: [] 35 | userData: 36 | -------------------------------------------------------------------------------- /Assets/Example/Materials/UV2.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/UV2.mat -------------------------------------------------------------------------------- /Assets/Example/Materials/UV2.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a0eb7b90e06fb6440bebd7592c38257a 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Materials/UVCube.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/UVCube.mat -------------------------------------------------------------------------------- /Assets/Example/Materials/UVCube.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e14e91e6e6e3f1c4684f38000352beb3 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Materials/UVMAP.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/UVMAP.mat -------------------------------------------------------------------------------- /Assets/Example/Materials/UVMAP.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dec1e389cac1a8a4e91a946631d11f5f 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Materials/relativity.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/relativity.mat -------------------------------------------------------------------------------- /Assets/Example/Materials/relativity.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d0d6de19c8bd7e940a5116f4c5e66d5c 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Materials/relativity2.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Materials/relativity2.mat -------------------------------------------------------------------------------- /Assets/Example/Materials/relativity2.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1ff953ca540dd5a459545cdc90097ddd 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Models.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 952fa5693c14fe944b842bc68c649cb0 3 | folderAsset: yes 4 | timeCreated: 1456164064 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Example/Models/cube.fbx.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b4421849ad06e4b4284a9fce215ebb3a 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: Camera 7 | 100002: Cube 8 | 100004: //RootNode 9 | 100006: Lamp 10 | 400000: Camera 11 | 400002: Cube 12 | 400004: //RootNode 13 | 400006: Lamp 14 | 2300000: Cube 15 | 3300000: Cube 16 | 4300000: Cube 17 | 7400000: Default Take 18 | 9500000: //RootNode 19 | materials: 20 | importMaterials: 1 21 | materialName: 0 22 | materialSearch: 1 23 | animations: 24 | legacyGenerateAnimations: 4 25 | bakeSimulation: 0 26 | animationCompression: 1 27 | animationRotationError: .5 28 | animationPositionError: .5 29 | animationScaleError: .5 30 | animationWrapMode: 0 31 | clipAnimations: [] 32 | isReadable: 1 33 | meshes: 34 | lODScreenPercentages: [] 35 | globalScale: .5 36 | meshCompression: 0 37 | addColliders: 0 38 | swapUVChannels: 0 39 | generateSecondaryUV: 0 40 | useFileUnits: 1 41 | optimizeMeshForGPU: 1 42 | secondaryUVAngleDistortion: 8 43 | secondaryUVAreaDistortion: 15.000001 44 | secondaryUVHardAngle: 88 45 | secondaryUVPackMargin: 4 46 | tangentSpace: 47 | normalSmoothAngle: 60 48 | splitTangentsAcrossUV: 1 49 | normalImportMode: 0 50 | tangentImportMode: 1 51 | importAnimation: 1 52 | copyAvatar: 0 53 | humanDescription: 54 | human: [] 55 | skeleton: [] 56 | handles: [] 57 | armTwist: .5 58 | foreArmTwist: .5 59 | upperLegTwist: .5 60 | legTwist: .5 61 | armStretch: .0500000007 62 | legStretch: .0500000007 63 | feetSpacing: 0 64 | rootMotionBoneName: 65 | lastHumanDescriptionAvatarSource: {instanceID: 0} 66 | additionalBone: 1 67 | animationType: 2 68 | userData: 69 | -------------------------------------------------------------------------------- /Assets/Example/Models/relativityTEXT.fbx.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a291371c993734443a6bfaa27d872a91 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: //RootNode 7 | 400000: //RootNode 8 | 2300000: //RootNode 9 | 3300000: //RootNode 10 | 4300000: Text 11 | 7400000: Default Take 12 | 9500000: //RootNode 13 | materials: 14 | importMaterials: 1 15 | materialName: 0 16 | materialSearch: 1 17 | animations: 18 | legacyGenerateAnimations: 4 19 | bakeSimulation: 0 20 | animationCompression: 1 21 | animationRotationError: .5 22 | animationPositionError: .5 23 | animationScaleError: .5 24 | animationWrapMode: 0 25 | clipAnimations: [] 26 | isReadable: 1 27 | meshes: 28 | lODScreenPercentages: [] 29 | globalScale: .00999999978 30 | meshCompression: 0 31 | addColliders: 0 32 | swapUVChannels: 0 33 | generateSecondaryUV: 0 34 | useFileUnits: 1 35 | optimizeMeshForGPU: 1 36 | secondaryUVAngleDistortion: 8 37 | secondaryUVAreaDistortion: 15.000001 38 | secondaryUVHardAngle: 88 39 | secondaryUVPackMargin: 4 40 | tangentSpace: 41 | normalSmoothAngle: 60 42 | splitTangentsAcrossUV: 1 43 | normalImportMode: 0 44 | tangentImportMode: 1 45 | importAnimation: 1 46 | copyAvatar: 0 47 | humanDescription: 48 | human: [] 49 | skeleton: [] 50 | handles: [] 51 | armTwist: .5 52 | foreArmTwist: .5 53 | upperLegTwist: .5 54 | legTwist: .5 55 | armStretch: .0500000007 56 | legStretch: .0500000007 57 | feetSpacing: 0 58 | rootMotionBoneName: 59 | lastHumanDescriptionAvatarSource: {instanceID: 0} 60 | additionalBone: 1 61 | animationType: 2 62 | userData: 63 | -------------------------------------------------------------------------------- /Assets/Example/Models/relativitylogo.fbx.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f1451be7fc56abc4da66d32724fe208e 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: Camera 7 | 100002: Cube 8 | 100004: Lamp 9 | 100006: //RootNode 10 | 400000: Camera 11 | 400002: Cube 12 | 400004: Lamp 13 | 400006: //RootNode 14 | 2300000: Cube 15 | 2300002: //RootNode 16 | 3300000: Cube 17 | 3300002: //RootNode 18 | 4300000: Cube 19 | 7400000: Default Take 20 | 9500000: //RootNode 21 | materials: 22 | importMaterials: 1 23 | materialName: 0 24 | materialSearch: 1 25 | animations: 26 | legacyGenerateAnimations: 4 27 | bakeSimulation: 0 28 | animationCompression: 1 29 | animationRotationError: .5 30 | animationPositionError: .5 31 | animationScaleError: .5 32 | animationWrapMode: 0 33 | clipAnimations: [] 34 | isReadable: 1 35 | meshes: 36 | lODScreenPercentages: [] 37 | globalScale: .00999999978 38 | meshCompression: 0 39 | addColliders: 0 40 | swapUVChannels: 0 41 | generateSecondaryUV: 0 42 | useFileUnits: 1 43 | optimizeMeshForGPU: 1 44 | secondaryUVAngleDistortion: 8 45 | secondaryUVAreaDistortion: 15.000001 46 | secondaryUVHardAngle: 88 47 | secondaryUVPackMargin: 4 48 | tangentSpace: 49 | normalSmoothAngle: 60 50 | splitTangentsAcrossUV: 1 51 | normalImportMode: 0 52 | tangentImportMode: 1 53 | importAnimation: 1 54 | copyAvatar: 0 55 | humanDescription: 56 | human: [] 57 | skeleton: [] 58 | handles: [] 59 | armTwist: .5 60 | foreArmTwist: .5 61 | upperLegTwist: .5 62 | legTwist: .5 63 | armStretch: .0500000007 64 | legStretch: .0500000007 65 | feetSpacing: 0 66 | rootMotionBoneName: 67 | lastHumanDescriptionAvatarSource: {instanceID: 0} 68 | additionalBone: 1 69 | animationType: 2 70 | userData: 71 | -------------------------------------------------------------------------------- /Assets/Example/Models/sphereTEx.fbx.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d960366646406d94e8edaac8e2953fe7 3 | ModelImporter: 4 | serializedVersion: 15 5 | fileIDToRecycleName: 6 | 100000: Camera 7 | 100002: Lamp 8 | 100004: Sphere 9 | 100006: //RootNode 10 | 400000: Camera 11 | 400002: Lamp 12 | 400004: Sphere 13 | 400006: //RootNode 14 | 2300000: Sphere 15 | 3300000: Sphere 16 | 4300000: Sphere 17 | 7400000: Default Take 18 | 9500000: //RootNode 19 | materials: 20 | importMaterials: 1 21 | materialName: 0 22 | materialSearch: 1 23 | animations: 24 | legacyGenerateAnimations: 4 25 | bakeSimulation: 0 26 | animationCompression: 1 27 | animationRotationError: .5 28 | animationPositionError: .5 29 | animationScaleError: .5 30 | animationWrapMode: 0 31 | clipAnimations: [] 32 | isReadable: 1 33 | meshes: 34 | lODScreenPercentages: [] 35 | globalScale: 1 36 | meshCompression: 0 37 | addColliders: 0 38 | swapUVChannels: 0 39 | generateSecondaryUV: 0 40 | useFileUnits: 1 41 | optimizeMeshForGPU: 1 42 | secondaryUVAngleDistortion: 8 43 | secondaryUVAreaDistortion: 15.000001 44 | secondaryUVHardAngle: 88 45 | secondaryUVPackMargin: 4 46 | tangentSpace: 47 | normalSmoothAngle: 60 48 | splitTangentsAcrossUV: 1 49 | normalImportMode: 0 50 | tangentImportMode: 1 51 | importAnimation: 1 52 | copyAvatar: 0 53 | humanDescription: 54 | human: [] 55 | skeleton: [] 56 | handles: [] 57 | armTwist: .5 58 | foreArmTwist: .5 59 | upperLegTwist: .5 60 | legTwist: .5 61 | armStretch: .0500000007 62 | legStretch: .0500000007 63 | feetSpacing: 0 64 | rootMotionBoneName: 65 | lastHumanDescriptionAvatarSource: {instanceID: 0} 66 | additionalBone: 1 67 | animationType: 2 68 | userData: 69 | -------------------------------------------------------------------------------- /Assets/Example/PrefabScripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fdb61df02d4d86b44bcc682bafe402e3 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/PrefabScripts/Receiver2Script.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class Receiver2Script : MonoBehaviour { 5 | 6 | // Use this for initialization 7 | void Start () { 8 | 9 | } 10 | 11 | // Update is called once per frame 12 | void OnTriggerEnter(Collider collider) 13 | { 14 | //If an object crashes into us, set their death time so they know when to disappear. 15 | collider.gameObject.GetComponent().SetDeathTime(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Assets/Example/PrefabScripts/Receiver2Script.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ad0a8f4c21118441a84d662e23d6f1c 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Example/PrefabScripts/ReceiverScript.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class ReceiverScript : MonoBehaviour { 5 | 6 | //Store our partner's transform 7 | public Transform senderTransform; 8 | // Use this for initialization 9 | void Start() 10 | { 11 | //Look at our paired sender. 12 | this.transform.LookAt(senderTransform); 13 | } 14 | 15 | // Update is called once per frame 16 | void LateUpdate() 17 | { 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Assets/Example/PrefabScripts/ReceiverScript.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a36f815af6df68542a6691bd7fccc275 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Example/PrefabScripts/SenderScript.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class SenderScript : MonoBehaviour { 5 | 6 | //Store our partner's transform 7 | public Transform receiverTransform; 8 | //how long between character creation? 9 | public int launchTimer; 10 | //how much time has passed 11 | private float launchCounter; 12 | 13 | public string prefabName = "Moving Person"; 14 | //What's their speed? 15 | public float viwMax = 3; 16 | 17 | void Start() 18 | { 19 | //We let you set a public variable to determine the number of seconds between each launch of an object. 20 | //If that variable is unset, we make sure to put it at 3 here. 21 | if (launchTimer <= 0) 22 | { 23 | launchTimer = 3; 24 | } 25 | //Point to the associated receiver. 26 | if (receiverTransform != null) { 27 | this.transform.LookAt (receiverTransform); 28 | } 29 | //Take the minimum of the chosen viwMax, and the Game State's chosen Max Speed 30 | viwMax = Mathf.Min(viwMax,(float)GameObject.FindGameObjectWithTag(Tags.player).GetComponent().MaxSpeed); 31 | } 32 | 33 | // Update is called once per frame 34 | void Update() 35 | { //If we're not paused, increment the timer 36 | if (!GameObject.FindGameObjectWithTag(Tags.player).GetComponent().MovementFrozen) 37 | { 38 | launchCounter += Time.deltaTime; 39 | } 40 | //If it has been at least LaunchTimer seconds since we last fired an object 41 | if (launchCounter >= launchTimer) 42 | { 43 | //Reset the counter 44 | launchCounter = 0; 45 | //And instantiate a new object 46 | LaunchObject(); 47 | } 48 | } 49 | void LaunchObject() 50 | { 51 | //Instantiate a new Object (You can find this object in the GameObjects folder, it's a prefab. 52 | GameObject launchedObject = (GameObject)Instantiate(Resources.Load("GameObjects/"+prefabName, typeof(GameObject)), transform.position, this.transform.rotation); 53 | //Translate it to our center, and put it so that it's just touching the ground 54 | launchedObject.transform.Translate((new Vector3(0, launchedObject.GetComponent().mesh.bounds.extents.y, 0) )); 55 | //Make it a child of our transform. 56 | launchedObject.transform.parent = transform; 57 | //Determine if it has a Relativistic Object, Firework, or multiple RO's to set VIW on. 58 | RelativisticObject ro = launchedObject.GetComponent(); 59 | RelativisticObject [] ros = launchedObject.GetComponentsInChildren(); 60 | 61 | if (ro != null) 62 | { 63 | ro.viw = viwMax * this.transform.forward; 64 | //And let the object know when it was created, so that it knows when not to be seen by the player 65 | ro.SetStartTime(); 66 | } 67 | else if(ros.Length>0) 68 | { 69 | for(int i=0;i()!=null) 77 | { 78 | launchedObject.GetComponent().viw = viwMax * transform.forward; 79 | //And let the object know when it was created, so that it knows when not to be seen by the player 80 | launchedObject.GetComponent().SetStartTime(); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Assets/Example/PrefabScripts/SenderScript.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ef4f31d7c213b094ea80e5635ce54b16 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Example/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e9c0479af8073b94782677482a3808b5 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3eba299145ac1f142adf204a773ed20b 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/Firework.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Resources/GameObjects/Firework.prefab -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/Firework.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ad7bebf503d483b4bbf7e08b6220a3fa 3 | timeCreated: 1456164980 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/InfoPanel.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Resources/GameObjects/InfoPanel.prefab -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/InfoPanel.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 337cd66e92184d7469778c41d4664bb7 3 | timeCreated: 1456244771 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/Moving Person.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Resources/GameObjects/Moving Person.prefab -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/Moving Person.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a9d6292f960f15b449abaee6c8b3c449 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/Particle.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Resources/GameObjects/Particle.prefab -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/Particle.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da23da208a090994c80711657ec815b4 3 | timeCreated: 1456164982 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/PlayerMesh.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Resources/GameObjects/PlayerMesh.prefab -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/PlayerMesh.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 65bd5fb130602984eac594b0769e1c29 3 | timeCreated: 1456192803 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/Receiver.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Resources/GameObjects/Receiver.prefab -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/Receiver.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2b83784f21f1adf459e83222794fd6fb 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/Sender.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Resources/GameObjects/Sender.prefab -------------------------------------------------------------------------------- /Assets/Example/Resources/GameObjects/Sender.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1ce0a7626fcdd7949ae9fad09019025b 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 51dd65a0b17279d44829528a3a5ac729 3 | folderAsset: yes 4 | timeCreated: 1456164103 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Example/Scenes/displayLevel.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/Assets/Example/Scenes/displayLevel.unity -------------------------------------------------------------------------------- /Assets/Example/Scenes/displayLevel.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e6c3d01f4b4f6a34d94e744a9dc68e1e 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Example/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b417c0aa491ca5d4880fd8ba09eb1329 3 | folderAsset: yes 4 | timeCreated: 1456164036 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Example/Scripts/InfoScript.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | ///Written by user tyoc213 4 | public class InfoScript : MonoBehaviour { 5 | GameObject infoPanel; 6 | //Gamestate reference for quick access 7 | GameState state; 8 | // Use this for initialization 9 | void Start () { 10 | GameObject canvas = GameObject.Find ("Canvas"); 11 | if (canvas != null) { 12 | GameObject go = Resources.Load("GameObjects/InfoPanel"); 13 | if(go != null){ 14 | infoPanel = Instantiate(go); 15 | infoPanel.GetComponent().SetParent(canvas.GetComponent(), false); 16 | } 17 | } 18 | state = GetComponent(); 19 | } 20 | 21 | //just print out a bunch of information onto the screen. 22 | void Update(){ 23 | string msg = "Current C: " + state.SpeedOfLight 24 | + "\nIncrease/Decrease with N/M" 25 | + "\n\nCurrent Speed: " + state.PlayerVelocity 26 | + "\nMove with with WASD"; 27 | UnityEngine.UI.Text text = infoPanel.GetComponentInChildren (); 28 | text.text = msg; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Assets/Example/Scripts/InfoScript.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b93fcf56abe5e34b93aa951988edfb0 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Example/Scripts/RelativisticParent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using UnityEngine; 6 | 7 | public class RelativisticParent : MonoBehaviour { 8 | //Keep track of our own Mesh Filter 9 | private MeshFilter meshFilter; 10 | //Store this object's velocity here. 11 | public Vector3 viw; 12 | private GameState state; 13 | //When was this object created? use for moving objects 14 | private float startTime = 0; 15 | //When should we die? again, for moving objects 16 | private float deathTime = 0; 17 | 18 | // Get the start time of our object, so that we know where not to draw it 19 | public void SetStartTime() 20 | { 21 | startTime = (float) GameObject.FindGameObjectWithTag(Tags.player).GetComponent().TotalTimeWorld; 22 | } 23 | //Set the death time, so that we know at what point to destroy the object in the player's view point. 24 | public void SetDeathTime() 25 | { 26 | deathTime = (float)state.TotalTimeWorld; 27 | } 28 | //This is a function that just ensures we're slower than our maximum speed. The VIW that Unity sets SHOULD (it's creator-chosen) be smaller than the maximum speed. 29 | private void checkSpeed() 30 | { 31 | if (viw.magnitude > state.MaxSpeed-.01) 32 | { 33 | viw = viw.normalized * (float)(state.MaxSpeed-.01f); 34 | } 35 | } 36 | // Use this for initialization 37 | void Start() 38 | { 39 | if (GetComponent()) 40 | { 41 | GetComponent().enabled = false; 42 | } 43 | int vertCount = 0, triangleCount = 0; 44 | checkSpeed (); 45 | Matrix4x4 worldLocalMatrix = transform.worldToLocalMatrix; 46 | 47 | //This code combines the meshes of children of parent objects 48 | //This increases our FPS by a ton 49 | //Get an array of the meshfilters 50 | MeshFilter[] meshFilters = GetComponentsInChildren(); 51 | //Count submeshes 52 | int[] subMeshCount = new int[meshFilters.Length]; 53 | //Get all the meshrenderers 54 | MeshRenderer[] meshRenderers = GetComponentsInChildren(); 55 | //Length of our original array 56 | int meshFilterLength = meshFilters.Length; 57 | //And a counter 58 | int subMeshCounts = 0; 59 | 60 | //For every meshfilter, 61 | for (int y = 0; y < meshFilterLength; y++) 62 | { 63 | //If it's null, ignore it. 64 | if (meshFilters[y] == null) continue; 65 | if (meshFilters[y].sharedMesh == null) continue; 66 | //else add its vertices to the vertcount 67 | vertCount += meshFilters[y].sharedMesh.vertices.Length; 68 | //Add its triangles to the count 69 | triangleCount += meshFilters[y].sharedMesh.triangles.Length; 70 | //Add the number of submeshes to its spot in the array 71 | subMeshCount[y] = meshFilters[y].mesh.subMeshCount; 72 | //And add up the total number of submeshes 73 | subMeshCounts += meshFilters[y].mesh.subMeshCount; 74 | } 75 | // Get a temporary array of EVERY vertex 76 | Vector3[] tempVerts = new Vector3[vertCount]; 77 | //And make a triangle array for every submesh 78 | int[][] tempTriangles = new int[subMeshCounts][]; 79 | 80 | for (int u = 0; u < subMeshCounts; u++) 81 | { 82 | //Make every array the correct length of triangles 83 | tempTriangles[u] = new int[triangleCount]; 84 | } 85 | //Also grab our UV texture coordinates 86 | Vector2[] tempUVs = new Vector2[vertCount]; 87 | //And store a number of materials equal to the number of submeshes. 88 | Material[] tempMaterials = new Material[subMeshCounts]; 89 | 90 | int vertIndex = 0; 91 | Mesh MFs; 92 | int subMeshIndex = 0; 93 | //For all meshfilters 94 | for (int i = 0; i < meshFilterLength; i++) 95 | { 96 | //just doublecheck that the mesh isn't null 97 | MFs = meshFilters[i].sharedMesh; 98 | if (MFs == null) continue; 99 | 100 | //Otherwise, for all submeshes in the current mesh 101 | for (int q = 0; q < subMeshCount[i]; q++) 102 | { 103 | //grab its material 104 | tempMaterials[subMeshIndex] = meshRenderers[i].materials[q]; 105 | //Grab its triangles 106 | int[] tempSubTriangles = MFs.GetTriangles(q); 107 | //And put them into the submesh's triangle array 108 | for (int k = 0; k < tempSubTriangles.Length; k++) 109 | { 110 | tempTriangles[subMeshIndex][k] = tempSubTriangles[k] + vertIndex; 111 | } 112 | //Increment the submesh index 113 | subMeshIndex++; 114 | } 115 | Matrix4x4 cTrans = worldLocalMatrix * meshFilters[i].transform.localToWorldMatrix; 116 | //For all the vertices in the mesh 117 | for (int v = 0; v < MFs.vertices.Length; v++) 118 | { 119 | //Get the vertex and the UV coordinate 120 | tempVerts[vertIndex] = cTrans.MultiplyPoint3x4(MFs.vertices[v]); 121 | tempUVs[vertIndex] = MFs.uv[v]; 122 | vertIndex++; 123 | } 124 | //And delete that gameobject. 125 | meshFilters[i].gameObject.SetActive(false); 126 | } 127 | //Put it all together now. 128 | Mesh myMesh = new Mesh(); 129 | //Make the mesh have as many submeshes as you need 130 | myMesh.subMeshCount = subMeshCounts; 131 | //Set its vertices to tempverts 132 | myMesh.vertices = tempVerts; 133 | //start at the first submesh 134 | subMeshIndex = 0; 135 | //For every submesh in each meshfilter 136 | for (int l = 0; l < meshFilterLength; l++) 137 | { 138 | for (int g = 0; g < subMeshCount[l]; g++) 139 | { 140 | //Set a new submesh, using the triangle array and its submesh index (built in unity function) 141 | myMesh.SetTriangles(tempTriangles[subMeshIndex], subMeshIndex); 142 | //increment the submesh index 143 | subMeshIndex++; 144 | } 145 | } 146 | //Just shunt in the UV coordinates, we don't need to change them 147 | myMesh.uv = tempUVs; 148 | //THEN totally replace our object's mesh with this new, combined mesh 149 | GetComponent().mesh = myMesh; 150 | GetComponent().enabled = true; 151 | GetComponent().mesh.RecalculateNormals(); 152 | GetComponent().GetComponent().materials = tempMaterials; 153 | 154 | transform.gameObject.SetActive(true); 155 | //End section of combining meshes 156 | 157 | 158 | 159 | state = GameObject.FindGameObjectWithTag(Tags.player).GetComponent(); 160 | 161 | meshFilter = GetComponent(); 162 | 163 | MeshRenderer tempRenderer = GetComponent(); 164 | 165 | 166 | 167 | //Then the standard RelativisticObject startup 168 | if (tempRenderer.materials[0].mainTexture != null) 169 | { 170 | //So that we can set unique values to every moving object, we have to instantiate a material 171 | //It's the same as our old one, but now it's not connected to every other object with the same material 172 | Material quickSwapMaterial = Instantiate((tempRenderer as Renderer).materials[0]) as Material; 173 | //Then, set the value that we want 174 | quickSwapMaterial.SetFloat("_viw", 0); 175 | 176 | //And stick it back into our renderer. We'll do the SetVector thing every frame. 177 | tempRenderer.materials[0] = quickSwapMaterial; 178 | 179 | //set our start time and start position in the shader. 180 | tempRenderer.materials[0].SetFloat("_strtTime", (float)startTime); 181 | tempRenderer.materials[0].SetVector("_strtPos", new Vector4(transform.position.x, transform.position.y, transform.position.z, 0)); 182 | } 183 | 184 | //This code is a hack to ensure that frustrum culling does not take place 185 | //It changes the render bounds so that everything is contained within them 186 | Transform camTransform = Camera.main.transform; 187 | float distToCenter = (Camera.main.farClipPlane - Camera.main.nearClipPlane) / 2.0f; 188 | Vector3 center = camTransform.position + camTransform.forward * distToCenter; 189 | float extremeBound = 500000.0f; 190 | meshFilter.sharedMesh.bounds = new Bounds(center, Vector3.one * extremeBound); 191 | 192 | 193 | if (GetComponent()) 194 | { 195 | GetComponent().enabled = true; 196 | } 197 | } 198 | 199 | // Update is called once per frame 200 | void Update() 201 | { 202 | 203 | 204 | //Grab our renderer. 205 | MeshRenderer tempRenderer = GetComponent(); 206 | 207 | if (meshFilter != null && !state.MovementFrozen) 208 | { 209 | 210 | //Send our object's v/c (Velocity over the Speed of Light) to the shader 211 | if (tempRenderer != null) 212 | { 213 | Vector3 tempViw = viw / (float)state.SpeedOfLight; 214 | tempRenderer.materials[0].SetVector("_viw", new Vector4(tempViw.x, tempViw.y, tempViw.z, 0)); 215 | } 216 | 217 | //As long as our object is actually alive, perform these calculations 218 | if (transform!=null && deathTime != 0) 219 | { 220 | //Here I take the angle that the player's velocity vector makes with the z axis 221 | float rotationAroundZ = 57.2957795f * Mathf.Acos(Vector3.Dot(state.PlayerVelocityVector, Vector3.forward) / state.PlayerVelocityVector.magnitude); 222 | 223 | if (state.PlayerVelocityVector.sqrMagnitude == 0) 224 | { 225 | rotationAroundZ = 0; 226 | } 227 | 228 | //Now we turn that rotation into a quaternion 229 | 230 | Quaternion rotateZ = Quaternion.AngleAxis(-rotationAroundZ, Vector3.Cross(state.PlayerVelocityVector,Vector3.forward)); 231 | //****************************************************************** 232 | 233 | //Place the vertex to be changed in a new Vector3 234 | Vector3 riw = new Vector3(transform.position.x, transform.position.y, transform.position.z); 235 | riw -= state.playerTransform.position; 236 | 237 | 238 | //And we rotate our point that much to make it as if our magnitude of velocity is in the Z direction 239 | riw = rotateZ * riw; 240 | 241 | 242 | //Here begins the original code, made by the guys behind the Relativity game 243 | /**************************** 244 | * Start Part 6 Bullet 1 245 | 246 | */ 247 | 248 | //Rotate that velocity! 249 | Vector3 storedViw = rotateZ * viw; 250 | 251 | float c = -Vector3.Dot(riw, riw); //first get position squared (position doted with position) 252 | 253 | float b = -(2 * Vector3.Dot(riw, storedViw)); //next get position doted with velocity, should be only in the Z direction 254 | 255 | float a = (float)state.SpeedOfLightSqrd - Vector3.Dot(storedViw, storedViw); 256 | 257 | /**************************** 258 | * Start Part 6 Bullet 2 259 | * **************************/ 260 | 261 | float tisw = (float)(((-b - (Math.Sqrt((b * b) - 4f * a * c))) / (2f * a))); 262 | //If we're past our death time (in the player's view, as seen by tisw) 263 | if (state.TotalTimeWorld + tisw > deathTime) 264 | { 265 | Destroy(this.gameObject); 266 | } 267 | 268 | } 269 | 270 | //make our rigidbody's velocity viw 271 | if (GetComponent()!=null) 272 | { 273 | 274 | if (!double.IsNaN((double)state.SqrtOneMinusVSquaredCWDividedByCSquared) && (float)state.SqrtOneMinusVSquaredCWDividedByCSquared != 0) 275 | { 276 | Vector3 tempViw = viw; 277 | //ASK RYAN WHY THESE WERE DIVIDED BY THIS 278 | tempViw.x /= (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 279 | tempViw.y /= (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 280 | tempViw.z /= (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 281 | 282 | GetComponent().velocity = tempViw; 283 | } 284 | 285 | 286 | } 287 | } 288 | 289 | 290 | } 291 | 292 | 293 | } -------------------------------------------------------------------------------- /Assets/Example/Scripts/RelativisticParent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1b445c33217e1d6448753fc6615f7063 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Example/Scripts/Tags.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class Tags 5 | { 6 | public const string player = "Player"; 7 | public const string playerMesh = "Playermesh"; 8 | } 9 | -------------------------------------------------------------------------------- /Assets/Example/Scripts/Tags.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eb33d307f8851694f84592d4c44ca548 3 | timeCreated: 1429569870 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/OpenRelativity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f611ded292d97024093ecfaa0562f2dc 3 | folderAsset: yes 4 | timeCreated: 1456244277 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cad0d2074f6be014ebea25d1e826651b 3 | folderAsset: yes 4 | timeCreated: 1456244285 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Scripts/Firework.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using UnityEngine; 6 | public class Firework : MonoBehaviour 7 | { 8 | public const float RAD_2_DEG = 57.2957795f; 9 | //Keep track of our own Mesh Filter 10 | private MeshFilter meshFilter; 11 | //Store our raw vertices in this variable, so that we can refer to them later 12 | private Vector3[] rawVerts; 13 | //Store this object's velocity here. 14 | public Vector3 viw; 15 | //Keep track of Game State so that we can reference it quickly 16 | public GameState state; 17 | //When was this object created? use for moving objects 18 | private float startTime = 0; 19 | //When should we die? again, for moving objects 20 | private float deathTime = 0; 21 | 22 | //FIREWORK VARIABLES 23 | public float count = 10; 24 | public float startTimer = 4; 25 | public bool isParticle = false; 26 | public float particleSpeed = 2; 27 | 28 | float timer=0; 29 | 30 | //This is in case you implement memory pools for generated objects. Whenever they are re enabled they should activate again 31 | void OnEnable() 32 | { 33 | timer = startTimer; 34 | ResetDeathTime(); 35 | } 36 | //Grab the gamestate and keep it safe 37 | void Awake() 38 | { 39 | //Get the player's GameState, use it later for general information 40 | state = GameObject.FindGameObjectWithTag(Tags.player).GetComponent(); 41 | } 42 | 43 | // Get the start time of our object, so that we know where not to draw it 44 | //Turn off the mesh renderer to avoid transparency problems 45 | public void SetStartTime() 46 | { 47 | startTime = (float)state.TotalTimeWorld; 48 | GetComponent().enabled = false; 49 | //start my countdown 50 | timer = startTimer; 51 | } 52 | //Set the death time, so that we know at what point to destroy the object in the player's view point. 53 | 54 | public void Start() 55 | { 56 | checkSpeed(); 57 | //Get the meshfilter 58 | meshFilter = GetComponent(); 59 | //Also get the meshrenderer so that we can give it a unique material 60 | MeshRenderer tempRenderer = GetComponent(); 61 | //If we have a MeshRenderer on our object 62 | if (tempRenderer != null) 63 | { 64 | //And if we have a texture on our material 65 | if (tempRenderer.materials[0].mainTexture != null) 66 | { 67 | //So that we can set unique values to every moving object, we have to instantiate a material 68 | //It's the same as our old one, but now it's not connected to every other object with the same material 69 | Material quickSwapMaterial = Instantiate((tempRenderer as Renderer).materials[0]) as Material; 70 | //Then, set the value that we want 71 | //And stick it back into our renderer. We'll do the SetVector thing every frame. 72 | tempRenderer.materials[0] = quickSwapMaterial; 73 | tempRenderer.materials[0].SetFloat("_strtTime", (float)startTime); 74 | tempRenderer.materials[0].SetVector("_strtPos", new Vector4(transform.position.x, transform.position.y, transform.position.z, 0)); 75 | } 76 | } 77 | //Get the vertices of our mesh 78 | if (meshFilter != null) 79 | { 80 | rawVerts = meshFilter.mesh.vertices; 81 | } 82 | else 83 | rawVerts = null; 84 | 85 | 86 | //This code is a hack to ensure that frustrum culling does not take place 87 | //It changes the render bounds so that everything is contained within them 88 | //At high speeds the Lorenz contraction means that some objects not normally in the view frame are actually visible 89 | //If we did frustrum culling, these objects would be ignored (because we cull BEFORE running the shader, which does the lorenz contraction) 90 | Transform camTransform = Camera.main.transform; 91 | float distToCenter = (Camera.main.farClipPlane + Camera.main.nearClipPlane) / 2.0f; 92 | Vector3 center = camTransform.position + camTransform.forward * distToCenter; 93 | float extremeBound = 500000.0f; 94 | meshFilter.sharedMesh.bounds = new Bounds(center, Vector3.one * extremeBound); 95 | } 96 | //If you reenable the object, it will destroy itself unless you reset the death time 97 | void ResetDeathTime() 98 | { 99 | deathTime = 0; 100 | } 101 | //Set our death time. This tells the object when to die (it's not where it should be due to runtime effect) 102 | public void SetDeathTime() 103 | { 104 | //If we're a firework not a particle, explode into particles! 105 | if (!isParticle) 106 | { 107 | //float slerp = 1.0f / count; 108 | //Get a spacing for the generated particles 109 | float spacing = (float)(360) / count; 110 | //Roll around a sphere, and send off a bunch of particles. Add judder to ensure it looks naturally not uniform 111 | for (int j = 0; j < count*2; j++) 112 | { 113 | for (int i = 0; i < count; i++) 114 | { 115 | float judder = UnityEngine.Random.Range(-.25f, .25f); 116 | float judderTwo = UnityEngine.Random.Range(-.25f, .25f); 117 | EmitParticle((j+ judderTwo) /2.0f*spacing,(i+ judder) * spacing); 118 | } 119 | } 120 | } 121 | //and, set the death time 122 | deathTime = (float)state.TotalTimeWorld; 123 | } 124 | //Standard update, taken out of Relativistic Object 125 | public void Update() 126 | { 127 | //Grab our renderer. 128 | MeshRenderer tempRenderer = GetComponent(); 129 | 130 | if (meshFilter != null && !state.MovementFrozen) 131 | { 132 | #region meshDensity 133 | //This is where I'm going to change our mesh density. 134 | //I'll take the model, and pass MeshDensity the mesh and unchanged vertices 135 | //If it comes back as having changed something, I'll edit the mesh. 136 | 137 | ObjectMeshDensity density = GetComponent(); 138 | 139 | if (density != null) 140 | { 141 | 142 | //Only run MeshDensity if the mesh needs to change, and if it's passed a threshold distance. 143 | if (rawVerts != null && density.change != null) 144 | { 145 | //This checks if we're within our large range, first mesh density circle 146 | //If we're within a distance of 40, split this mesh 147 | if (density.state == false && RecursiveTransform(rawVerts[0], meshFilter.transform).magnitude < 21000) 148 | { 149 | if (density.ReturnVerts(meshFilter.mesh, true)) 150 | { 151 | rawVerts = new Vector3[meshFilter.mesh.vertices.Length]; 152 | System.Array.Copy(meshFilter.mesh.vertices, rawVerts, meshFilter.mesh.vertices.Length); 153 | 154 | } 155 | } 156 | 157 | //If the object leaves our wide range, revert mesh to original state 158 | else if (density.state == true && RecursiveTransform(rawVerts[0], meshFilter.transform).magnitude > 21000) 159 | { 160 | if (density.ReturnVerts(meshFilter.mesh, false)) 161 | { 162 | rawVerts = new Vector3[meshFilter.mesh.vertices.Length]; 163 | System.Array.Copy(meshFilter.mesh.vertices, rawVerts, meshFilter.mesh.vertices.Length); 164 | } 165 | } 166 | 167 | } 168 | } 169 | #endregion 170 | 171 | 172 | //Send our object's v/c (Velocity over the Speed of Light) to the shader 173 | if (tempRenderer != null) 174 | { 175 | Vector3 tempViw = viw / (float)state.SpeedOfLight; 176 | tempRenderer.materials[0].SetVector("_viw", new Vector4(tempViw.x, tempViw.y, tempViw.z, 0)); 177 | } 178 | 179 | //As long as our object is actually alive, perform these calculations 180 | if (transform != null)// && deathTime != 0) 181 | { 182 | //Here I take the angle that the player's velocity vector makes with the z axis 183 | float rotationAroundZ = RAD_2_DEG * Mathf.Acos(Vector3.Dot(state.PlayerVelocityVector, Vector3.forward) / state.PlayerVelocityVector.magnitude); 184 | 185 | if (state.PlayerVelocityVector.sqrMagnitude == 0) 186 | { 187 | rotationAroundZ = 0; 188 | } 189 | 190 | //Now we turn that rotation into a quaternion 191 | 192 | Quaternion rotateZ = Quaternion.AngleAxis(-rotationAroundZ, Vector3.Cross(state.PlayerVelocityVector, Vector3.forward)); 193 | //****************************************************************** 194 | 195 | //Place the vertex to be changed in a new Vector3 196 | Vector3 riw = new Vector3(transform.position.x, transform.position.y, transform.position.z); 197 | riw -= state.playerTransform.position; 198 | 199 | 200 | //And we rotate our point that much to make it as if our magnitude of velocity is in the Z direction 201 | riw = rotateZ * riw; 202 | 203 | 204 | //Here begins the original code, made by the guys behind the Relativity game 205 | /**************************** 206 | * Start Part 6 Bullet 1 207 | 208 | */ 209 | 210 | //Rotate that velocity! 211 | Vector3 storedViw = rotateZ * viw; 212 | 213 | float c = -Vector3.Dot(riw, riw); //first get position squared (position doted with position) 214 | 215 | float b = -(2 * Vector3.Dot(riw, storedViw)); //next get position doted with velocity, should be only in the Z direction 216 | 217 | float a = (float)state.SpeedOfLightSqrd - Vector3.Dot(storedViw, storedViw); 218 | 219 | /**************************** 220 | * Start Part 6 Bullet 2 221 | * **************************/ 222 | 223 | float tisw = (float)(((-b - (Math.Sqrt((b * b) - 4f * a * c))) / (2f * a))); 224 | //If we're past our death time (in the player's view, as seen by tisw) 225 | if (state.TotalTimeWorld + tisw > deathTime && deathTime !=0) 226 | { 227 | KillObject(); 228 | } 229 | if (state.TotalTimeWorld +tisw >startTime &&!tempRenderer.enabled) 230 | { 231 | 232 | tempRenderer.enabled = true; 233 | } 234 | 235 | } 236 | 237 | //make our rigidbody's velocity the same as viw 238 | if (GetComponent () != null && !isParticle) { 239 | 240 | if (!double.IsNaN ((double)state.SqrtOneMinusVSquaredCWDividedByCSquared) && (float)state.SqrtOneMinusVSquaredCWDividedByCSquared != 0) { 241 | Vector3 tempViw = viw; 242 | tempViw.x /= (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 243 | tempViw.y /= (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 244 | tempViw.z /= (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 245 | 246 | GetComponent ().velocity = tempViw; 247 | } 248 | 249 | 250 | } else if (isParticle) { 251 | Vector3 tempViw = viw; 252 | tempViw.x /= (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 253 | tempViw.y /= (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 254 | tempViw.z /= (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 255 | transform.position = transform.position + tempViw * Time.deltaTime; 256 | } 257 | } 258 | //If nothing is null, then set the object to standstill, but make sure its rigidbody actually has a velocity. 259 | else if (meshFilter != null && tempRenderer != null && GetComponent() != null) 260 | { 261 | GetComponent().velocity = Vector3.zero; 262 | } 263 | 264 | //This time transformation goes from world time to this objects personal time 265 | timer -= (float)(state.DeltaTimeWorld * (Math.Sqrt(1 - (viw.sqrMagnitude) / state.SpeedOfLightSqrd))); 266 | //If we've passed the time to explode, blow it up 267 | if (timer <= 0) 268 | { 269 | SetDeathTime(); 270 | 271 | timer = float.MaxValue; 272 | } 273 | } 274 | //Actually destroy the object 275 | public void KillObject() 276 | { 277 | GameObject.Destroy(gameObject); 278 | } 279 | 280 | public Vector3 RecursiveTransform(Vector3 pt, Transform trans) 281 | { 282 | //Basically, this will transform the point until it has no more parent transforms. 283 | Vector3 pt1 = Vector3.zero; 284 | //If we have a parent transform, run this function again 285 | if (trans.parent != null) 286 | { 287 | pt = RecursiveTransform(pt1, trans.parent); 288 | 289 | return pt; 290 | } 291 | else 292 | { 293 | pt1 = trans.TransformPoint(pt); 294 | return pt1; 295 | } 296 | } 297 | 298 | //This is a function that just ensures we're slower than our maximum speed. The VIW that Unity sets SHOULD (it's creator-chosen) be smaller than the maximum speed. 299 | private void checkSpeed() 300 | { 301 | if (viw.magnitude > state.MaxSpeed - .01) 302 | { 303 | viw = viw.normalized * (float)(state.MaxSpeed - .01f); 304 | } 305 | } 306 | //Launch a single particle, see SetDeathTime above for its use 307 | public void EmitParticle(float gamma,float theta) 308 | { 309 | //rotate the direction down by gamma, around by theta 310 | Vector3 direction = Quaternion.AngleAxis(theta, transform.up) * Quaternion.AngleAxis(gamma,transform.right)*transform.up; 311 | GameObject launchedObject; 312 | //Instantiate a new Object (You can find this object in the GameObjects folder, it's a prefab. 313 | launchedObject = (GameObject)Instantiate(Resources.Load("GameObjects/Particle", typeof(GameObject)), transform.position, this.transform.rotation); 314 | 315 | //Translate it to our center, and put it so that it's just touching the ground 316 | launchedObject.transform.Translate(Vector3.zero); 317 | //Make it a child of our transform. 318 | launchedObject.transform.parent = transform.parent; 319 | launchedObject.transform.position = transform.position; 320 | launchedObject.GetComponent().isParticle = true; 321 | //Their velocity should be in the direction we're facing, at viwMax magnitude 322 | launchedObject.GetComponent().viw = particleSpeed * direction; 323 | //And let the object know when it was created, so that it knows when not to be seen by the player 324 | launchedObject.GetComponent().SetStartTime(); 325 | 326 | } 327 | 328 | 329 | 330 | } 331 | 332 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Scripts/Firework.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b4f0f6c8adade6498c97ffb02b89252 3 | timeCreated: 1456164245 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Scripts/GameState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Text; 4 | using UnityEngine; 5 | 6 | //using Microsoft.Xna.Framework; 7 | //using Microsoft.Xna.Framework.Audio; 8 | //using Microsoft.Xna.Framework.Content; 9 | //using Microsoft.Xna.Framework.GamerServices; 10 | //using Microsoft.Xna.Framework.Graphics; 11 | //using Microsoft.Xna.Framework.Input; 12 | //using Microsoft.Xna.Framework.Net; 13 | //using Microsoft.Xna.Framework.Storage; 14 | 15 | 16 | public class GameState : MonoBehaviour 17 | { 18 | #region Member Variables 19 | 20 | private System.IO.TextWriter stateStream; 21 | 22 | //Player orientation 23 | private Quaternion orientation = Quaternion.identity; 24 | //world rotation so that we can transform between the two 25 | private Matrix4x4 worldRotation; 26 | //Player's velocity in vector format 27 | private Vector3 playerVelocityVector; 28 | 29 | //grab the player's transform so that we can use it 30 | public Transform playerTransform; 31 | //If we've paused the game 32 | private bool movementFrozen = false; 33 | //player Velocity as a scalar magnitude 34 | public double playerVelocity; 35 | //time passed since last frame in the world frame 36 | private double deltaTimeWorld; 37 | //time passed since last frame in the player frame 38 | private double deltaTimePlayer; 39 | //total time passed in the player frame 40 | private double totalTimePlayer; 41 | //total time passed in the world frame 42 | private double totalTimeWorld; 43 | //speed of light 44 | private double c = 200; 45 | //Speed of light that is affected by the Unity editor 46 | public double totalC = 200; 47 | //max speed the player can achieve (starting value accessible from Unity Editor) 48 | public double maxPlayerSpeed; 49 | //max speed, for game use, not accessible from Unity Editor 50 | private double maxSpeed; 51 | //speed of light squared, kept for easy access in many calculations 52 | private double cSqrd; 53 | 54 | //Use this to determine the state of the color shader. If it's True, all you'll see is the lorenz transform. 55 | private bool shaderOff = false; 56 | 57 | //Did we hit the menu key? 58 | public bool menuKeyDown = false; 59 | //Did we hit the shader key? 60 | public bool shaderKeyDown = false; 61 | 62 | 63 | //This is a value that gets used in many calculations, so we calculate it each frame 64 | private double sqrtOneMinusVSquaredCWDividedByCSquared; 65 | //Player rotation and change in rotation since last frame 66 | public Vector3 playerRotation = new Vector3(0, 0, 0); 67 | public Vector3 deltaRotation = new Vector3(0, 0, 0); 68 | public double pctOfSpdUsing = 0; // Percent of velocity you are using 69 | 70 | 71 | 72 | #endregion 73 | 74 | #region Properties 75 | 76 | public float finalMaxSpeed = .99f; 77 | public bool MovementFrozen { get { return movementFrozen; } set { movementFrozen = value; } } 78 | 79 | public Matrix4x4 WorldRotation { get { return worldRotation; } } 80 | public Quaternion Orientation { get { return orientation; } } 81 | public Vector3 PlayerVelocityVector { get { return playerVelocityVector; } set { playerVelocityVector = value; } } 82 | 83 | public double PctOfSpdUsing { get { return pctOfSpdUsing; } set { pctOfSpdUsing = value; } } 84 | public double PlayerVelocity { get { return playerVelocity; } } 85 | public double SqrtOneMinusVSquaredCWDividedByCSquared { get { return sqrtOneMinusVSquaredCWDividedByCSquared; } } 86 | public double DeltaTimeWorld { get { return deltaTimeWorld; } } 87 | public double DeltaTimePlayer { get { return deltaTimePlayer; } } 88 | public double TotalTimePlayer { get { return totalTimePlayer; } } 89 | public double TotalTimeWorld { get { return totalTimeWorld; } } 90 | public double SpeedOfLight { get { return c; } set { c = value; cSqrd = value * value; } } 91 | public double SpeedOfLightSqrd { get { return cSqrd; } } 92 | 93 | public bool keyHit = false; 94 | public double MaxSpeed { get { return maxSpeed; } set { maxSpeed = value; } } 95 | #endregion 96 | 97 | #region consts 98 | private const float ORB_SPEED_INC = 0.05f; 99 | private const float ORB_DECEL_RATE = 0.6f; 100 | private const float ORB_SPEED_DUR = 2f; 101 | private const float MAX_SPEED = 20.00f; 102 | public const float NORM_PERCENT_SPEED = .99f; 103 | public const int splitDistance = 21000; 104 | #endregion 105 | 106 | 107 | public void Awake() 108 | { 109 | //Initialize the player's speed to zero 110 | playerVelocityVector = Vector3.zero; 111 | playerVelocity = 0; 112 | //Set our constants 113 | MaxSpeed = MAX_SPEED; 114 | pctOfSpdUsing = NORM_PERCENT_SPEED; 115 | 116 | c = totalC; 117 | cSqrd = c*c; 118 | //And ensure that the game starts/ 119 | movementFrozen = false; 120 | 121 | } 122 | public void reset() 123 | { 124 | //Reset everything not level-based 125 | playerRotation.x = 0; 126 | playerRotation.y = 0; 127 | playerRotation.z = 0; 128 | pctOfSpdUsing = 0; 129 | } 130 | //Call this function to pause and unpause the game 131 | public void ChangeState() 132 | { 133 | if (movementFrozen) 134 | { 135 | //When we unpause, lock the cursor and hide it so that it doesn't get in the way 136 | movementFrozen = false; 137 | Cursor.visible = false; 138 | Cursor.lockState = CursorLockMode.Locked; 139 | } 140 | else 141 | { 142 | //When we pause, set our velocity to zero, show the cursor and unlock it. 143 | GameObject.FindGameObjectWithTag(Tags.playerMesh).GetComponent().velocity = Vector3.zero; 144 | movementFrozen = true; 145 | Cursor.visible = true; 146 | Cursor.lockState = CursorLockMode.None; 147 | } 148 | 149 | } 150 | //We set this in late update because of timing issues with collisions 151 | public void LateUpdate() 152 | { 153 | //Set the pause code in here so that our other objects can access it. 154 | if (Input.GetAxis("Menu Key") > 0 && !menuKeyDown) 155 | { 156 | menuKeyDown = true; 157 | ChangeState(); 158 | } 159 | //set up our buttonUp function 160 | else if (!(Input.GetAxis("Menu Key") > 0)) 161 | { 162 | menuKeyDown = false; 163 | } 164 | //Set our button code for the shader on/off button 165 | if (Input.GetAxis("Shader") > 0 && !shaderKeyDown) 166 | { 167 | if(shaderOff) 168 | shaderOff = false; 169 | else 170 | shaderOff = true; 171 | 172 | shaderKeyDown = true; 173 | } 174 | //set up our buttonUp function 175 | else if (!(Input.GetAxis("Shader") > 0)) 176 | { 177 | shaderKeyDown = false; 178 | } 179 | 180 | //If we're not paused, update everything 181 | if (!movementFrozen) 182 | { 183 | //Put our player position into the shader so that it can read it. 184 | Shader.SetGlobalVector("_playerOffset", new Vector4(playerTransform.position.x, playerTransform.position.y, playerTransform.position.z, 0)); 185 | 186 | 187 | //if we reached max speed, forward or backwards, keep at max speed 188 | 189 | if (playerVelocityVector.magnitude >= (float)MaxSpeed-.01f) 190 | { 191 | playerVelocityVector = playerVelocityVector.normalized * ((float)MaxSpeed-.01f); 192 | } 193 | 194 | //update our player velocity 195 | playerVelocity = playerVelocityVector.magnitude; 196 | 197 | 198 | //During colorshift on/off, during the last level we don't want to have the funky 199 | //colors changing so they can apperciate the other effects 200 | if (shaderOff) 201 | { 202 | Shader.SetGlobalFloat("_colorShift", (float)0.0); 203 | } 204 | else 205 | { 206 | Shader.SetGlobalFloat("_colorShift", (float)1); 207 | } 208 | 209 | //Send v/c to shader 210 | Shader.SetGlobalVector("_vpc", new Vector4(-playerVelocityVector.x, -playerVelocityVector.y, -playerVelocityVector.z, 0) / (float)c); 211 | //Send world time to shader 212 | Shader.SetGlobalFloat("_wrldTime", (float)TotalTimeWorld); 213 | 214 | /****************************** 215 | * PART TWO OF ALGORITHM 216 | * THE NEXT 4 LINES OF CODE FIND 217 | * THE TIME PASSED IN WORLD FRAME 218 | * ****************************/ 219 | //find this constant 220 | sqrtOneMinusVSquaredCWDividedByCSquared = (double)Math.Sqrt(1 - (playerVelocity * playerVelocity) / cSqrd); 221 | 222 | //Set by Unity, time since last update 223 | deltaTimePlayer = (double)Time.deltaTime; 224 | //Get the total time passed of the player and world for display purposes 225 | if (keyHit) 226 | { 227 | totalTimePlayer += deltaTimePlayer; 228 | if (!double.IsNaN(sqrtOneMinusVSquaredCWDividedByCSquared)) 229 | { 230 | //Get the delta time passed for the world, changed by relativistic effects 231 | deltaTimeWorld = deltaTimePlayer / sqrtOneMinusVSquaredCWDividedByCSquared; 232 | //and get the total time passed in the world 233 | totalTimeWorld += deltaTimeWorld; 234 | } 235 | } 236 | 237 | //Set our rigidbody's velocity 238 | if (!double.IsNaN(deltaTimePlayer) && !double.IsNaN(sqrtOneMinusVSquaredCWDividedByCSquared)) 239 | { 240 | GameObject.FindGameObjectWithTag(Tags.playerMesh).GetComponent().velocity = -1*(playerVelocityVector / (float)sqrtOneMinusVSquaredCWDividedByCSquared); 241 | } 242 | //But if either of those two constants is null due to a zero error, that means our velocity is zero anyways. 243 | else 244 | { 245 | GameObject.FindGameObjectWithTag(Tags.playerMesh).GetComponent().velocity = Vector3.zero; 246 | } 247 | /***************************** 248 | * PART 3 OF ALGORITHM 249 | * FIND THE ROTATION MATRIX 250 | * AND CHANGE THE PLAYERS VELOCITY 251 | * BY THIS ROTATION MATRIX 252 | * ***************************/ 253 | 254 | 255 | //Find the turn angle 256 | //Steering constant angular velocity in the player frame 257 | //Rotate around the y-axis 258 | 259 | orientation = Quaternion.AngleAxis(playerRotation.y, Vector3.up) * Quaternion.AngleAxis(playerRotation.x, Vector3.right); 260 | Quaternion WorldOrientation = Quaternion.Inverse(orientation); 261 | Normalize(orientation); 262 | worldRotation = CreateFromQuaternion(WorldOrientation); 263 | 264 | //Add up our rotation so that we know where the character (NOT CAMERA) should be facing 265 | playerRotation += deltaRotation; 266 | 267 | 268 | } 269 | } 270 | #region Matrix/Quat math 271 | //They are functions that XNA had but Unity doesn't, so I had to make them myself 272 | 273 | //This function takes in a quaternion and creates a rotation matrix from it 274 | public Matrix4x4 CreateFromQuaternion(Quaternion q) 275 | { 276 | double w = q.w; 277 | double x = q.x; 278 | double y = q.y; 279 | double z = q.z; 280 | 281 | double wSqrd = w * w; 282 | double xSqrd = x * x; 283 | double ySqrd = y * y; 284 | double zSqrd = z * z; 285 | 286 | Matrix4x4 matrix; 287 | matrix.m00 = (float)(wSqrd + xSqrd - ySqrd - zSqrd); 288 | matrix.m01 = (float)(2 * x * y - 2 * w * z); 289 | matrix.m02 = (float)(2 * x * z + 2 * w * y); 290 | matrix.m03 = (float)0; 291 | matrix.m10 = (float)(2 * x * y + 2 * w * z); 292 | matrix.m11 = (float)(wSqrd - xSqrd + ySqrd - zSqrd); 293 | matrix.m12 = (float)(2 * y * z + 2 * w * x); 294 | matrix.m13 = (float)0; 295 | matrix.m20 = (float)(2 * x * z - 2 * w * y); 296 | matrix.m21 = (float)(2 * y * z - 2 * w * x); 297 | matrix.m22 = (float)(wSqrd - xSqrd - ySqrd + zSqrd); 298 | matrix.m23 = 0; 299 | matrix.m30 = 0; 300 | matrix.m31 = 0; 301 | matrix.m32 = 0; 302 | matrix.m33 = 1; 303 | return matrix; 304 | } 305 | 306 | //Normalize the given quaternion so that its magnitude is one. 307 | public Quaternion Normalize(Quaternion quat) 308 | { 309 | Quaternion q = quat; 310 | 311 | double magnitudeSqr = q.w * q.w + q.x * q.x + q.y * q.y + q.z * q.z; 312 | if (magnitudeSqr != 1) 313 | { 314 | double magnitude = (double)Math.Sqrt(magnitudeSqr); 315 | q.w = (float)((double)q.w / magnitude); 316 | q.x = (float)((double)q.x / magnitude); 317 | q.y = (float)((double)q.y / magnitude); 318 | q.z = (float)((double)q.z / magnitude); 319 | } 320 | return q; 321 | } 322 | //Transform the matrix by a vector3 323 | public Vector3 TransformNormal(Vector3 normal, Matrix4x4 matrix) 324 | { 325 | Vector3 final; 326 | final.x = matrix.m00 * normal.x + matrix.m10 * normal.y + matrix.m20 * normal.z; 327 | 328 | final.y = matrix.m02 * normal.x + matrix.m11 * normal.y + matrix.m21 * normal.z; 329 | 330 | final.z = matrix.m03 * normal.x + matrix.m12 * normal.y + matrix.m22 * normal.z; 331 | return final; 332 | } 333 | #endregion 334 | } 335 | 336 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Scripts/GameState.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f97cfc7fbbcc4d446b2dbd9ade31bf33 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Scripts/MovementScripts.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class MovementScripts: MonoBehaviour 5 | { 6 | //Consts 7 | private const float SLOW_DOWN_RATE = 2f; 8 | private const float ACCEL_RATE = 20f; 9 | private const int INIT_FRAME_WAIT = 5; 10 | private const float DEGREE_TO_RADIAN_CONST = 57.2957795f; 11 | public float controllerBoost=6000; 12 | //Affect our rotation speed 13 | public float rotSpeed; 14 | //Keep track of the camera transform 15 | public Transform camTransform; 16 | //Just turn this negative when they press the Y button for inversion. 17 | private int inverted; 18 | //What is our current target for the speed of light? 19 | public int speedOfLightTarget; 20 | //What is each step we take to reach that target? 21 | private float speedOfLightStep; 22 | //For now, you can change this how you like. 23 | public float mouseSensitivity; 24 | //So we can use getAxis as keyHit function 25 | public bool invertKeyDown = false; 26 | //Keep track of total frames passed 27 | int frames; 28 | //How fast are we going to shoot the bullets? 29 | public float viwMax = 3; 30 | //Gamestate reference for quick access 31 | GameState state; 32 | 33 | void Start() 34 | { 35 | //grab Game State, we need it for many actions 36 | state = GetComponent(); 37 | //Lock and hide cursor 38 | Cursor.lockState = CursorLockMode.Locked; 39 | Cursor.visible = false; 40 | //Set the speed of light to the starting speed of light in GameState 41 | speedOfLightTarget = (int)state.SpeedOfLight; 42 | //Inverted, at first 43 | inverted = -1; 44 | 45 | 46 | viwMax = Mathf.Min(viwMax,(float)GameObject.FindGameObjectWithTag(Tags.player).GetComponent().MaxSpeed); 47 | 48 | frames = 0; 49 | } 50 | //Again, use LateUpdate to solve some collision issues. 51 | void LateUpdate() 52 | { 53 | if(true) 54 | { 55 | float viewRotX = 0; 56 | //If we're not paused, update speed and rotation using player input. 57 | if(!state.MovementFrozen) 58 | { 59 | state.deltaRotation = Vector3.zero; 60 | 61 | //If they press the Y button, invert all Y axes 62 | if (Input.GetAxis("Invert Button") > 0 && !invertKeyDown) 63 | { 64 | inverted *= -1; 65 | invertKeyDown = true; 66 | } 67 | //And if they released it, set the invertkeydown to false. 68 | else if ( !(Input.GetAxis("Invert Button") > 0)) 69 | { 70 | invertKeyDown = false; 71 | } 72 | 73 | #region ControlScheme 74 | 75 | //PLAYER MOVEMENT 76 | 77 | //If we press W, move forward, if S, backwards. 78 | //A adds speed to the left, D to the right. We're using FPS style controls 79 | //Here's hoping they work. 80 | 81 | //The acceleration relation is defined by the following equation 82 | //vNew = (v+uParallel+ (uPerpendicular/gamma))/(1+(v*u)/c^2) 83 | 84 | //Okay, so Gerd found a good equation that doesn't break when your velocity is zero, BUT your velocity has to be in the x direction. 85 | //So, we're gonna reuse some code from our relativisticObject component, and rotate everything to be at the X axis. 86 | 87 | //Cache our velocity 88 | Vector3 playerVelocityVector = state.PlayerVelocityVector; 89 | 90 | //Get our angle between the velocity and the X axis. Get the angle in degrees (radians suck) 91 | float rotationAroundX = DEGREE_TO_RADIAN_CONST * Mathf.Acos(Vector3.Dot(playerVelocityVector, Vector3.right) / playerVelocityVector.magnitude); 92 | 93 | 94 | 95 | //Make a Quaternion from the angle, one to rotate, one to rotate back. 96 | Quaternion rotateX = Quaternion.AngleAxis(rotationAroundX, Vector3.Cross(playerVelocityVector, Vector3.right).normalized); 97 | Quaternion unRotateX = Quaternion.AngleAxis(rotationAroundX, Vector3.Cross(Vector3.right,playerVelocityVector).normalized); 98 | 99 | 100 | //If the magnitude's zero just make these angles zero and the Quaternions identity Q's 101 | if (playerVelocityVector.sqrMagnitude == 0) 102 | { 103 | rotationAroundX = 0; 104 | rotateX = Quaternion.identity; 105 | unRotateX = Quaternion.identity; 106 | } 107 | 108 | //Store our added velocity into temporary variable addedVelocity 109 | Vector3 addedVelocity = Vector3.zero; 110 | 111 | //Turn our camera rotation into a Quaternion. This allows us to make where we're pointing the direction of our added velocity. 112 | //If you want to constrain the player to just x/z movement, with no Y direction movement, comment out the next two lines 113 | //and uncomment the line below that is marked 114 | float cameraRotationAngle = -DEGREE_TO_RADIAN_CONST * Mathf.Acos(Vector3.Dot(camTransform.forward, Vector3.forward)); 115 | Quaternion cameraRotation = Quaternion.AngleAxis(cameraRotationAngle, Vector3.Cross(camTransform.forward, Vector3.forward).normalized); 116 | 117 | //UNCOMMENT THIS LINE if you would like to constrain the player to just x/z movement. 118 | //Quaternion cameraRotation = Quaternion.AngleAxis(camTransform.eulerAngles.y, Vector3.up); 119 | 120 | 121 | float temp; 122 | //Movement due to left/right input 123 | addedVelocity += new Vector3(0, 0, (temp = -Input.GetAxis("Vertical"))*ACCEL_RATE* (float)Time.deltaTime); 124 | if (temp != 0) 125 | { 126 | state.keyHit = true; 127 | } 128 | 129 | addedVelocity += new Vector3((temp = -Input.GetAxis("Horizontal"))*ACCEL_RATE * (float)Time.deltaTime, 0, 0); 130 | if (temp != 0) 131 | { 132 | state.keyHit = true; 133 | } 134 | 135 | //And rotate our added velocity by camera angle 136 | 137 | addedVelocity = cameraRotation * addedVelocity; 138 | 139 | //AUTO SLOW DOWN CODE BLOCK 140 | 141 | //If we are not adding velocity this round to our x direction, slow down 142 | if (addedVelocity.x == 0) 143 | { 144 | //find our current direction of movement and oppose it 145 | addedVelocity += new Vector3(-1*SLOW_DOWN_RATE*playerVelocityVector.x * (float)Time.deltaTime, 0, 0); 146 | } 147 | //If we are not adding velocity this round to our z direction, slow down 148 | if (addedVelocity.z == 0) 149 | { 150 | addedVelocity += new Vector3(0, 0, -1*SLOW_DOWN_RATE*playerVelocityVector.z * (float)Time.deltaTime); 151 | } 152 | //If we are not adding velocity this round to our y direction, slow down 153 | if (addedVelocity.y == 0) 154 | { 155 | addedVelocity += new Vector3(0, -1*SLOW_DOWN_RATE*playerVelocityVector.y * (float)Time.deltaTime,0); 156 | } 157 | /* 158 | * IF you turn on this bit of code, you'll get head bob. It's a fun little effect, but if you make the magnitude of the cosine too large it gets sickening. 159 | if (!double.IsNaN((float)(0.2 * Mathf.Cos((float)GetComponent().TotalTimePlayer) * Time.deltaTime)) && frames > 2) 160 | { 161 | addedVelocity.y += (float)(0.2 * Mathf.Cos((float)GetComponent().TotalTimePlayer) * Time.deltaTime); 162 | } 163 | */ 164 | //Add the velocities here. remember, this is the equation: 165 | //vNew = (1/(1+vOld*vAddx/cSqrd))*(Vector3(vAdd.x+vOld.x,vAdd.y/Gamma,vAdd.z/Gamma)) 166 | if (addedVelocity.sqrMagnitude != 0) 167 | { 168 | //Rotate our velocity Vector 169 | Vector3 rotatedVelocity = rotateX * playerVelocityVector; 170 | //Rotate our added Velocity 171 | addedVelocity = rotateX * addedVelocity; 172 | 173 | //get gamma so we don't have to bother getting it every time 174 | float gamma = (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 175 | //Do relativistic velocity addition as described by the above equation. 176 | rotatedVelocity = (1 / (1 + (rotatedVelocity.x * addedVelocity.x) / (float)state.SpeedOfLightSqrd)) * 177 | (new Vector3(addedVelocity.x + rotatedVelocity.x, addedVelocity.y * gamma, gamma * addedVelocity.z)); 178 | 179 | //Unrotate our new total velocity 180 | rotatedVelocity = unRotateX * rotatedVelocity; 181 | //Set it 182 | state.PlayerVelocityVector = rotatedVelocity; 183 | 184 | } 185 | //CHANGE the speed of light 186 | 187 | //Get our input axis (DEFAULT N, M) value to determine how much to change the speed of light 188 | int temp2 = (int)(Input.GetAxis("Speed of Light")); 189 | //If it's too low, don't subtract from the speed of light, and reset the speed of light 190 | if(temp2<0 && speedOfLightTarget<=state.MaxSpeed) 191 | { 192 | temp2 = 0; 193 | speedOfLightTarget = (int)state.MaxSpeed; 194 | } 195 | if(temp2!=0) 196 | { 197 | speedOfLightTarget += temp2; 198 | 199 | speedOfLightStep = Mathf.Abs((float)(state.SpeedOfLight - speedOfLightTarget) / 20); 200 | } 201 | //Now, if we're not at our target, move towards the target speed that we're hoping for 202 | if (state.SpeedOfLight < speedOfLightTarget * .995) 203 | { 204 | //Then we change the speed of light, so that we get a smooth change from one speed of light to the next. 205 | state.SpeedOfLight += speedOfLightStep; 206 | } 207 | else if (state.SpeedOfLight > speedOfLightTarget * 1.005) 208 | { 209 | //See above 210 | state.SpeedOfLight -= speedOfLightStep; 211 | } 212 | //If we're within a +-.05 distance of our target, just set it to be our target. 213 | else if (state.SpeedOfLight != speedOfLightTarget) 214 | { 215 | state.SpeedOfLight = speedOfLightTarget; 216 | } 217 | 218 | //MOUSE CONTROLS 219 | //Current position of the mouse 220 | //Difference between last frame's mouse position 221 | //X axis position change 222 | float positionChangeX = -(float)Input.GetAxis("Mouse X"); 223 | 224 | //Y axis position change 225 | float positionChangeY = (float)inverted * Input.GetAxis("Mouse Y"); 226 | 227 | //Use these to determine camera rotation, that is, to look around the world without changing direction of motion 228 | //These two are for X axis rotation and Y axis rotation, respectively 229 | float viewRotY = 0; 230 | if(Mathf.Abs(positionChangeX)<=1 && Mathf.Abs(positionChangeY)<=1) 231 | { 232 | //Take the position changes and translate them into an amount of rotation 233 | viewRotX = (float)(-positionChangeX * Time.deltaTime * rotSpeed * mouseSensitivity * controllerBoost); 234 | viewRotY = (float)(positionChangeY * Time.deltaTime * rotSpeed * mouseSensitivity * controllerBoost); 235 | } 236 | else 237 | { 238 | //Take the position changes and translate them into an amount of rotation 239 | viewRotX = (float)(-positionChangeX * Time.deltaTime * rotSpeed * mouseSensitivity); 240 | viewRotY = (float)(positionChangeY * Time.deltaTime * rotSpeed * mouseSensitivity); 241 | } 242 | //Perform Rotation on the camera, so that we can look in places that aren't the direction of movement 243 | //Wait some frames on start up, otherwise we spin during the intialization when we can't see yet 244 | if (frames > INIT_FRAME_WAIT) 245 | { 246 | camTransform.Rotate(new Vector3(0, viewRotX, 0), Space.World); 247 | if ((camTransform.eulerAngles.x + viewRotY < 90 && camTransform.eulerAngles.x + viewRotY > 90 - 180) || (camTransform.eulerAngles.x + viewRotY > 270 && camTransform.eulerAngles.x + viewRotY < 270+180)) 248 | { 249 | camTransform.Rotate(new Vector3(viewRotY, 0, 0)); 250 | } 251 | } 252 | else{ 253 | //keep track of our frames 254 | frames++; 255 | } 256 | 257 | //If we have a speed of light less than max speed, fix it. 258 | //This should never happen 259 | if (state.SpeedOfLight < state.MaxSpeed) 260 | { 261 | state.SpeedOfLight = state.MaxSpeed; 262 | } 263 | 264 | 265 | #endregion 266 | 267 | //Send current speed of light to the shader 268 | Shader.SetGlobalFloat("_spdOfLight", (float)state.SpeedOfLight); 269 | 270 | if (Camera.main) 271 | { 272 | Shader.SetGlobalFloat("xyr", (float)Camera.main.pixelWidth / Camera.main.pixelHeight); 273 | Shader.SetGlobalFloat("xs", (float)Mathf.Tan(Mathf.Deg2Rad * Camera.main.fieldOfView / 2f)); 274 | 275 | //Don't cull because at high speeds, things come into view that are not visible normally 276 | //This is due to the lorenz transformation, which is pretty cool but means that basic culling will not work. 277 | Camera.main.layerCullSpherical = true; 278 | Camera.main.useOcclusionCulling = false; 279 | } 280 | 281 | 282 | } 283 | } 284 | 285 | 286 | 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Scripts/MovementScripts.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: afe53cba7abc30f45a8e4f209b6731fc 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Scripts/ObjectMeshDensity.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System; 5 | 6 | public class ObjectMeshDensity : MonoBehaviour { 7 | 8 | //Need these three lists to create a new set of each variable needed for a new mesh 9 | List newTriangles = new List(); 10 | List newVerts = new List(); 11 | List newUV = new List(); 12 | //state array contains information on splitting 13 | public bool state; 14 | //These store the original and split mesh 15 | public Mesh change; 16 | public Mesh original; 17 | 18 | 19 | //This constant determines triangle size. We subdivide meshes until all their triangles have less than this area. 20 | public double constant = 2; 21 | 22 | // Use this for initialization 23 | void Start () { 24 | //Grab the meshfilter, and if it's not null, keep going 25 | MeshFilter meshFilter = GetComponent(); 26 | if (meshFilter != null) 27 | { 28 | //Store a copy of our original mesh 29 | original = new Mesh(); 30 | 31 | original.vertices = meshFilter.mesh.vertices; 32 | original.uv = meshFilter.mesh.uv; 33 | original.triangles = meshFilter.mesh.triangles; 34 | 35 | original.RecalculateBounds(); 36 | original.RecalculateNormals(); 37 | original.name = meshFilter.mesh.name; 38 | //Prepare a new mesh for our split mesh 39 | change = new Mesh(); 40 | change.vertices = meshFilter.mesh.vertices; 41 | change.uv = meshFilter.mesh.uv; 42 | change.triangles = meshFilter.mesh.triangles; 43 | 44 | change.RecalculateBounds(); 45 | change.RecalculateNormals(); 46 | change.name = meshFilter.mesh.name; 47 | 48 | //Keep splitting this mesh until all of its triangles have area less than our chosen value 49 | bool isDone = true; 50 | int numberOfLoops = 0; 51 | while (isDone == true) 52 | { 53 | isDone = Subdivide(change, meshFilter.transform); 54 | numberOfLoops++; 55 | 56 | } 57 | if (numberOfLoops == 1) 58 | { 59 | change = null; 60 | } 61 | 62 | } 63 | else 64 | { 65 | original = null; 66 | change = null; 67 | } 68 | } 69 | 70 | 71 | //This function takes in information from RelativityModel, and returns either the split mesh or the original mesh, depending on the variable Subdivide 72 | public bool ReturnVerts(Mesh mesh, bool Subdivide) 73 | { 74 | //Check that there is actually a mesh here, not just a placeholder 75 | 76 | //Are we supposed to subdivide again? 77 | if (Subdivide) 78 | { 79 | //Set the state of the current mesh to split 80 | state = true; 81 | //Clear the mesh and replace it with the split mesh's values 82 | mesh.Clear(); 83 | mesh.vertices = change.vertices; 84 | mesh.uv = change.uv; 85 | mesh.triangles = change.triangles; 86 | mesh.RecalculateBounds(); 87 | mesh.RecalculateNormals(); 88 | return true; 89 | 90 | } 91 | //If not, we must be here to revert the mesh 92 | else if (!Subdivide) 93 | { 94 | //set the state of the current mesh to unchanged 95 | state = false; 96 | 97 | //Clear the mesh and replace it with the original mesh's values 98 | mesh.Clear(); 99 | mesh.vertices = original.vertices; 100 | mesh.uv = original.uv; 101 | mesh.triangles = original.triangles; 102 | mesh.RecalculateBounds(); 103 | mesh.RecalculateNormals(); 104 | return true; 105 | } 106 | 107 | return false; 108 | } 109 | 110 | 111 | //These are my own version of list to Array functions, I was having trouble with the regular ones 112 | // but might try them again 113 | 114 | //Copy over triangle list to triangle array 115 | int[] CopyOverT(List newT, int[] T) 116 | { 117 | T = new int[newT.Count]; 118 | for (int i = 0; i < newT.Count; i++) 119 | { 120 | T[i] = newT[i]; 121 | } 122 | return T; 123 | } 124 | //Copy vector list, return vector array 125 | Vector3[] CopyOverV(List newT, Vector3[] T) 126 | { 127 | T = new Vector3[newT.Count]; 128 | for (int i = 0; i < newT.Count; i++) 129 | { 130 | T[i].x = newT[i].x; 131 | T[i].y = newT[i].y; 132 | T[i].z = newT[i].z; 133 | } 134 | return T; 135 | } 136 | //Copy over UV list, return UV array 137 | Vector2[] CopyOverV2(List newT, Vector2[] T) 138 | { 139 | T = new Vector2[newT.Count]; 140 | for (int i = 0; i < newT.Count; i++) 141 | { 142 | T[i].x = newT[i].x; 143 | T[i].y = newT[i].y; 144 | } 145 | return T; 146 | } 147 | //Debug function, prints entire list of triangles and their vertices 148 | void printTriangles(Vector3[] oVerts, int[] triangles) 149 | { 150 | print(triangles.Length); 151 | for (int i = 0; i < triangles.Length; i += 3) 152 | { 153 | print("triangle " + i + " " + oVerts[triangles[i]] + " " + oVerts[triangles[i + 1]] + " " + oVerts[triangles[i + 2]]); 154 | } 155 | } 156 | //Find the midpoint between two vectors 157 | Vector3 Mid(Vector3 one, Vector3 two) 158 | { 159 | Vector3 vect; 160 | vect.x = (one.x + two.x) / 2; 161 | vect.y = (one.y + two.y) / 2; 162 | vect.z = (one.z + two.z) / 2; 163 | return vect; 164 | } 165 | //Finds midpoint of two V2s 166 | Vector2 Mid2(Vector2 one, Vector2 two) 167 | { 168 | Vector2 vect; 169 | vect.x = (one.x + two.x) / 2; 170 | vect.y = (one.y + two.y) / 2; 171 | return vect; 172 | } 173 | 174 | //Just subdivide something 175 | //Using this for subdividing a mesh as far as we need to for its mesh triangle area to be less than our defined constant 176 | public bool Subdivide(Mesh mesh, Transform transform) 177 | { 178 | //Take in the UVs and Triangles 179 | bool change = false; 180 | Vector2[] oldUV = new Vector2[mesh.uv.Length]; 181 | int[] oldTriangles = new int[mesh.triangles.Length]; 182 | Vector3[] oldVerts = new Vector3[mesh.vertices.Length]; 183 | System.Array.Copy(mesh.triangles, oldTriangles, mesh.triangles.Length); 184 | System.Array.Copy(mesh.uv, oldUV, mesh.uv.Length); 185 | System.Array.Copy(mesh.vertices, oldVerts, mesh.vertices.Length); 186 | 187 | int lastIndexAdded = 0; //Use this to keep track of the last vertex that you added to the list from each loop. 188 | int lastTriangleIndexAdded = 0; //Use this to keep track of the last vertex that you added to the list from each loop. 189 | 190 | //Loop through the triangles. If one has an area greater than our chosen constant, then subdivide it 191 | for (int i = 0; i < mesh.triangles.Length / 3; i++) 192 | { 193 | //Get two edges, take their cross product, and divide the magnitude in half. That should give us the triangle's area. 194 | Vector3 dist1 = (RecursiveTransform(mesh.vertices[mesh.triangles[lastIndexAdded]], transform) - RecursiveTransform(mesh.vertices[mesh.triangles[lastIndexAdded + 1]], transform)); 195 | Vector3 dist2 = (RecursiveTransform(mesh.vertices[mesh.triangles[lastIndexAdded + 2]], transform) - RecursiveTransform(mesh.vertices[mesh.triangles[lastIndexAdded + 1]], transform)); 196 | float area = Vector3.Cross(dist2, dist1).magnitude / 2; 197 | //If that area is larger than our desired triangle size: 198 | if (area > constant) 199 | { 200 | change = true; 201 | //Add old verts 202 | newVerts.Add(oldVerts[oldTriangles[lastIndexAdded]]); 203 | newVerts.Add(oldVerts[oldTriangles[lastIndexAdded + 1]]); 204 | newVerts.Add(oldVerts[oldTriangles[lastIndexAdded + 2]]); 205 | //new ones 206 | newVerts.Add(Mid(oldVerts[oldTriangles[lastIndexAdded]], oldVerts[oldTriangles[lastIndexAdded + 1]])); 207 | newVerts.Add(Mid(oldVerts[oldTriangles[lastIndexAdded]], oldVerts[oldTriangles[lastIndexAdded + 2]])); 208 | newVerts.Add(Mid(oldVerts[oldTriangles[lastIndexAdded + 1]], oldVerts[oldTriangles[lastIndexAdded + 2]])); 209 | 210 | //Triangle 1 211 | newTriangles.Add(lastTriangleIndexAdded); 212 | newTriangles.Add(lastTriangleIndexAdded + 3); 213 | newTriangles.Add(lastTriangleIndexAdded + 4); 214 | //Triangle 2 215 | newTriangles.Add(lastTriangleIndexAdded + 5); 216 | newTriangles.Add(lastTriangleIndexAdded + 4); 217 | newTriangles.Add(lastTriangleIndexAdded + 3); 218 | //Triangle 3 219 | newTriangles.Add(lastTriangleIndexAdded + 4); 220 | newTriangles.Add(lastTriangleIndexAdded + 5); 221 | newTriangles.Add(lastTriangleIndexAdded + 2); 222 | //Triangle 4 223 | newTriangles.Add(lastTriangleIndexAdded + 5); 224 | newTriangles.Add(lastTriangleIndexAdded + 3); 225 | newTriangles.Add(lastTriangleIndexAdded + 1); 226 | //Add the new and old UV verts 227 | newUV.Add(oldUV[oldTriangles[lastIndexAdded]]); 228 | newUV.Add(oldUV[oldTriangles[lastIndexAdded + 1]]); 229 | newUV.Add(oldUV[oldTriangles[lastIndexAdded + 2]]); 230 | newUV.Add(Mid2(oldUV[oldTriangles[lastIndexAdded]], oldUV[oldTriangles[lastIndexAdded + 1]])); 231 | newUV.Add(Mid2(oldUV[oldTriangles[lastIndexAdded]], oldUV[oldTriangles[lastIndexAdded + 2]])); 232 | newUV.Add(Mid2(oldUV[oldTriangles[lastIndexAdded + 1]], oldUV[oldTriangles[lastIndexAdded + 2]])); 233 | 234 | lastIndexAdded += 3; 235 | lastTriangleIndexAdded += 6; 236 | 237 | 238 | } 239 | else 240 | { 241 | ///Else put in placeholder vertices of (0,0,0), and don't reference them 242 | ///EDIT: Hopefully this lastIndexAdded variable will reduce this problem to nothing. 243 | newVerts.Add(oldVerts[oldTriangles[lastIndexAdded]]); 244 | newVerts.Add(oldVerts[oldTriangles[lastIndexAdded + 1]]); 245 | newVerts.Add(oldVerts[oldTriangles[lastIndexAdded + 2]]); 246 | 247 | 248 | newTriangles.Add(lastTriangleIndexAdded); 249 | newTriangles.Add(lastTriangleIndexAdded + 1); 250 | newTriangles.Add(lastTriangleIndexAdded + 2); 251 | 252 | newUV.Add(oldUV[oldTriangles[lastIndexAdded]]); 253 | newUV.Add(oldUV[oldTriangles[lastIndexAdded + 1]]); 254 | newUV.Add(oldUV[oldTriangles[lastIndexAdded + 2]]); 255 | 256 | lastIndexAdded += 3; 257 | lastTriangleIndexAdded += 3; 258 | } 259 | 260 | } 261 | //Clear Mesh 262 | mesh.Clear(); 263 | //Copy over Verts 264 | oldVerts = CopyOverV(newVerts, oldVerts); 265 | mesh.vertices = oldVerts; 266 | //Copy over UVs 267 | oldUV = CopyOverV2(newUV, oldUV); 268 | mesh.uv = oldUV; 269 | //Triangles 270 | oldTriangles = CopyOverT(newTriangles, oldTriangles); 271 | mesh.triangles = oldTriangles; 272 | //Recalculate mesh values 273 | mesh.RecalculateBounds(); 274 | mesh.RecalculateNormals(); 275 | //Clear our lists 276 | newTriangles.Clear(); 277 | newVerts.Clear(); 278 | newUV.Clear(); 279 | return change; 280 | } 281 | public bool SubdivideSubMesh(Mesh mesh, Transform transform, int count) 282 | { 283 | //Take in the UVs and Triangles 284 | bool change = false; 285 | Vector2[] oldUV = new Vector2[mesh.uv.Length]; 286 | Vector3[] oldVerts = new Vector3[mesh.vertices.Length]; 287 | System.Array.Copy(mesh.uv, oldUV, mesh.uv.Length); 288 | System.Array.Copy(mesh.vertices, oldVerts, mesh.vertices.Length); 289 | int[][] oldTriangles = new int[count][]; 290 | int lastIndexAdded = 0; //Use this to keep track of the last vertex that you added to the list from each loop. 291 | int lastTriangleIndexAdded = 0; //Use this to keep track of the last vertex that you added to the list from each loop. 292 | 293 | //Loop through the triangles. If one has an area greater than our chosen constant, then subdivide it] 294 | int offset = 0; 295 | for (int q = 0; q < mesh.subMeshCount; q++) 296 | { 297 | 298 | oldTriangles[q] = mesh.GetTriangles(q); 299 | for (int i = 0; i < oldTriangles[q].Length / 3; i++) 300 | { 301 | Vector3 dist1 = (RecursiveTransform(mesh.vertices[mesh.triangles[lastIndexAdded]], transform) - RecursiveTransform(mesh.vertices[mesh.triangles[lastIndexAdded + 1]], transform)); 302 | Vector3 dist2 = (RecursiveTransform(mesh.vertices[mesh.triangles[lastIndexAdded + 2]], transform) - RecursiveTransform(mesh.vertices[mesh.triangles[lastIndexAdded + 1]], transform)); 303 | float area = Vector3.Cross(dist2, dist1).magnitude / 2; 304 | if(i==0) 305 | print(area); 306 | if (area > constant) 307 | { 308 | change = true; 309 | //Add old verts 310 | newVerts.Add(oldVerts[oldTriangles[q][lastIndexAdded]]); 311 | newVerts.Add(oldVerts[oldTriangles[q][lastIndexAdded + 1]]); 312 | newVerts.Add(oldVerts[oldTriangles[q][lastIndexAdded + 2]]); 313 | //new ones 314 | newVerts.Add(Mid(oldVerts[oldTriangles[q][lastIndexAdded]], oldVerts[oldTriangles[q][lastIndexAdded + 1]])); 315 | newVerts.Add(Mid(oldVerts[oldTriangles[q][lastIndexAdded]], oldVerts[oldTriangles[q][lastIndexAdded + 2]])); 316 | newVerts.Add(Mid(oldVerts[oldTriangles[q][lastIndexAdded + 1]], oldVerts[oldTriangles[q][lastIndexAdded + 2]])); 317 | 318 | //Triangle 1 319 | newTriangles.Add(offset+lastTriangleIndexAdded); 320 | newTriangles.Add(offset + lastTriangleIndexAdded + 3); 321 | newTriangles.Add(offset + lastTriangleIndexAdded + 4); 322 | //Triangle 2 323 | newTriangles.Add(offset + lastTriangleIndexAdded + 5); 324 | newTriangles.Add(offset + lastTriangleIndexAdded + 4); 325 | newTriangles.Add(offset + lastTriangleIndexAdded + 3); 326 | //Triangle 3 327 | newTriangles.Add(offset + lastTriangleIndexAdded + 4); 328 | newTriangles.Add(offset + lastTriangleIndexAdded + 5); 329 | newTriangles.Add(offset + lastTriangleIndexAdded + 2); 330 | //Triangle 4 331 | newTriangles.Add(offset + lastTriangleIndexAdded + 5); 332 | newTriangles.Add(offset + lastTriangleIndexAdded + 3); 333 | newTriangles.Add(offset + lastTriangleIndexAdded + 1); 334 | //Add the new and old UV verts 335 | newUV.Add(oldUV[oldTriangles[q][lastIndexAdded]]); 336 | newUV.Add(oldUV[oldTriangles[q][lastIndexAdded + 1]]); 337 | newUV.Add(oldUV[oldTriangles[q][lastIndexAdded + 2]]); 338 | newUV.Add(Mid2(oldUV[oldTriangles[q][lastIndexAdded]], oldUV[oldTriangles[q][lastIndexAdded + 1]])); 339 | newUV.Add(Mid2(oldUV[oldTriangles[q][lastIndexAdded]], oldUV[oldTriangles[q][lastIndexAdded + 2]])); 340 | newUV.Add(Mid2(oldUV[oldTriangles[q][lastIndexAdded + 1]], oldUV[oldTriangles[q][lastIndexAdded + 2]])); 341 | 342 | lastIndexAdded += 3; 343 | lastTriangleIndexAdded += 6; 344 | 345 | 346 | } 347 | else 348 | { 349 | ///Else put in placeholder vertices of (0,0,0), and don't reference them 350 | ///EDIT: Hopefully this lastIndexAdded variable will reduce this problem to nothing. 351 | newVerts.Add(oldVerts[oldTriangles[q][lastIndexAdded]]); 352 | newVerts.Add(oldVerts[oldTriangles[q][lastIndexAdded + 1]]); 353 | newVerts.Add(oldVerts[oldTriangles[q][lastIndexAdded + 2]]); 354 | 355 | 356 | newTriangles.Add(offset + lastTriangleIndexAdded); 357 | newTriangles.Add(offset + lastTriangleIndexAdded + 1); 358 | newTriangles.Add(offset + lastTriangleIndexAdded + 2); 359 | 360 | newUV.Add(oldUV[oldTriangles[q][lastIndexAdded]]); 361 | newUV.Add(oldUV[oldTriangles[q][lastIndexAdded + 1]]); 362 | newUV.Add(oldUV[oldTriangles[q][lastIndexAdded + 2]]); 363 | 364 | lastIndexAdded += 3; 365 | lastTriangleIndexAdded += 3; 366 | } 367 | 368 | } 369 | oldTriangles[q] = CopyOverT(newTriangles, oldTriangles[q]); 370 | newTriangles.Clear(); 371 | } 372 | 373 | 374 | print(count); 375 | //Clear Mesh 376 | mesh.Clear(); 377 | //Copy over Verts 378 | oldVerts = CopyOverV(newVerts, oldVerts); 379 | mesh.vertices = oldVerts; 380 | mesh.subMeshCount = count; 381 | for (int j = 0; j < count; j++) 382 | { 383 | mesh.SetTriangles(oldTriangles[j], j); 384 | } 385 | //Copy over UVs 386 | oldUV = CopyOverV2(newUV, oldUV); 387 | mesh.uv = oldUV; 388 | //Recalculate mesh values 389 | mesh.RecalculateBounds(); 390 | mesh.RecalculateNormals(); 391 | //Clear our lists 392 | newTriangles.Clear(); 393 | newVerts.Clear(); 394 | newUV.Clear(); 395 | return change; 396 | } 397 | public Vector3 RecursiveTransform(Vector3 pt, Transform trans) 398 | { 399 | //Basically, this will transform the point until it has no more parent transforms. 400 | Vector3 pt1 = Vector3.zero; 401 | //If we have a parent transform, run this function again 402 | if (trans.parent != null) 403 | { 404 | pt = RecursiveTransform(pt1, trans.parent); 405 | 406 | return pt; 407 | } 408 | else 409 | { 410 | pt1 = trans.TransformPoint(pt); 411 | return pt1; 412 | } 413 | } 414 | } 415 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Scripts/ObjectMeshDensity.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 22c9071b0911d364c9c468ac5a90502c 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Scripts/RelativisticObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using UnityEngine; 6 | public class RelativisticObject : MonoBehaviour { 7 | public const float RAD_2_DEG = 57.2957795f; 8 | //Keep track of our own Mesh Filter 9 | private MeshFilter meshFilter; 10 | //Store our raw vertices in this variable, so that we can refer to them later 11 | private Vector3[] rawVerts; 12 | //Store this object's velocity here. 13 | public Vector3 viw; 14 | //Keep track of Game State so that we can reference it quickly 15 | public GameState state; 16 | //When was this object created? use for moving objects 17 | private float startTime = 0; 18 | //When should we die? again, for moving objects 19 | private float deathTime = 0; 20 | 21 | //Use this instead of relativistic parent 22 | public bool isParent =false; 23 | void Awake() 24 | { 25 | //Get the player's GameState, use it later for general information 26 | state = GameObject.FindGameObjectWithTag(Tags.player).GetComponent(); 27 | } 28 | 29 | // Get the start time of our object, so that we know where not to draw it 30 | public void SetStartTime() 31 | { 32 | startTime = (float) state.TotalTimeWorld; 33 | if(GetComponent()!=null) 34 | GetComponent().enabled = false; 35 | } 36 | //Set the death time, so that we know at what point to destroy the object in the player's view point. 37 | public virtual void SetDeathTime() 38 | { 39 | deathTime = (float)state.TotalTimeWorld; 40 | } 41 | void CombineParent() 42 | { 43 | if (GetComponent()) 44 | { 45 | GetComponent().enabled = false; 46 | } 47 | int vertCount = 0, triangleCount = 0; 48 | Matrix4x4 worldLocalMatrix = transform.worldToLocalMatrix; 49 | 50 | //This code combines the meshes of children of parent objects 51 | //This increases our FPS by a ton 52 | //Get an array of the meshfilters 53 | MeshFilter[] meshFilters = GetComponentsInChildren(true); 54 | //Count submeshes 55 | int[] subMeshCount = new int[meshFilters.Length]; 56 | //Get all the meshrenderers 57 | MeshRenderer[] meshRenderers = GetComponentsInChildren(true); 58 | //Length of our original array 59 | int meshFilterLength = meshFilters.Length; 60 | //And a counter 61 | int subMeshCounts = 0; 62 | 63 | //For every meshfilter, 64 | for (int y = 0; y < meshFilterLength; y++) 65 | { 66 | //If it's null, ignore it. 67 | if (meshFilters[y] == null) continue; 68 | if (meshFilters[y].sharedMesh == null) continue; 69 | //else add its vertices to the vertcount 70 | vertCount += meshFilters[y].sharedMesh.vertices.Length; 71 | //Add its triangles to the count 72 | triangleCount += meshFilters[y].sharedMesh.triangles.Length; 73 | //Add the number of submeshes to its spot in the array 74 | subMeshCount[y] = meshFilters[y].mesh.subMeshCount; 75 | //And add up the total number of submeshes 76 | subMeshCounts += meshFilters[y].mesh.subMeshCount; 77 | } 78 | // Get a temporary array of EVERY vertex 79 | Vector3[] tempVerts = new Vector3[vertCount]; 80 | //And make a triangle array for every submesh 81 | int[][] tempTriangles = new int[subMeshCounts][]; 82 | 83 | for (int u = 0; u < subMeshCounts; u++) 84 | { 85 | //Make every array the correct length of triangles 86 | tempTriangles[u] = new int[triangleCount]; 87 | } 88 | //Also grab our UV texture coordinates 89 | Vector2[] tempUVs = new Vector2[vertCount]; 90 | //And store a number of materials equal to the number of submeshes. 91 | Material[] tempMaterials = new Material[subMeshCounts]; 92 | 93 | int vertIndex = 0; 94 | Mesh MFs; 95 | int subMeshIndex = 0; 96 | //For all meshfilters 97 | for (int i = 0; i < meshFilterLength; i++) 98 | { 99 | //just doublecheck that the mesh isn't null 100 | MFs = meshFilters[i].sharedMesh; 101 | if (MFs == null) continue; 102 | 103 | //Otherwise, for all submeshes in the current mesh 104 | for (int q = 0; q < subMeshCount[i]; q++) 105 | { 106 | //grab its material 107 | tempMaterials[subMeshIndex] = meshRenderers[i].materials[q]; 108 | //Grab its triangles 109 | int[] tempSubTriangles = MFs.GetTriangles(q); 110 | //And put them into the submesh's triangle array 111 | for (int k = 0; k < tempSubTriangles.Length; k++) 112 | { 113 | tempTriangles[subMeshIndex][k] = tempSubTriangles[k] + vertIndex; 114 | } 115 | //Increment the submesh index 116 | subMeshIndex++; 117 | } 118 | Matrix4x4 cTrans = worldLocalMatrix * meshFilters[i].transform.localToWorldMatrix; 119 | //For all the vertices in the mesh 120 | for (int v = 0; v < MFs.vertices.Length; v++) 121 | { 122 | //Get the vertex and the UV coordinate 123 | tempVerts[vertIndex] = cTrans.MultiplyPoint3x4(MFs.vertices[v]); 124 | tempUVs[vertIndex] = MFs.uv[v]; 125 | vertIndex++; 126 | } 127 | //And delete that gameobject. 128 | meshFilters[i].gameObject.SetActive(false); 129 | } 130 | //Put it all together now. 131 | Mesh myMesh = new Mesh(); 132 | //Make the mesh have as many submeshes as you need 133 | myMesh.subMeshCount = subMeshCounts; 134 | //Set its vertices to tempverts 135 | myMesh.vertices = tempVerts; 136 | //start at the first submesh 137 | subMeshIndex = 0; 138 | //For every submesh in each meshfilter 139 | for (int l = 0; l < meshFilterLength; l++) 140 | { 141 | for (int g = 0; g < subMeshCount[l]; g++) 142 | { 143 | //Set a new submesh, using the triangle array and its submesh index (built in unity function) 144 | myMesh.SetTriangles(tempTriangles[subMeshIndex], subMeshIndex); 145 | //increment the submesh index 146 | subMeshIndex++; 147 | } 148 | } 149 | //Just shunt in the UV coordinates, we don't need to change them 150 | myMesh.uv = tempUVs; 151 | //THEN totally replace our object's mesh with this new, combined mesh 152 | 153 | MeshFilter meshy = gameObject.GetComponent(); 154 | if (GetComponent() == null) 155 | { 156 | gameObject.AddComponent(); 157 | meshy = gameObject.AddComponent(); 158 | } 159 | meshy.mesh = myMesh; 160 | GetComponent().enabled = false; 161 | 162 | meshy.mesh.RecalculateNormals(); 163 | meshy.GetComponent().materials = tempMaterials; 164 | 165 | transform.gameObject.SetActive(true); 166 | 167 | } 168 | void Start() 169 | { 170 | checkSpeed(); 171 | //Get the meshfilter 172 | if(isParent) 173 | { 174 | CombineParent(); 175 | } 176 | meshFilter = GetComponent(); 177 | 178 | //Also get the meshrenderer so that we can give it a unique material 179 | MeshRenderer tempRenderer = GetComponent(); 180 | //If we have a MeshRenderer on our object 181 | if (tempRenderer != null) 182 | { 183 | //And if we have a texture on our material 184 | for (int i = 0; i < tempRenderer.materials.Length; i++) 185 | { 186 | //if (tempRenderer.materials[i]!=null && tempRenderer.materials[i].mainTexture != null) 187 | //{ 188 | //So that we can set unique values to every moving object, we have to instantiate a material 189 | //It's the same as our old one, but now it's not connected to every other object with the same material 190 | Material quickSwapMaterial = Instantiate((tempRenderer as Renderer).materials[i]) as Material; 191 | //Then, set the value that we want 192 | quickSwapMaterial.SetFloat("_viw", 0); 193 | 194 | //And stick it back into our renderer. We'll do the SetVector thing every frame. 195 | tempRenderer.materials[i] = quickSwapMaterial; 196 | 197 | //set our start time and start position in the shader. 198 | tempRenderer.materials[i].SetFloat("_strtTime", (float)startTime); 199 | tempRenderer.materials[i].SetVector("_strtPos", new Vector4(transform.position.x, transform.position.y, transform.position.z, 0)); 200 | //} 201 | } 202 | } 203 | //Get the vertices of our mesh 204 | if (meshFilter != null) 205 | { 206 | rawVerts = meshFilter.mesh.vertices; 207 | } 208 | else 209 | rawVerts = null; 210 | 211 | 212 | //This code is a hack to ensure that frustrum culling does not take place 213 | //It changes the render bounds so that everything is contained within them 214 | //At high speeds the Lorenz contraction means that some objects not normally in the view frame are actually visible 215 | //If we did frustrum culling, these objects would be ignored (because we cull BEFORE running the shader, which does the lorenz contraction) 216 | if (meshFilter != null) 217 | { 218 | Transform camTransform = Camera.main.transform; 219 | float distToCenter = (Camera.main.farClipPlane + Camera.main.nearClipPlane) / 2.0f; 220 | Vector3 center = camTransform.position + camTransform.forward * distToCenter; 221 | float extremeBound = 500000.0f; 222 | meshFilter.sharedMesh.bounds = new Bounds(center, Vector3.one * extremeBound); 223 | } 224 | } 225 | 226 | 227 | public void Update() 228 | { 229 | //Grab our renderer. 230 | MeshRenderer tempRenderer = GetComponent(); 231 | 232 | if (meshFilter != null && !state.MovementFrozen) 233 | { 234 | #region meshDensity 235 | //This is where I'm going to change our mesh density. 236 | //I'll take the model, and pass MeshDensity the mesh and unchanged vertices 237 | //If it comes back as having changed something, I'll edit the mesh. 238 | 239 | ObjectMeshDensity density = GetComponent(); 240 | 241 | if (density != null) 242 | { 243 | 244 | //Only run MeshDensity if the mesh needs to change, and if it's passed a threshold distance. 245 | if (rawVerts != null && density.change != null) 246 | { 247 | //This checks if we're within our large range, first mesh density circle 248 | //If we're within a distance of 40, split this mesh 249 | if (density.state == false && RecursiveTransform(rawVerts[0], meshFilter.transform).magnitude < 21000) 250 | { 251 | if (density.ReturnVerts(meshFilter.mesh, true)) 252 | { 253 | rawVerts = new Vector3[meshFilter.mesh.vertices.Length]; 254 | System.Array.Copy(meshFilter.mesh.vertices, rawVerts, meshFilter.mesh.vertices.Length); 255 | 256 | } 257 | } 258 | 259 | //If the object leaves our wide range, revert mesh to original state 260 | else if (density.state == true && RecursiveTransform(rawVerts[0], meshFilter.transform).magnitude > 21000) 261 | { 262 | if (density.ReturnVerts(meshFilter.mesh, false)) 263 | { 264 | rawVerts = new Vector3[meshFilter.mesh.vertices.Length]; 265 | System.Array.Copy(meshFilter.mesh.vertices, rawVerts, meshFilter.mesh.vertices.Length); 266 | } 267 | } 268 | 269 | } 270 | } 271 | #endregion 272 | 273 | 274 | //Send our object's v/c (Velocity over the Speed of Light) to the shader 275 | if (tempRenderer != null) 276 | { 277 | Vector3 tempViw = viw / (float)state.SpeedOfLight; 278 | for (int i = 0; i < tempRenderer.materials.Length; i++) 279 | { 280 | tempRenderer.materials[i].SetVector("_viw", new Vector4(tempViw.x, tempViw.y, tempViw.z, 0)); 281 | } 282 | } 283 | 284 | //As long as our object is actually alive, perform these calculations 285 | if (transform != null) 286 | { 287 | //Here I take the angle that the player's velocity vector makes with the z axis 288 | float rotationAroundZ = RAD_2_DEG * Mathf.Acos(Vector3.Dot(state.PlayerVelocityVector, Vector3.forward) / state.PlayerVelocityVector.magnitude); 289 | 290 | if (state.PlayerVelocityVector.sqrMagnitude == 0) 291 | { 292 | rotationAroundZ = 0; 293 | } 294 | 295 | //Now we turn that rotation into a quaternion 296 | 297 | Quaternion rotateZ = Quaternion.AngleAxis(-rotationAroundZ, Vector3.Cross(state.PlayerVelocityVector, Vector3.forward)); 298 | //****************************************************************** 299 | 300 | //Place the vertex to be changed in a new Vector3 301 | Vector3 riw = new Vector3(transform.position.x, transform.position.y, transform.position.z); 302 | riw -= state.playerTransform.position; 303 | 304 | 305 | //And we rotate our point that much to make it as if our magnitude of velocity is in the Z direction 306 | riw = rotateZ * riw; 307 | 308 | 309 | //Here begins the original code, made by the guys behind the Relativity game 310 | /**************************** 311 | * Start Part 6 Bullet 1 312 | 313 | */ 314 | 315 | //Rotate that velocity! 316 | Vector3 storedViw = rotateZ * viw; 317 | 318 | float c = -Vector3.Dot(riw, riw); //first get position squared (position doted with position) 319 | 320 | float b = -(2 * Vector3.Dot(riw, storedViw)); //next get position doted with velocity, should be only in the Z direction 321 | 322 | float a = (float)state.SpeedOfLightSqrd - Vector3.Dot(storedViw, storedViw); 323 | 324 | /**************************** 325 | * Start Part 6 Bullet 2 326 | * **************************/ 327 | 328 | float tisw = (float)(((-b - (Math.Sqrt((b * b) - 4f * a * c))) / (2f * a))); 329 | //If we're past our death time (in the player's view, as seen by tisw) 330 | if (state.TotalTimeWorld + tisw > deathTime && deathTime!=0) 331 | { 332 | KillObject(); 333 | } 334 | if (state.TotalTimeWorld + tisw > startTime && !tempRenderer.enabled) 335 | { 336 | tempRenderer.enabled = true; 337 | if(GetComponent()!= null) 338 | { 339 | GetComponent().enabled=true; 340 | } 341 | } 342 | } 343 | 344 | //make our rigidbody's velocity viw 345 | if (GetComponent() != null) 346 | { 347 | 348 | if (!double.IsNaN((double)state.SqrtOneMinusVSquaredCWDividedByCSquared) && (float)state.SqrtOneMinusVSquaredCWDividedByCSquared != 0) 349 | { 350 | Vector3 tempViw = viw; 351 | //ASK RYAN WHY THESE WERE DIVIDED BY THIS 352 | tempViw.x /= (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 353 | tempViw.y /= (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 354 | tempViw.z /= (float)state.SqrtOneMinusVSquaredCWDividedByCSquared; 355 | 356 | GetComponent().velocity = tempViw; 357 | } 358 | 359 | 360 | } 361 | } 362 | //If nothing is null, then set the object to standstill, but make sure its rigidbody actually has a velocity. 363 | else if (meshFilter != null && tempRenderer != null && GetComponent() != null) 364 | { 365 | GetComponent().velocity = Vector3.zero; 366 | } 367 | 368 | 369 | 370 | } 371 | public void KillObject() 372 | { 373 | gameObject.SetActive (false); 374 | //Destroy(this.gameObject); 375 | } 376 | public Vector3 RecursiveTransform(Vector3 pt, Transform trans) 377 | { 378 | //Basically, this will transform the point until it has no more parent transforms. 379 | Vector3 pt1 = Vector3.zero; 380 | //If we have a parent transform, run this function again 381 | if (trans.parent != null) 382 | { 383 | pt = RecursiveTransform(pt1, trans.parent); 384 | 385 | return pt; 386 | } 387 | else 388 | { 389 | pt1 = trans.TransformPoint(pt); 390 | return pt1; 391 | } 392 | } 393 | 394 | //This is a function that just ensures we're slower than our maximum speed. The VIW that Unity sets SHOULD (it's creator-chosen) be smaller than the maximum speed. 395 | private void checkSpeed() 396 | { 397 | if (viw.magnitude > state.MaxSpeed-.01) 398 | { 399 | viw = viw.normalized * (float)(state.MaxSpeed-.01f); 400 | } 401 | } 402 | 403 | void OnEnable() 404 | { 405 | ResetDeathTime(); 406 | } 407 | void ResetDeathTime() 408 | { 409 | deathTime = 0; 410 | } 411 | } -------------------------------------------------------------------------------- /Assets/OpenRelativity/Scripts/RelativisticObject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fed80f06f083fad4abc68c7de5d73215 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ab6253a84b38a84449c1c3b6a168ca0e 3 | folderAsset: yes 4 | timeCreated: 1456244290 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Shaders/ColorCorrectionEffect.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | [ExecuteInEditMode] 5 | [AddComponentMenu("Image Effects/Color Correction (Ramp)")] 6 | public class ColorCorrectionEffect : ImageEffectBase { 7 | 8 | // Called by camera to apply image effect 9 | void OnRenderImage (RenderTexture source, RenderTexture destination) { 10 | Graphics.Blit (source, destination, material); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Shaders/ColorCorrectionEffect.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 18cb4fa7a1ac9814a9ca4810997ae0c3 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Shaders/ImageEffectBase.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | [RequireComponent (typeof(Camera))] 4 | [AddComponentMenu("")] 5 | public class ImageEffectBase : MonoBehaviour { 6 | /// Provides a shader property that is set in the inspector 7 | /// and a material instantiated from the shader 8 | public Shader shader; 9 | private Material m_Material; 10 | 11 | protected void Start () 12 | { 13 | // Disable if we don't support image effects 14 | if (!SystemInfo.supportsImageEffects) { 15 | enabled = false; 16 | return; 17 | } 18 | 19 | // Disable the image effect if the shader can't 20 | // run on the users graphics card 21 | if (!shader || !shader.isSupported) 22 | enabled = false; 23 | } 24 | 25 | protected Material material { 26 | get { 27 | if (m_Material == null) { 28 | m_Material = new Material (shader); 29 | m_Material.hideFlags = HideFlags.HideAndDontSave; 30 | } 31 | return m_Material; 32 | } 33 | } 34 | 35 | protected void OnDisable() { 36 | if( m_Material ) { 37 | DestroyImmediate( m_Material ); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Shaders/ImageEffectBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d9c0ab42b3b3c44a935b54277f6b76e 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Shaders/desaturateShader.shader: -------------------------------------------------------------------------------- 1 | // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' 2 | 3 | Shader "Colors/Desaturate" { 4 | Properties { 5 | _MainTex ("Base (RGB)", 2D) = "" {} 6 | } 7 | 8 | CGINCLUDE 9 | // Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members uv1) 10 | #pragma exclude_renderers d3d11 xbox360 11 | 12 | #include "UnityCG.cginc" 13 | 14 | struct v2f { 15 | float4 pos : POSITION; 16 | float2 uv1; 17 | }; 18 | 19 | sampler2D _MainTex; 20 | sampler2D _CameraDepthTexture; 21 | uniform float4 _MainTex_TexelSize; 22 | uniform float4 _CameraDepthTexture_ST; 23 | 24 | float3 hsv_to_rgb(float3 HSV) 25 | { 26 | HSV.x /= 360; 27 | float var_h = HSV.x * 6; 28 | 29 | float var_1 = HSV.z * ( 1.0 - HSV.y ); 30 | float var_2 = HSV.z * ( 1.0 - HSV.y * (var_h-floor( var_h ))); 31 | float var_3 = HSV.z * ( 1.0 - HSV.y * (1-(var_h-floor( var_h )))); 32 | 33 | float3 RGB = float3(HSV.z, var_1, var_2); 34 | 35 | if (var_h < 5) { RGB = float3(var_3, var_1, HSV.z); } 36 | if (var_h < 4) { RGB = float3(var_1, var_2, HSV.z); } 37 | if (var_h < 3) { RGB = float3(var_1, HSV.z, var_3); } 38 | if (var_h < 2) { RGB = float3(var_2, HSV.z, var_1); } 39 | if (var_h < 1) { RGB = float3(HSV.z, var_3, var_1); } 40 | 41 | return (RGB); 42 | } 43 | 44 | float3 rgb_to_hsv( float3 rgb ) 45 | { 46 | float min, max, delta; 47 | float3 hsv; 48 | 49 | min = rgb.x <= rgb.y ? rgb.x : rgb.y; 50 | min = min <= rgb.z ? min : rgb.z; 51 | max = rgb.x >= rgb.y ? rgb.x : rgb.y; 52 | max = max >= rgb.z ? max : rgb.z; 53 | 54 | hsv.z = max; 55 | delta = max - min; 56 | if( max != 0 ) 57 | { 58 | hsv.y = delta / max; 59 | } 60 | else 61 | { 62 | // r = g = b = 0 // s = 0, v is undefined 63 | hsv.y = 0; 64 | hsv.x = 0; 65 | return hsv; 66 | } 67 | if( rgb.x == max ) 68 | hsv.x = ( rgb.y - rgb.z ) / delta; // between yellow & magenta 69 | else if( rgb.y == max ) 70 | hsv.x = 2 + ( rgb.z - rgb.x ) / delta; // between cyan & yellow 71 | else 72 | hsv.x = 4 + ( rgb.x - rgb.y ) / delta; // between magenta & cyan 73 | hsv.x *= 60; // degrees 74 | if( hsv.x < 0 ) 75 | hsv.x += 360; 76 | return hsv; 77 | } 78 | 79 | //For the screen, this function is called a total of 4 times, as the screen renders to a square of 4 verticies. 80 | v2f vert( appdata_img v ) { 81 | v2f o; 82 | 83 | o.pos = UnityObjectToClipPos(v.vertex); 84 | o.uv1.xy = v.texcoord; 85 | 86 | //You need this otherwise the screen flips and weird stuff happens 87 | #ifdef SHADER_API_D3D9 88 | if (_MainTex_TexelSize.y < 0) 89 | o.uv1.y = o.uv1.y; 90 | #endif 91 | 92 | return o; 93 | } 94 | 95 | //Per pixel or something like that 96 | float4 frag(v2f i) : COLOR 97 | { 98 | //Grab initial color 99 | half4 color = (half4)tex2D(_MainTex, i.uv1).rgba; 100 | 101 | float3 hsv = rgb_to_hsv(float3(color.x,color.y,color.z)); 102 | hsv.y *= 0.5; 103 | float3 rgb = hsv_to_rgb(hsv); 104 | 105 | 106 | 107 | 108 | return float4(rgb.x,rgb.y,rgb.z,0); 109 | } 110 | 111 | ENDCG 112 | 113 | Subshader { 114 | 115 | Pass { 116 | ZTest Always Cull Off ZWrite Off 117 | Fog { Mode off } 118 | 119 | CGPROGRAM 120 | 121 | #pragma fragmentoption ARB_precision_hint_fastest 122 | 123 | #pragma vertex vert 124 | #pragma fragment frag 125 | #pragma target 3.0 126 | 127 | ENDCG 128 | } 129 | } 130 | 131 | Fallback off 132 | 133 | } // shader -------------------------------------------------------------------------------- /Assets/OpenRelativity/Shaders/desaturateShader.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f10b9076907ea104a98ea401d3e3d6e9 3 | ShaderImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Shaders/relativity.shader: -------------------------------------------------------------------------------- 1 | // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' 2 | // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject' 3 | // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' 4 | 5 | Shader "Relativity/ColorShift" 6 | { 7 | Properties 8 | { 9 | _MainTex ("Base (RGB)", 2D) = "" {} //Visible Spectrum Texture ( RGB ) 10 | _UVTex("UV",2D) = "" {} //UV texture 11 | _IRTex("IR",2D) = "" {} //IR texture 12 | _viw ("viw", Vector)=(0,0,0,0) //Vector that represents object's velocity in world frame 13 | _strtTime ("strtTime", float)=0 //For moving objects, when they created, this variable is set to current world time 14 | _Cutoff ("Base Alpha cutoff", Range (0,.9)) = 0.1 //Used to determine when not to render alpha materials 15 | } 16 | 17 | CGINCLUDE 18 | // Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members pos2,uv1,svc,vr,draw) 19 | #pragma exclude_renderers d3d11 xbox360 20 | // Upgrade NOTE: excluded shader from Xbox360; has structs without semantics (struct v2f members pos2,uv1,svc,vr) 21 | // Not sure when this^ got added, seems like unity did it automatically some update? 22 | #pragma exclude_renderers xbox360 23 | #pragma glsl 24 | #include "UnityCG.cginc" 25 | 26 | //Color shift variables, used to make guassians for XYZ curves 27 | #define xla 0.39952807612909519 28 | #define xlb 444.63156780935032 29 | #define xlc 20.095464678736523 30 | 31 | #define xha 1.1305579611401821 32 | #define xhb 593.23109262398259 33 | #define xhc 34.446036241271742 34 | 35 | #define ya 1.0098874822455657 36 | #define yb 556.03724875218927 37 | #define yc 46.184868454550838 38 | 39 | #define za 2.0648400466720593 40 | #define zb 448.45126344558236 41 | #define zc 22.357297606503543 42 | 43 | //Used to determine where to center UV/IR curves 44 | #define IR_RANGE 400 45 | #define IR_START 700 46 | #define UV_RANGE 380 47 | #define UV_START 0 48 | 49 | 50 | //This is the data sent from the vertex shader to the fragment shader 51 | struct v2f 52 | { 53 | float4 pos : POSITION; //internal, used for display 54 | float4 pos2 : TEXCOORD0; //Position in world, relative to player position in world 55 | float2 uv1 : TEXCOORD1; //Used to specify what part of the texture to grab in the fragment shader(not relativity specific, general shader variable) 56 | float svc: TEXCOORD2; //sqrt( 1 - (v-c)^2), calculated in vertex shader to save operations in fragment. It's a term used often in lorenz and doppler shift calculations, so we need to keep it cached to save computing 57 | float4 vr : TEXCOORD3; //Relative velocity of object vpc - viw 58 | float draw : TEXCOORD4; //Draw the vertex? Used to not draw objects that are calculated to be seen before they were created. Object's start time is used to determine this. If something comes out of a building, it should not draw behind the building. 59 | }; 60 | 61 | 62 | //Variables that we use to access texture data 63 | sampler2D _MainTex; 64 | sampler2D _IRTex; 65 | sampler2D _UVTex; 66 | sampler2D _CameraDepthTexture; 67 | 68 | float4 _viw = float4(0,0,0,0); //velocity of object in world 69 | float4 _vpc = float4(0,0,0,0); //velocity of player 70 | float4 _playerOffset = float4(0,0,0,0); //player position in world 71 | float _spdOfLight = 100; //current speed of light 72 | float _wrldTime = 0; //current time in world 73 | float _strtTime = 0; //starting time in world 74 | float _colorShift = 1; //actually a boolean, should use color effects or not ( doppler + spotlight). 75 | 76 | float xyr = 1; // xy ratio 77 | float xs = 1; // x scale 78 | 79 | uniform float4 _MainTex_TexelSize; 80 | uniform float4 _CameraDepthTexture_ST; 81 | 82 | //Per vertex operations 83 | v2f vert( appdata_img v ) 84 | { 85 | v2f o; 86 | 87 | o.pos = mul(unity_ObjectToWorld, v.vertex); //get position in world frame 88 | o.pos -= _playerOffset; //Shift such that we use a coordinate system where the player is at 0,0,0 89 | 90 | 91 | o.uv1.xy = v.texcoord; //get the UV coordinate for the current vertex, will be passed to fragment shade 92 | 93 | float speed = sqrt( pow((_vpc.x),2) + pow((_vpc.y),2) + pow((_vpc.z),2)); 94 | //vw + vp/(1+vw*vp/c^2) 95 | 96 | 97 | float vuDot = (_vpc.x*_viw.x + _vpc.y*_viw.y + _vpc.z*_viw.z); //Get player velocity dotted with velocity of the object. 98 | 99 | float4 uparra = (vuDot / (speed * speed)) * _vpc; 100 | uparra = !(isnan(uparra) || isinf(uparra)) ? uparra : 0; 101 | 102 | //Get the perpendicular component of our velocity, just by subtraction 103 | float4 uperp = _viw - uparra; 104 | //relative velocity calculation 105 | float4 vr =( _vpc - uparra - (sqrt(1-speed*speed))*uperp)/(1+vuDot); 106 | 107 | //set our relative velocity 108 | o.vr = vr; 109 | vr *= -1; 110 | //relative speed 111 | float speedr = sqrt( pow((vr.x),2) + pow((vr.y),2) + pow((vr.z),2)); 112 | o.svc = sqrt( 1 - speedr * speedr); // To decrease number of operations in fragment shader, we're storing this value 113 | 114 | //You need this otherwise the screen flips and weird stuff happens 115 | #ifdef SHADER_API_D3D9 116 | if (_MainTex_TexelSize.y < 0) 117 | o.uv1.y = 1.0- o.uv1.y; 118 | #endif 119 | //riw = location in world, for reference 120 | float4 riw = o.pos; //Position that will be used in the output 121 | 122 | if (speedr != 0) // If speed is zero, rotation fails 123 | { 124 | float a; //angle 125 | float ux; 126 | float uy; 127 | float ca; //cosine of a 128 | float sa; /// sine of a 129 | if ( speed != 0 ) 130 | { 131 | //we're getting the angle between our z direction of movement and the world's Z axis 132 | a = -acos(-_vpc.z/speed); 133 | if ( _vpc.x != 0 || _vpc.y != 0 ) 134 | { 135 | ux = _vpc.y/sqrt(_vpc.x*_vpc.x + _vpc.y*_vpc.y); 136 | uy = -_vpc.x/sqrt(_vpc.x*_vpc.x + _vpc.y*_vpc.y); 137 | } 138 | 139 | else 140 | { 141 | ux = 0; 142 | uy = 0; 143 | } 144 | ca = cos(a); 145 | sa = sin(a); 146 | 147 | //We're rotating player velocity here, making it seem like the player's movement is all in the Z direction 148 | //This is because all of our equations are based off of movement in one direction. 149 | 150 | //And we rotate our point that much to make it as if our magnitude of velocity is in the Z direction 151 | riw.x = o.pos.x * (ca + ux*ux*(1-ca)) + o.pos.y*(ux*uy*(1-ca)) + o.pos.z*(uy*sa); 152 | riw.y = o.pos.x * (uy*ux*(1-ca)) + o.pos.y * ( ca + uy*uy*(1-ca)) - o.pos.z*(ux*sa); 153 | riw.z = o.pos.x * (-uy*sa) + o.pos.y * (ux*sa) + o.pos.z*(ca); 154 | } 155 | 156 | 157 | 158 | //Here begins the original code, made by the guys behind the Relativity game 159 | 160 | //Rotate our velocity 161 | float4 rotateViw = float4(0,0,0,0); 162 | if ( speed != 0 ) 163 | { 164 | //Here we rotate our object's velocity so that we keep consistent with the rotation of our player's velocity. 165 | rotateViw.x = (_viw.x * (ca + ux*ux*(1-ca)) + _viw.y*(ux*uy*(1-ca)) + _viw.z*(uy*sa))*_spdOfLight; 166 | rotateViw.y = (_viw.x * (uy*ux*(1-ca)) + _viw.y * ( ca + uy*uy*(1-ca)) - _viw.z*(ux*sa))*_spdOfLight; 167 | rotateViw.z = (_viw.x * (-uy*sa) + _viw.y * (ux*sa) + _viw.z*(ca))*_spdOfLight; 168 | } 169 | else 170 | { 171 | rotateViw.x = (_viw.x) * _spdOfLight; 172 | rotateViw.z = (_viw.z) * _spdOfLight; 173 | rotateViw.y = (_viw.y) * _spdOfLight; 174 | } 175 | 176 | float c = -(riw.x*riw.x + riw.y*riw.y + riw.z*riw.z); //first get position squared (position doted with position) 177 | 178 | float b = -(2 * ( riw.x*rotateViw.x + riw.y*rotateViw.y + riw.z*rotateViw.z)); //next get position doted with velocity, should be only in the Z direction 179 | 180 | float d = (_spdOfLight*_spdOfLight) - (rotateViw.x*rotateViw.x + rotateViw.y*rotateViw.y + rotateViw.z*rotateViw.z); 181 | 182 | float tisw = (float)(((-b - (sqrt((b * b) - ((float)float(4)) * d * c))) / (((float)float(2)) * d))); 183 | 184 | //Check to make sure that objects that have velocity do not appear before they were created (Moving Person objects behind Sender objects) 185 | if (_wrldTime + tisw > _strtTime || _strtTime==0) 186 | { 187 | o.draw = 1; 188 | } 189 | else 190 | { 191 | o.draw = 0; 192 | } 193 | 194 | 195 | 196 | //get the new position offset, based on the new time we just found 197 | //Should only be in the Z direction 198 | 199 | riw.x += rotateViw.x * tisw; 200 | riw.y += rotateViw.y * tisw; 201 | riw.z += rotateViw.z * tisw; 202 | 203 | //Apply Lorentz transform 204 | // float newz =(riw.z + state.PlayerVelocity * tisw) / state.SqrtOneMinusVSquaredCWDividedByCSquared; 205 | //I had to break it up into steps, unity was getting order of operations wrong. 206 | float newz = (((float)speed*_spdOfLight) * tisw); 207 | 208 | newz = riw.z + newz; 209 | newz /= (float)sqrt(1 - (speed*speed)); 210 | riw.z = newz; 211 | if (speed != 0) 212 | { 213 | float trx = riw.x; 214 | float trry = riw.y; 215 | 216 | riw.x = riw.x * (ca + ux*ux*(1-ca)) + riw.y*(ux*uy*(1-ca)) - riw.z*(uy*sa); 217 | riw.y = trx * (uy*ux*(1-ca)) + riw.y * ( ca + uy*uy*(1-ca)) + riw.z*(ux*sa); 218 | riw.z = trx * (uy*sa) - trry * (ux*sa) + riw.z*(ca); 219 | } 220 | } 221 | else 222 | { 223 | o.draw = 1; 224 | } 225 | 226 | riw += _playerOffset; 227 | 228 | //Transform the vertex back into local space for the mesh to use it 229 | o.pos = mul(unity_WorldToObject*1.0,riw); 230 | 231 | o.pos2 = mul(unity_ObjectToWorld, o.pos ); 232 | o.pos2 -= _playerOffset; 233 | 234 | 235 | o.pos = UnityObjectToClipPos(o.pos); 236 | 237 | 238 | return o; 239 | } 240 | 241 | //Color functions, there's no check for division by 0 which may cause issues on 242 | //some graphics cards. 243 | float3 RGBToXYZC( float r, float g, float b) 244 | { 245 | float3 xyz; 246 | xyz.x = 0.13514*r + 0.120432*g + 0.057128*b; 247 | xyz.y = 0.0668999*r + 0.232706*g + 0.0293946*b; 248 | xyz.z = 0.0*r + 0.0000218959*g + 0.358278*b; 249 | return xyz; 250 | } 251 | float3 XYZToRGBC( float x, float y, float z) 252 | { 253 | float3 rgb; 254 | rgb.x = 9.94845*x -5.1485*y - 1.16389*z; 255 | rgb.y = -2.86007*x + 5.77745*y - 0.0179627*z; 256 | rgb.z = 0.000174791*x - 0.000353084*y + 2.79113*z; 257 | 258 | return rgb; 259 | } 260 | float3 weightFromXYZCurves(float3 xyz) 261 | { 262 | float3 returnVal; 263 | returnVal.x = 0.0735806 * xyz.x -0.0380793 * xyz.y - 0.00860837 * xyz.z; 264 | returnVal.y = -0.0665378 * xyz.x + 0.134408 * xyz.y - 0.000417865 * xyz.z; 265 | returnVal.z = 0.00000299624 * xyz.x - 0.00000605249 * xyz.y + 0.0484424 * xyz.z; 266 | return returnVal; 267 | } 268 | 269 | float getXFromCurve(float3 param, float shift) 270 | { 271 | float top1 = param.x * xla * exp( (float)(-(pow((param.y*shift) - xlb,2) 272 | /(2*(pow(param.z*shift,2)+pow(xlc,2))))))*sqrt( (float)(float(2)*(float)3.14159265358979323)); 273 | float bottom1 = sqrt((float)(1/pow(param.z*shift,2))+(1/pow(xlc,2))); 274 | 275 | float top2 = param.x * xha * exp( float(-(pow((param.y*shift) - xhb,2) 276 | /(2*(pow(param.z*shift,2)+pow(xhc,2))))))*sqrt( (float)(float(2)*(float)3.14159265358979323)); 277 | float bottom2 = sqrt((float)(1/pow(param.z*shift,2))+(1/pow(xhc,2))); 278 | 279 | return (top1/bottom1) + (top2/bottom2); 280 | } 281 | float getYFromCurve(float3 param, float shift) 282 | { 283 | float top = param.x * ya * exp( float(-(pow((param.y*shift) - yb,2) 284 | /(2*(pow(param.z*shift,2)+pow(yc,2))))))*sqrt( float(float(2)*(float)3.14159265358979323)); 285 | float bottom = sqrt((float)(1/pow(param.z*shift,2))+(1/pow(yc,2))); 286 | 287 | return top/bottom; 288 | } 289 | 290 | float getZFromCurve(float3 param, float shift) 291 | { 292 | float top = param.x * za * exp( float(-(pow((param.y*shift) - zb,2) 293 | /(2*(pow(param.z*shift,2)+pow(zc,2))))))*sqrt( float(float(2)*(float)3.14159265358979323)); 294 | float bottom = sqrt((float)(1/pow(param.z*shift,2))+(1/pow(zc,2))); 295 | 296 | return top/bottom; 297 | } 298 | 299 | float3 constrainRGB( float r, float g, float b) 300 | { 301 | float w; 302 | 303 | w = (0 < r) ? 0 : r; 304 | w = (w < g) ? w : g; 305 | w = (w < b) ? w : b; 306 | w = -w; 307 | 308 | if (w > 0) { 309 | r += w; g += w; b += w; 310 | } 311 | w = r; 312 | w = ( w < g) ? g : w; 313 | w = ( w < b) ? b : w; 314 | 315 | if ( w > 1 ) 316 | { 317 | r /= w; 318 | g /= w; 319 | b /= w; 320 | } 321 | float3 rgb; 322 | rgb.x = r; 323 | rgb.y = g; 324 | rgb.z = b; 325 | return rgb; 326 | 327 | }; 328 | 329 | //Per pixel shader, does color modifications 330 | float4 frag(v2f i) : COLOR 331 | { 332 | //Used to maintian a square scale ( adjust for screen aspect ratio ) 333 | float x1 = i.pos2.x * 2*xs; 334 | float y1 = i.pos2.y * 2*xs/xyr; 335 | float z1 = i.pos2.z; 336 | 337 | // ( 1 - (v/c)cos(theta) ) / sqrt ( 1 - (v/c)^2 ) 338 | float shift = (1-((x1*i.vr.x + y1*i.vr.y + z1*i.vr.z)/sqrt( x1 * x1 + y1 * y1 + z1 * z1)))/i.svc; 339 | if ( _colorShift == 0) 340 | { 341 | shift = 1.0f; 342 | } 343 | //Get initial color 344 | float4 data = tex2D (_MainTex, i.uv1).rgba; 345 | float UV = tex2D( _UVTex, i.uv1).r; 346 | float IR = tex2D( _IRTex, i.uv1).r; 347 | 348 | //Set alpha of drawing pixel to 0 if vertex shader has determined it should not be drawn. 349 | data.a = i.draw ? data.a : 0; 350 | 351 | float3 rgb = data.xyz; 352 | 353 | 354 | 355 | 356 | //Color shift due to doppler, go from RGB -> XYZ, shift, then back to RGB. 357 | float3 xyz = RGBToXYZC(float(rgb.x),float(rgb.y),float(rgb.z)); 358 | float3 weights = weightFromXYZCurves(xyz); 359 | float3 rParam,gParam,bParam,UVParam,IRParam; 360 | rParam.x = weights.x; rParam.y = ( float) 615; rParam.z = ( float)8; 361 | gParam.x = weights.y; gParam.y = ( float) 550; gParam.z = ( float)4; 362 | bParam.x = weights.z; bParam.y = ( float) 463; bParam.z = ( float)5; 363 | UVParam.x = 0.02; UVParam.y = UV_START + UV_RANGE*UV; UVParam.z = (float)5; 364 | IRParam.x = 0.02; IRParam.y = IR_START + IR_RANGE*IR; IRParam.z = (float)5; 365 | 366 | float xf = pow((1/shift),3)*(getXFromCurve(rParam, shift) + getXFromCurve(gParam,shift) + getXFromCurve(bParam,shift) + getXFromCurve(IRParam,shift) + getXFromCurve(UVParam,shift)); 367 | float yf = pow((1/shift),3)*(getYFromCurve(rParam, shift) + getYFromCurve(gParam,shift) + getYFromCurve(bParam,shift) + getYFromCurve(IRParam,shift) + getYFromCurve(UVParam,shift)); 368 | float zf = pow((1/shift),3)*(getZFromCurve(rParam, shift) + getZFromCurve(gParam,shift) + getZFromCurve(bParam,shift) + getZFromCurve(IRParam,shift) + getZFromCurve(UVParam,shift)); 369 | 370 | float3 rgbFinal = XYZToRGBC(xf,yf,zf); 371 | rgbFinal = constrainRGB(rgbFinal.x,rgbFinal.y, rgbFinal.z); //might not be needed 372 | 373 | //Test if unity_Scale is correct, unity occasionally does not give us the correct scale and you will see strange things in vertices, this is just easy way to test 374 | //float4x4 temp = mul(unity_Scale.w*_Object2World, _World2Object); 375 | //float4 temp2 = mul( temp,float4( (float)rgbFinal.x,(float)rgbFinal.y,(float)rgbFinal.z,data.a)); 376 | //return temp2; 377 | //float4 temp2 =float4( (float)rgbFinal.x,(float)rgbFinal.y,(float)rgbFinal.z,data.a ); 378 | return float4((float)rgbFinal.x,(float)rgbFinal.y,(float)rgbFinal.z,data.a); //use me for any real build 379 | } 380 | 381 | ENDCG 382 | 383 | Subshader { 384 | 385 | Pass { 386 | //Shader properties, for things such as transparency 387 | Cull Off ZWrite On 388 | ZTest LEqual 389 | Fog { Mode off } //Fog does not shift properly and there is no way to do so with this fog 390 | Tags {"RenderType"="Transparent" "Queue"="Transparent"} 391 | 392 | AlphaTest Greater [_Cutoff] 393 | Blend SrcAlpha OneMinusSrcAlpha 394 | 395 | CGPROGRAM 396 | 397 | #pragma fragmentoption ARB_precision_hint_nicest 398 | 399 | #pragma vertex vert 400 | #pragma fragment frag 401 | #pragma target 3.0 402 | 403 | ENDCG 404 | } 405 | } 406 | 407 | Fallback "Unlit/Transparent" 408 | 409 | } // shader 410 | 411 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Shaders/relativity.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7a0e8a44bcacae44a92d0b49b588eb0a 3 | ShaderImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/OpenRelativity/Shaders/skybox.shader: -------------------------------------------------------------------------------- 1 | // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' 2 | // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject' 3 | // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' 4 | 5 | Shader "Relativity/SkyboxShift" { 6 | Properties { 7 | _MainTex ("Base (RGB)", 2D) = "" {} 8 | _UVTex("UV",2D) = "" {} 9 | _IRTex("IR",2D) = "" {} 10 | _viw ("viw", float)=0 11 | } 12 | 13 | CGINCLUDE 14 | // Upgrade NOTE: excluded shader from Xbox360; has structs without semantics (struct v2f members pos2,uv1,svc,vr) 15 | #pragma exclude_renderers xbox360 16 | 17 | #pragma glsl 18 | #include "UnityCG.cginc" 19 | 20 | #define xla 0.39842970153455692 21 | #define xlb 444.50376680864167 22 | #define xlc -20.212233772937985 23 | 24 | #define xha 1.1305579611073924 25 | #define xhb 593.23109259420676 26 | #define xhc 34.446036264605638 27 | 28 | #define ya 1.0104130954965003 29 | #define yb 556.12431133891937 30 | #define yc 46.102600601714499 31 | 32 | #define za 2.0586397904795373 33 | #define zb 448.35859770333445 34 | #define zc -22.546254030641482 35 | 36 | #define IR_RANGE 400 37 | #define IR_START 700 38 | #define UV_RANGE 380 39 | #define UV_START 0 40 | 41 | 42 | 43 | struct v2f { 44 | float4 pos : POSITION; 45 | float4 pos2 : TEXCOORD0; 46 | float2 uv1 : TEXCOORD1; 47 | float svc : TEXCOORD2; 48 | float4 vr : TEXCOORD3; 49 | }; 50 | 51 | sampler2D _MainTex; 52 | sampler2D _IRTex; 53 | sampler2D _UVTex; 54 | sampler2D _CameraDepthTexture; 55 | 56 | float4 _viw = float4(0,0,0,0); //velocity of object 57 | float4 _vpc = float4(0,0,0,0); 58 | float _spdOfLight = 100 ; 59 | float4 _playerOffset = float4(0,0,0,0); 60 | float _colorShift = 1; 61 | 62 | float cx = 1; //cos x 63 | float cy = 1; // cos y 64 | float cz = 1; // cos z 65 | float sx = 0; // sin x 66 | float sy = 0; // sin yv 67 | float sz = 0; // sin z 68 | float xyr = 1; // xy ratio 69 | float xs = 1; // x scale 70 | 71 | uniform float4 _MainTex_TexelSize; 72 | uniform float4 _CameraDepthTexture_ST; 73 | 74 | //For the screen, this function is called a total of 4 times, as the screen renders to a square of 4 verticies. 75 | v2f vert( appdata_img v ) { 76 | v2f o; 77 | 78 | 79 | o.pos = UnityObjectToClipPos(v.vertex); 80 | o.pos2 = mul(unity_ObjectToWorld, v.vertex); 81 | 82 | o.pos2 -= _playerOffset; 83 | 84 | 85 | o.uv1.xy = v.texcoord; 86 | 87 | float4 vr = _vpc - _viw; 88 | o.vr = vr; 89 | float s = sqrt( pow((vr.x),2) + pow((vr.y),2) + pow((vr.z),2)); 90 | o.svc = sqrt( 1 - s * s); // To decrease number of operations in fragment shader 91 | 92 | //You need this otherwise the screen flips and weird stuff happens 93 | #ifdef SHADER_API_D3D9 94 | if (_MainTex_TexelSize.y < 0) 95 | o.uv1.y = 1.0- o.uv1.y; 96 | #endif 97 | 98 | return o; 99 | } 100 | 101 | 102 | float3 RGBToXYZC( float r, float g, float b) 103 | { 104 | float3 xyz; 105 | xyz.x = 0.135134*r + 0.120531*g + 0.0570346*b; 106 | xyz.y = 0.0669015*r + 0.23295*g + 0.0291481*b; 107 | xyz.z = 0.0*r + 0.0000247454*g + 0.358275*b; 108 | return xyz; 109 | } 110 | float3 XYZToRGBC( float x, float y, float z) 111 | { 112 | float3 rgb; 113 | rgb.x = 9.94832*x -5.14725*y - 1.16493*z; 114 | rgb.y = -2.91664*x + 5.85296*y - 0.0379474*z; 115 | rgb.z = 0.000197335*x - 0.000398597*y + 2.79115*z; 116 | 117 | return rgb; 118 | } 119 | float3 weightFromXYZCurves(float3 xyz) 120 | { 121 | float3 returnVal; 122 | returnVal.x = 0.0735764 * xyz.x -0.0380683 * xyz.y - 0.00861569 * xyz.z; 123 | returnVal.y = -0.0665233 * xyz.x + 0.13437 * xyz.y - 0.000341907 * xyz.z; 124 | returnVal.z = 0.00000345602 * xyz.x - 0.0000069808 * xyz.y + 0.0485362 * xyz.z; 125 | return returnVal; 126 | } 127 | 128 | float getXFromCurve(float3 param, float shift) 129 | { 130 | float top1 = param.x * xla * exp( (float)(-(pow((param.y*shift) - xlb,2) 131 | /(2*(pow(param.z*shift,2)+pow(xlc,2))))))*sqrt( (float)(float(2)*(float)3.14159265358979323)); 132 | float bottom1 = sqrt((float)(1/pow(param.z*shift,2))+(1/pow(xlc,2))); 133 | 134 | float top2 = param.x * xha * exp( float(-(pow((param.y*shift) - xhb,2) 135 | /(2*(pow(param.z*shift,2)+pow(xhc,2))))))*sqrt( (float)(float(2)*(float)3.14159265358979323)); 136 | float bottom2 = sqrt((float)(1/pow(param.z*shift,2))+(1/pow(xhc,2))); 137 | 138 | return (top1/bottom1) + (top2/bottom2); 139 | } 140 | float getYFromCurve(float3 param, float shift) 141 | { 142 | float top = param.x * ya * exp( float(-(pow((param.y*shift) - yb,2) 143 | /(2*(pow(param.z*shift,2)+pow(yc,2))))))*sqrt( float(float(2)*(float)3.14159265358979323)); 144 | float bottom = sqrt((float)(1/pow(param.z*shift,2))+(1/pow(yc,2))); 145 | 146 | return top/bottom; 147 | } 148 | 149 | float getZFromCurve(float3 param, float shift) 150 | { 151 | float top = param.x * za * exp( float(-(pow((param.y*shift) - zb,2) 152 | /(2*(pow(param.z*shift,2)+pow(zc,2))))))*sqrt( float(float(2)*(float)3.14159265358979323)); 153 | float bottom = sqrt((float)(1/pow(param.z*shift,2))+(1/pow(zc,2))); 154 | 155 | return top/bottom; 156 | } 157 | 158 | float3 constrainRGB( float r, float g, float b) 159 | { 160 | float w; 161 | 162 | 163 | 164 | w = (0 < r) ? 0 : r; 165 | w = (w < g) ? w : g; 166 | w = (w < b) ? w : b; 167 | w = -w; 168 | 169 | 170 | 171 | if (w > 0) { 172 | r += w; g += w; b += w; 173 | } 174 | w = r; 175 | w = ( w < g) ? g : w; 176 | w = ( w < b) ? b : w; 177 | 178 | if ( w > 1 ) 179 | { 180 | r /= w; 181 | g /= w; 182 | b /= w; 183 | } 184 | float3 rgb; 185 | rgb.x = r; 186 | rgb.y = g; 187 | rgb.z = b; 188 | return rgb; 189 | 190 | }; 191 | 192 | //Per pixel or something like that 193 | float4 frag(v2f i) : COLOR 194 | { 195 | 196 | float x1 = i.pos2.x * 2*xs; 197 | float y1 = i.pos2.y * 2*xs/xyr; 198 | float z1 = i.pos2.z; 199 | 200 | float svc = (1-((x1*i.vr.x + y1*i.vr.y + z1*i.vr.z)/sqrt( x1 * x1 + y1 * y1 + z1 * z1)))/i.svc; 201 | 202 | if(_colorShift == 0) 203 | { 204 | svc = 1.0f; 205 | } 206 | //Get initial color 207 | float3 rgb = tex2D (_MainTex, i.uv1).rgb; 208 | float UV = tex2D( _UVTex, i.uv1).r; 209 | float IR = tex2D( _IRTex, i.uv1).r; 210 | 211 | float3 xyz = RGBToXYZC(float(rgb.x),float(rgb.y),float(rgb.z)); 212 | float3 weights = weightFromXYZCurves(xyz); 213 | float3 rParam,gParam,bParam,UVParam,IRParam; 214 | rParam.x = weights.x; rParam.y = ( float) 615; rParam.z = ( float)8; 215 | gParam.x = weights.y; gParam.y = ( float) 550; gParam.z = ( float)4; 216 | bParam.x = weights.z; bParam.y = ( float) 463; bParam.z = ( float)5; 217 | UVParam.x = 0.1; UVParam.y = UV_START + UV_RANGE*UV; UVParam.z = (float)1; 218 | IRParam.x = 0.1; IRParam.y = IR_START + IR_RANGE*IR; IRParam.z = (float)1; 219 | 220 | float xf = pow((1/svc),3)*(getXFromCurve(rParam, svc) + getXFromCurve(gParam,svc) + getXFromCurve(bParam,svc) + getXFromCurve(IRParam,svc) + getXFromCurve(UVParam,svc)); 221 | float yf = pow((1/svc),3)*(getYFromCurve(rParam, svc) + getYFromCurve(gParam,svc) + getYFromCurve(bParam,svc) + getYFromCurve(IRParam,svc) + getYFromCurve(UVParam,svc)); 222 | float zf = pow((1/svc),3)*(getZFromCurve(rParam, svc) + getZFromCurve(gParam,svc) + getZFromCurve(bParam,svc) + getZFromCurve(IRParam,svc) + getZFromCurve(UVParam,svc)); 223 | 224 | float3 rgbFinal = XYZToRGBC(xf,yf,zf); 225 | //rgbFinal = constrainRGB(rgbFinal.x,rgbFinal.y, rgbFinal.z); 226 | 227 | float4x4 temp = mul(1.0*unity_ObjectToWorld, unity_WorldToObject); 228 | float4 temp2 = mul( temp,float4( (float)rgbFinal.x,(float)rgbFinal.y,(float)rgbFinal.z,1)); 229 | //float4 temp2 =float4( (float)rgbFinal.x,(float)rgbFinal.y,(float)rgbFinal.z,1); 230 | return temp2; 231 | //float a = sizeof(float); 232 | //return float4( yf - 0.1,0,0,1); 233 | 234 | 235 | } 236 | 237 | ENDCG 238 | 239 | Subshader { 240 | 241 | Pass { 242 | Cull Off ZWrite On 243 | Fog { Mode off } 244 | Blend SrcAlpha OneMinusSrcAlpha 245 | 246 | CGPROGRAM 247 | 248 | #pragma fragmentoption ARB_precision_hint_nicest 249 | 250 | #pragma vertex vert 251 | #pragma fragment frag 252 | #pragma target 3.0 253 | 254 | ENDCG 255 | } 256 | } 257 | 258 | Fallback "Unlit/Texture" 259 | 260 | } // shader -------------------------------------------------------------------------------- /Assets/OpenRelativity/Shaders/skybox.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a8b469e68b8081c4b8475b25057170bd 3 | ShaderImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /InputManager - OSXPS3.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/InputManager - OSXPS3.asset -------------------------------------------------------------------------------- /InputManager - WindowsXBOX.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/InputManager - WindowsXBOX.asset -------------------------------------------------------------------------------- /MITLicense.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2013 Massachusetts Institute of Technology 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | } 4 | } 5 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/ClusterInputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshLayers.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/NavMeshLayers.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/PresetManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.3.1f1 2 | m_StandardAssetsVersion: 0 3 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITGameLab/OpenRelativity/35b806a1224ff96047c1ce3c907e7c68bb9e540e/ProjectSettings/UnityConnectSettings.asset -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenRelativity 2 | 3 | Welcome to OpenRelativity! This project is a spin-off from the MIT Game Lab's game A Slower Speed of Light. 4 | 5 | OpenRelativity is a set of tools for simulating the effects of traveling near the speed of light in the Unity3D game engine. We are producing this simple engine in the hopes that more developers or educators can use our toolset to produce more simulations or explorations of travel near the speed of light. 6 | 7 | Within this readme is a quick overview of each piece of code that we have put into this project, along with a very quick description of how to use the toolset to make sure your project follows the rules of relativity. We hope you can use this toolset to produce something amazing, and if you find bugs or have an improvement to make to the code base, feel free to help turn OpenRelativity into an even better project. 8 | 9 | ## Getting Started 10 | 11 | Just download the project and open the Unity scene. Everything should work out of the box. 12 | 13 | ### Prerequisities 14 | 15 | The only necessary component is Unity3D, available at [their website](https://unity3d.com/get-unity/download). 16 | 17 | 18 | ## OpenRelativity Limitations and Usage 19 | 20 | ### General Notes on Relativity and the Limitations of our Code: 21 | 22 | To most accurately simulate the effects of special relativity using our toolkit, please adhere to the following guidelines: 23 | 24 | 1. Only the player object may move freely. All other objects must either have a constant velocity originating at infinity and ending at infinity, or else be still. 25 | 26 | 2. The Player's speed must never reach or exceed the speed of light. 27 | 28 | 3. Due to constraint one, the other objects in the scene cannot travel in any direction but a straight line. 29 | 30 | 4. Because we did not write a new lighting system, all shadows must be permanent. That is, any shadow that is present on an object must be part of its texture and assumed to never change. DO NOT use the built in Unity lighting system with baked shadows unless no objects in the scene will ever disappear. Lighting and shadows are an extremely complicated field of special relativity, and they are not supported at this time. 31 | 32 | ### The Scene 33 | 34 | We have set up this project with a few basic settings that are meant to make our code base work smoothly. First, under Render Settings, we have the skybox's shader. This shader is slightly different from the one on every other object, and it also determines the basic texture of the sky. We do not work with anything other than solid colors, but if you would like to experiment with a more interesting texture on the skybox, feel free to do so. Next, under the Project Settings/Tags, we have a custom tag of "Playermesh" and a custom layer "Player." The Playermesh tag is used to access the top level player object, which contains the player's mesh and physical information. The Player layer is used to denote which objects should collide with the player. We currently have the Project Settings/Physics collision layers set up so that objects collide only with objects denoted "Player" and not with other objects in the scene. There is one exception to this, in the Receiver object, but that will be covered later. Apart from this, the scene is as it should be normally. 35 | 36 | ### The Player 37 | 38 | The player is already set up with our movement code, game state code, and a quick script that puts the speed of light and player speed on the screen. It is set up as a nested object. The player mesh is the parent object, which has the physical aspects of the player. It has a mesh renderer, a collider, and a rigidbody. Each of these components is necessary for our code base. Any of these attributes can be modified, but if the rigidbody's drag, gravity, or frozen rotation settings are changed, the project will no longer adhere to the rules of special relativity and it may react unpredictably with our code, so please don't change these settings unless you know what you're doing. If you wish to change the player's mesh, that won't cause any problems, but keep in mind that this framework was meant to provide a first-person view of relativity, and anything but a first person view will no longer be physically accurate. 39 | 40 | At the second level, we have the Player gameobject, which is where we keep the code. There are three pieces of code on the player character. Movement Scripts takes care of the player's movement, the camera's movement, and the change in the speed of light by user input. Game State keeps track of many important variables for the relativistic effects, and controls pausing and ending the game. 41 | 42 | Finally, we have the camera. The camera does not have any scripts on it, but is affected by Movement Scripts and must be attached to the player or else the perspective will be off. 43 | 44 | ### Other Objects 45 | 46 | By a few simple steps, any object can be added to the scene of Open Relativity. These steps mostly consist of adding the following components to your new object. 47 | 48 | The object must have a Mesh Filter with a mesh attached to it. Any mesh will do, regardless of complexity. 49 | 50 | The object must have a Collider attached to it. Box Colliders work great and are the simplest. Mesh colliders will most likely not work well, and they will definitely not conform to the Lorenz contraction because we do that in the graphics card, not in scripts. 51 | 52 | The object must have a Mesh Renderer. As in constraint four, we do not have a lighting system, so it is best if you uncheck "cast shadows" and "receive shadows" in the Mesh Renderer. Any materials that are a part of the Mesh Renderer must use the ColorShift shader. Note that they do not need to use the relativity materials that are in the project, but they do need to have the ColorShift shader (the Relativity/ColorShift option in the Shader drop down menu) in order to function properly. 53 | 54 | The object must have a rigidbody with gravity unchecked, 100 mass and infinite drag. 55 | 56 | Finally, the object must have the script "RelativisticObject" attached to it. If the objects VIW (Velocity In World) is set to anything but (0,0,0), it will move constantly while the scene is playing. 57 | 58 | With these components added to your new object, they will deform and change color according to the rules of special relativity. That's all it takes! 59 | 60 | 61 | ## Code Overview 62 | 63 | ### Relativistic Object / Relativistic Parent 64 | 65 | Relativistic Object is the base code for all the non-player objects in the scene. Combined with the Relativity shader, it keeps track of relatvistic effects,moves the object if needed, and performs necessary actions for the shader to work. It first forces the object to have a unique material, so that the object's shader uses variables specific to that object, and not across all objects using the relativity shader (which is what would happen if we did nothing). It also keeps track of when the object was created and when it is supposed to disappear, so that the time-distorting effects of special relativity do not accidentally force the object to appear before its start location or after its disappearance. 66 | 67 | Relativistic Parent is much the same as Relativistic Object. However, for complex parented objects with many smaller parts, each with their own materials, it vastly increases the speed of the engine if they are all kept on a single object. This code takes all the meshes of the parent object's children and combines them with its own, attaching the materials and textures necessary to the correct submeshes. There is one important problem: I do not combine the colliders of the child objects, so it is important that the parent object's collider contains within it all of the child objects, or else the player will be able to clip through their meshes as only the parent's collider remains after the combining of all the meshes. 68 | ### Firework 69 | Firework is identical to Relativistic Object except that there is also a timer on the object. When it dies, it releases a cloud of particles. This behavior is mostly to show the possibilities of working with timers. As you lower the speed of light and the fireworks travel closer to the speed of light, you will notice they last longer (as will their particles) due to time dilation. 70 | ### Movement Scripts 71 | 72 | Movement Scripts is what takes player input for the mouse and keyboard and moves the player accordingly. This code covers player movement, camera movement, and change in the speed of light. The movement follows a formula for relativistic velocity addition, which is included in the comments before the movement code. It is also currently set for free movement in three dimensions. If you wish to constrain the player to a flat ground plane (the X-Z plane, in Unity) then there are a couple lines of code that are marked for easy change. 73 | 74 | ### Info Script 75 | 76 | This just displays the two text boxes in the upper-left corner, using info from Game State. 77 | 78 | ### Game State 79 | 80 | Game State is the brain of the Open Relativity code. It stores important variables for relativistic effects and keeps track of changes in the player's status. Relativistic Object and Movement Scripts rely on being able to find Game State and access its information. It also keeps track of the pause state of the game, letting all other objects query game state rather than keeping track of it themselves. 81 | 82 | ### Object Mesh Density 83 | 84 | Object Mesh density takes a constant value (named constant). It searches over the triangles on the mesh of the object that it is attached to. If it finds a triangle with an area greater than the constant value, it splits that triangle into four smaller triangles, in a way that still works effectively with the relativistic code. The reason for this code is that the Lorenz contraction looks better with a higher concentration of vertices (since it is a vertex shader). Using this will slow down your startup, as the code is (currently) fairly inefficient because we never used it in the game. I hope to make this faster soon. 85 | 86 | ### Relativity Shader 87 | 88 | This shader implements a vertex shader that runs the Lorenz contraction, and a fragment shader that implements the relativistic Doppler shift. More detail is available in the comments of the code, in a line-by-line explanation. 89 | 90 | ### Skybox Shader 91 | 92 | This shader implements relativistic Doppler shift on the skybox, because the Lorenz contraction does not work (and should not really be used) on the very low-vertex skybox. 93 | 94 | ### Receiver and Receiver2 Script 95 | 96 | This is the receiver side of the objects that create new moving characters. The receiver has to be given the transform of the sender object so that it knows where to face. Within the receiver object itself is the receiver2 object, whose only purpose is to know when the Moving Person object has entered its collider, and register a time for the Moving Person to delete itself. The receiver script simply takes a sender object's transform and points in that object's direction. The receiver2 script just has a collision modifier on it that causes any objects that collide with it to register a death time. 97 | 98 | ### Sender Script 99 | 100 | The Sender script is the other half of the objects that create moving characters. It takes the name of a prefab in the Resources/Gameobjects folder, time interval, a velocity, and a receiver's transform. On start up, it will point the object to look at the receiver, and at every interval specified will create a new Moving Person object. The Moving Person object will then move with a velocity specified in the Sender Script until it hits the Receiver2 object. 101 | 102 | ## Prefabs 103 | 104 | ### Receiver 105 | 106 | The Receiver object is made up of two separate objects. It has the Receiver as the parent object, and the Receiver2 as the child object. The meshes on this prefab can be changed without worry, as can the colliders. Be warned, however, that the collider for the Receiver2 object must be small enough that the Moving Person objects can enter the receiver before they disappear on colliding with the receiver2 object. In order to make the Receiver object work, it must be given a Sender object's transform, and the Sender must have the Receiver's transform. Also, the Receiver2 object and the Moving Person must collide with each other, while the Receiver object should not collide with the Moving Person object. This can be done by editing the layers of the Receiver2 and Receiver object. 107 | 108 | ### Sender 109 | 110 | The Sender object is much simpler than the Receiver object. It just requires the Sender script and the transform of a Receiver. The mesh on this object can also be changed to anything else, as can its collider as there are no restrictions on the size of the collider or the mesh. 111 | 112 | If you choose to leave the receiver to transform blank and point it to a prefab with the firework script, it will launch self-deleting objects. 113 | 114 | 115 | ### Moving Person 116 | 117 | This is the object that will be created at a Sender and move towards a Receiver. There is nothing to change on the scripts in the Moving Person object, as everything is specified by the Sender that creates the Moving Person. The mesh and collider on the Moving Person can also be modified without changing the function of the Moving Person. 118 | 119 | ### Firework Launcher 120 | 121 | Essentially a sender object that specifically references the Firework instead of a Moving Person. 122 | 123 | ### Firework 124 | 125 | This object uses the Firework script and is referenced by the Firework Launcher prefab. Its timer and number of launched particles are set to reasonable numbers for the scene, but can be tweaked at will. 126 | 127 | ### Particle 128 | 129 | A simple cube to be used as the "explosion" effect of a Firework. 130 | 131 | ## Materials 132 | 133 | The materials that come provided with Open Relativity are built to work with the relativity shader. If you have an object that you want to create a new material for, you must make sure the material has the following properties. It must use the relativity shader, and if you want it to have IR or UV spectrum wavelengths on it, the IR/UV textures in the material must have a grayscale image. 134 | 135 | ## Controller Support 136 | OpenRelativity has two separate InputManager.asset files that should be switched out depending on your target platform. The standard one (that is already in the project) is designed to work on Windows with an Xbox 360 controller. The file labeled InputManager - OSXPS3 is built to use a PS3 controller on OSX platforms. Simply rename the file "InputManager.asset" and replace the existing InputManager.asset file in the Project Settings folder to change which configuration you use. Again, these configurations are for both separate platforms and separate controllers. 137 | 138 | The controls are as follows: 139 | 140 | - Movement: left analog stick 141 | - Camera Movement: right analog stick 142 | - Invert Camera Y Axis: Y/Triangle button 143 | - Toggle Color Effects: B/Circle Button 144 | - Pause/Unpause Game: Start Button 145 | - Change C: Left/Right D-Pad keys 146 | 147 | ## License 148 | 149 | This project is licensed under the MIT License - see the [LICENSE](MITLicense.md) file for details 150 | 151 | ## Acknowledgments 152 | 153 | Thank you to Gerd Kortemeyer and the MIT Game Lab for their contribution and instruction on this project. 154 | 155 | Thanks to users Barnacle Nightshade, Tiago Morais Morgado, tyoc213, matthewh806, and sethwoodworth for contributing to the repo! 156 | --------------------------------------------------------------------------------