using System.Collections; using System.Collections.Generic; using Godot; using System; using System.Threading.Tasks; namespace Rokojori { public class MultiBakeModeOctahedral:MultiBakeModeImplementation { public readonly string octahedralShader = "res://addons/rokojori_action_library/External/Imposter/materials/shaders/ImpostorShader.gdshader"; public override MultiBaker.BakeMode GetBakeMode() { return MultiBaker.BakeMode.Octahedral; } public override int GetNumViews() { var views = multiBaker.octahedralSides * multiBaker.octahedralSides; return views; } public override void CreateMaterial( bool preview ) { var mb = multiBaker; var material = new ShaderMaterial(); material.Shader = ResourceLoader.Load( octahedralShader ) as Shader; material.SetShaderParameter( "isFullSphere", mb.octahedralFullSphere ); material.SetShaderParameter( "imposterFrames", Vector2.One * mb.octahedralSides ); Materials.Set( mb.X_outputMesh, material ); } public override void AssignMaterial( BakingMaterialMode mode, Texture2D texture ) { var mb = multiBaker; mb.CacheTexture( mode, texture ); var material = Materials.Get( mb.X_outputMesh ); if ( material == null ) { RJLog.Log( "Not the right material on mesh!" ); return; } if ( BakingMaterialMode.Albedo == mode || BakingMaterialMode.Preview == mode ) { material.SetShaderParameter( "imposterTextureAlbedo", texture ); } else if ( BakingMaterialMode.Normals == mode ) { material.SetShaderParameter( "imposterTextureNormal", texture ); } else if ( BakingMaterialMode.ORM == mode ) { material.SetShaderParameter( "imposterTextureOrm", texture ); } else if ( BakingMaterialMode.Depth == mode ) { material.SetShaderParameter( "imposterTextureDepth", texture ); } } public override void CreateBakes() { var fov = multiBaker.GetCameraFOV(); var distance = multiBaker.GetCameraDistance(); var outputScale = multiBaker.GetOutputScale(); var _bakers = multiBaker.bakers; var mb = multiBaker; _bakers.ForEach( b => { b.useCustomFOV = true; b.customFOV = fov; b.useCustomDistance = true; b.customDistance = distance; b.rotationMode = Baker.RotationMode.Quaternion; } ); var numTextures = GetNumViews(); var textureAlignment = TextureMerger.ComputeTextureAlignment( numTextures ); var toOP = 1f / ( mb.octahedralSides - 1 ); var index = 0; for ( int x = 0; x < mb.octahedralSides; x++ ) { for ( int y = 0; y < mb.octahedralSides; y++ ) { var inverseX = ( mb.octahedralSides - 1 ) - x; var inverseY = ( mb.octahedralSides - 1 ) - y; var octahedralPosition = new Vector2( y, inverseX ) * toOP; var normal = OctahedralMapping.Map( octahedralPosition, mb.octahedralFullSphere ); _bakers[ index ].rotationQuaternion = Math3D.LookRotation( normal, true ).Normalized().Inverse(); index ++; } } var qm = new QuadMesh(); mb.X_outputMesh.Mesh = qm; var magicScale = 0.75f; mb.X_outputMesh.Scale = Vector3.One * ( outputScale / mb.cameraZoom * magicScale); } } }