310 lines
9.9 KiB
C#
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;
|
|
}
|
|
}
|
|
} |