BITFALL/Assets/Plugins/CW/PaintIn3D/Required/Script/P3dCommandSphere.cs

310 lines
9.9 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using CW.Common;
namespace PaintIn3D
{
/// <summary>This class manages the sphere painting command.</summary>
public class P3dCommandSphere : P3dCommand
{
public P3dBlendMode Blend;
public bool In3D;
public Vector3 Position;
public Vector3 EndPosition;
public Vector3 Position2;
public Vector3 EndPosition2;
public int Extrusions;
public bool Clip;
public Matrix4x4 Matrix;
public Color Color;
public float Opacity;
public float Hardness;
public P3dHashedTexture TileTexture;
public Matrix4x4 TileMatrix;
public float TileOpacity;
public float TileTransition;
public Matrix4x4 MaskMatrix;
public P3dHashedTexture MaskShape;
public Vector4 MaskChannel;
public Vector3 MaskStretch;
public P3dRenderDepth DepthMask;
public static P3dCommandSphere Instance = new P3dCommandSphere();
private static Stack<P3dCommandSphere> pool = new Stack<P3dCommandSphere>();
private static Material cachedSpotMaterial;
private static Material cachedLineMaterial;
private static Material cachedQuadMaterial;
private static Material cachedLineClipMaterial;
private static Material cachedQuadClipMaterial;
private static int cachedSpotMaterialHash;
private static int cachedLineMaterialHash;
private static int cachedQuadMaterialHash;
private static int cachedLineClipMaterialHash;
private static int cachedQuadClipMaterialHash;
public override bool RequireMesh { get { return true; } }
private static int _In3D = Shader.PropertyToID("_In3D");
private static int _Position = Shader.PropertyToID("_Position");
private static int _EndPosition = Shader.PropertyToID("_EndPosition");
private static int _Position2 = Shader.PropertyToID("_Position2");
private static int _EndPosition2 = Shader.PropertyToID("_EndPosition2");
private static int _Matrix = Shader.PropertyToID("_Matrix");
private static int _Color = Shader.PropertyToID("_Color");
private static int _Opacity = Shader.PropertyToID("_Opacity");
private static int _Hardness = Shader.PropertyToID("_Hardness");
private static int _TileTexture = Shader.PropertyToID("_TileTexture");
private static int _TileMatrix = Shader.PropertyToID("_TileMatrix");
private static int _TileOpacity = Shader.PropertyToID("_TileOpacity");
private static int _TileTransition = Shader.PropertyToID("_TileTransition");
private static int _MaskMatrix = Shader.PropertyToID("_MaskMatrix");
private static int _MaskTexture = Shader.PropertyToID("_MaskTexture");
private static int _MaskChannel = Shader.PropertyToID("_MaskChannel");
private static int _MaskStretch = Shader.PropertyToID("_MaskStretch");
private static int _DepthMatrix = Shader.PropertyToID("_DepthMatrix");
private static int _DepthTexture = Shader.PropertyToID("_DepthTexture");
private static int _DepthBias = Shader.PropertyToID("_DepthBias");
static P3dCommandSphere()
{
BuildMaterial(ref cachedSpotMaterial, ref cachedSpotMaterialHash, "Hidden/Paint in 3D/Sphere");
BuildMaterial(ref cachedLineMaterial, ref cachedLineMaterialHash, "Hidden/Paint in 3D/Sphere", "P3D_LINE");
BuildMaterial(ref cachedQuadMaterial, ref cachedQuadMaterialHash, "Hidden/Paint in 3D/Sphere", "P3D_QUAD");
BuildMaterial(ref cachedLineClipMaterial, ref cachedLineClipMaterialHash, "Hidden/Paint in 3D/Sphere", "P3D_LINE_CLIP");
BuildMaterial(ref cachedQuadClipMaterial, ref cachedQuadClipMaterialHash, "Hidden/Paint in 3D/Sphere", "P3D_QUAD_CLIP");
}
public override void Apply(Material material)
{
base.Apply(material);
Blend.Apply(material);
var inv = Matrix.inverse;
material.SetFloat(_In3D, In3D ? 1.0f : 0.0f);
material.SetVector(_Position, inv.MultiplyPoint(Position));
material.SetVector(_EndPosition, inv.MultiplyPoint(EndPosition));
material.SetVector(_Position2, inv.MultiplyPoint(Position2));
material.SetVector(_EndPosition2, inv.MultiplyPoint(EndPosition2));
material.SetMatrix(_Matrix, inv);
material.SetColor(_Color, CwHelper.ToLinear(Color));
material.SetFloat(_Opacity, Opacity);
material.SetFloat(_Hardness, Hardness);
material.SetTexture(_TileTexture, TileTexture);
material.SetMatrix(_TileMatrix, TileMatrix);
material.SetFloat(_TileOpacity, TileOpacity);
material.SetFloat(_TileTransition, TileTransition);
material.SetMatrix(_MaskMatrix, MaskMatrix);
material.SetTexture(_MaskTexture, MaskShape);
material.SetVector(_MaskChannel, MaskChannel);
material.SetVector(_MaskStretch, MaskStretch);
if (DepthMask != null)
{
material.SetTexture(_DepthTexture, DepthMask.TargetTexture);
material.SetFloat(_DepthBias, DepthMask.Bias);
material.SetMatrix(_DepthMatrix, DepthMask.SourceMatrix);
}
else
{
material.SetTexture(_DepthTexture, null);
material.SetFloat(_DepthBias, -1.0f);
material.SetMatrix(_DepthMatrix, Matrix4x4.identity);
}
}
public override void Pool()
{
pool.Push(this);
}
public override void Transform(Matrix4x4 posMatrix, Matrix4x4 rotMatrix, Matrix4x4 rotMatrix2)
{
Position = posMatrix.MultiplyPoint(Position);
EndPosition = posMatrix.MultiplyPoint(EndPosition);
Position2 = posMatrix.MultiplyPoint(Position2);
EndPosition2 = posMatrix.MultiplyPoint(EndPosition2);
Matrix = rotMatrix * Matrix * rotMatrix2;
}
public override P3dCommand SpawnCopy()
{
var command = SpawnCopy(pool);
command.Blend = Blend;
command.In3D = In3D;
command.Position = Position;
command.EndPosition = EndPosition;
command.Position2 = Position2;
command.EndPosition2 = EndPosition2;
command.Extrusions = Extrusions;
command.Clip = Clip;
command.Matrix = Matrix;
command.Color = Color;
command.Opacity = Opacity;
command.Hardness = Hardness;
command.TileTexture = TileTexture;
command.TileMatrix = TileMatrix;
command.TileOpacity = TileOpacity;
command.TileTransition = TileTransition;
command.MaskMatrix = MaskMatrix;
command.MaskShape = MaskShape;
command.MaskChannel = MaskChannel;
command.MaskStretch = MaskStretch;
command.DepthMask = DepthMask;
return command;
}
public override void Apply(P3dPaintableTexture paintableTexture)
{
base.Apply(paintableTexture);
if (Blend.Index == P3dBlendMode.REPLACE_ORIGINAL || Blend.Index == P3dBlendMode.NORMAL_REPLACE_ORIGINAL)
{
Blend.Color = paintableTexture.Color;
Blend.Texture = paintableTexture.Texture;
}
}
public void SetLocation(Vector3 position, bool in3D = true)
{
In3D = in3D;
Extrusions = 0;
Clip = false;
Position = position;
}
public void SetLocation(Vector3 position, Vector3 endPosition, bool in3D = true, bool clip = false)
{
In3D = in3D;
Extrusions = 1;
Clip = clip;
Position = position;
EndPosition = endPosition;
}
public void SetLocation(Vector3 positionA, Vector3 positionB, Vector3 positionC, bool in3D = true)
{
In3D = in3D;
Extrusions = 2;
Clip = false;
Position = positionA;
EndPosition = positionB;
Position2 = positionC;
EndPosition2 = positionA;
}
public void SetLocation(Vector3 position, Vector3 endPosition, Vector3 position2, Vector3 endPosition2, bool in3D = true, bool clip = false)
{
In3D = in3D;
Extrusions = 2;
Clip = clip;
Position = position;
EndPosition = endPosition;
Position2 = position2;
EndPosition2 = endPosition2;
}
public void ClearMask()
{
MaskShape = null;
MaskChannel = Vector3.one;
}
public void SetMask(Matrix4x4 matrix, Texture shape, P3dChannel channel, Vector3 stretch)
{
MaskMatrix = matrix;
MaskShape = shape;
MaskChannel = P3dCommon.IndexToVector((int)channel);
MaskStretch = new Vector3(2.0f / stretch.x, 2.0f / stretch.y, 2.0f);
}
public void ApplyAspect(Texture texture)
{
if (texture != null)
{
var width = texture.width;
var height = texture.height;
if (width > height)
{
Matrix.m00 *= height / (float)width;
}
else
{
Matrix.m00 *= width / (float)height;
}
}
}
public void SetShape(float radius)
{
Matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one * radius);
}
public void SetShape(Quaternion rotation, Vector3 size, float angle)
{
if (In3D == true)
{
Matrix = Matrix4x4.TRS(Vector3.zero, rotation * Quaternion.Euler(0.0f, 0.0f, angle), size);
}
else
{
Matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0.0f, 0.0f, angle), size);
}
}
public void SetMaterial(P3dBlendMode blendMode, float hardness, Color color, float opacity, Texture tileTexture, Matrix4x4 tileMatrix, float tileOpacity, float tileTransition)
{
switch (Extrusions)
{
case 0:
{
Material = new P3dHashedMaterial(cachedSpotMaterial, cachedSpotMaterialHash);
}
break;
case 1:
{
if (Clip == true)
{
Material = new P3dHashedMaterial(cachedLineClipMaterial, cachedLineClipMaterialHash);
}
else
{
Material = new P3dHashedMaterial(cachedLineMaterial, cachedLineMaterialHash);
}
}
break;
case 2:
{
if (Clip == true)
{
Material = new P3dHashedMaterial(cachedQuadClipMaterial, cachedQuadClipMaterialHash);
}
else
{
Material = new P3dHashedMaterial(cachedQuadMaterial, cachedQuadMaterialHash);
}
}
break;
}
Blend = blendMode;
Pass = blendMode;
Hardness = hardness;
Color = color;
Opacity = opacity;
TileTexture = tileTexture;
TileMatrix = tileMatrix;
TileOpacity = tileOpacity;
TileTransition = tileTransition;
}
}
}