daily update on 20240407 by nitload youmu
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
// file="Camera.cs"
|
||||
// Project: StgSharp
|
||||
// AuthorGroup: Nitload Space
|
||||
// Copyright (c) Nitload Space. All rights reserved.
|
||||
//
|
||||
// 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:
|
||||
//
|
||||
// The above copyright notice and
|
||||
// this permission notice shall be included in all copies
|
||||
// or substantial portions of the Software.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------
|
||||
using StgSharp.Graphics;
|
||||
using StgSharp.Graphics.ShaderEdit;
|
||||
using StgSharp.Math;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace StgSharp.Graphic
|
||||
{
|
||||
public sealed class Camera : IglConvertable
|
||||
{
|
||||
|
||||
Uniform<Matrix44>[] convertedUniform ;
|
||||
|
||||
glHandleSet uniformHandle;
|
||||
internal bool _isLookAtAvailable;
|
||||
internal Matrix44 cameraAtt;
|
||||
internal vec3d cameraCoord;
|
||||
internal Matrix44 _lookAt;
|
||||
internal Matrix44 _projection;
|
||||
|
||||
public Camera()
|
||||
{
|
||||
cameraAtt = Matrix44.Unit;
|
||||
cameraCoord = Vec3d.Unit;
|
||||
_isLookAtAvailable = false;
|
||||
_lookAt = Matrix44.Unit;
|
||||
convertedUniform = new Uniform<Matrix44>[2];
|
||||
}
|
||||
|
||||
public Camera(vec3d position, vec3d target, vec3d up) : this()
|
||||
{
|
||||
SetLookAt(position, target, up);
|
||||
}
|
||||
|
||||
public Matrix44 LookAt
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_isLookAtAvailable)
|
||||
{
|
||||
return _lookAt;
|
||||
}
|
||||
Matrix44 att = cameraAtt;
|
||||
att.Colum1 = Linear.Normalize(att.Colum1);
|
||||
Matrix44 coord = Matrix44.Unit;
|
||||
coord.Colum3.vec -= cameraCoord.vec;
|
||||
_lookAt = att.Transpose * coord;
|
||||
_isLookAtAvailable = true;
|
||||
return _lookAt;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix44 Projection
|
||||
=> _projection;
|
||||
|
||||
public void MoveNear(float distance)
|
||||
{
|
||||
cameraCoord.Z -= distance;
|
||||
}
|
||||
|
||||
public void MoveRight(float distance)
|
||||
{
|
||||
cameraCoord.X -= distance;
|
||||
}
|
||||
|
||||
public void MoveUp(float distance)
|
||||
{
|
||||
cameraCoord.Y -= distance;
|
||||
}
|
||||
|
||||
public void Perspective(Radius fovy, Vec2d size, float zNear, float zFar)
|
||||
{
|
||||
if (fovy == Radius.Zero)
|
||||
{
|
||||
fovy = new Radius(0.000001f);
|
||||
}
|
||||
if (zFar == zNear)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float rad = fovy._radius;
|
||||
float aspect = size.X / size.Y;
|
||||
float tanHalfFovy = Scaler.Tan(rad / 2.0f);
|
||||
tanHalfFovy = tanHalfFovy==float.PositiveInfinity? float.MaxValue : tanHalfFovy;
|
||||
tanHalfFovy = tanHalfFovy == float.NegativeInfinity ? float.MinValue : tanHalfFovy;
|
||||
|
||||
_projection.Colum0.X = 1.0f / (aspect * tanHalfFovy);
|
||||
_projection.Colum1.Y = 1.0f / tanHalfFovy;
|
||||
_projection.Colum2.Z = (-(zFar + zNear)) / (zFar - zNear);
|
||||
_projection.Colum3.W = -1.0f;
|
||||
_projection.Colum2.Y = (-(2.0f * zFar * zNear)) / (zFar - zNear);
|
||||
}
|
||||
|
||||
public void Pitch(Radius r)
|
||||
{
|
||||
Matrix32 partialCoord = new Matrix32(
|
||||
cameraAtt.Colum1.vec,
|
||||
cameraAtt.Colum2.vec
|
||||
);
|
||||
Matrix22 rotation = new Matrix22(
|
||||
GeometryScaler.Cos(r), -GeometryScaler.Sin(r),
|
||||
GeometryScaler.Sin(r), -GeometryScaler.Cos(r)
|
||||
);
|
||||
|
||||
partialCoord *= rotation;
|
||||
cameraAtt.Colum1.vec = partialCoord.colum0.vec;
|
||||
cameraAtt.Colum2.vec = partialCoord.colum1.vec;
|
||||
}
|
||||
|
||||
public void SetLookAt(vec3d position, vec3d target, vec3d up)
|
||||
{
|
||||
vec3d direction = target - position;
|
||||
|
||||
Linear.Normalize(ref direction, ref up);
|
||||
vec3d right = Linear.Cross(up, direction);
|
||||
|
||||
cameraAtt.Colum0.vec = direction.vec;
|
||||
cameraAtt.Colum1.vec = up.vec;
|
||||
cameraAtt.Colum2.vec = right.vec;
|
||||
}
|
||||
|
||||
public void DisplayGLtypeDefinition()
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"struct camera\n" +
|
||||
"\t{{\n" +
|
||||
"\tmatrix4x4 Perspective;\n" +
|
||||
"\tmatrix4x4 View;\n" +
|
||||
"\t}}\n"
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all uniform related to this <see cref="Camera"/>.
|
||||
/// </summary>
|
||||
/// <param name="source">Shader program requires this camera.</param>
|
||||
/// <param name="uniformName">
|
||||
/// Name of all related uniforms.
|
||||
/// If you fallow form from <see cref="IglConvertable.DisplayGLtypeDefinition"/>
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public unsafe void GainAllUniforms(ShaderProgram source, params string[] uniformName)
|
||||
{
|
||||
GLcontext* gl = GL.api;
|
||||
uniformHandle = new glHandleSet(2);
|
||||
byte[] name1;
|
||||
byte[] name2;
|
||||
Console.WriteLine(uniformName.Length);
|
||||
switch (uniformName.Length)
|
||||
{
|
||||
case 2:
|
||||
name1 = Encoding.UTF8.GetBytes(uniformName[0]);
|
||||
name2 = Encoding.UTF8.GetBytes(uniformName[1]);
|
||||
fixed (byte* namePtr = name1)
|
||||
{
|
||||
uniformHandle[(uint)0].Value = gl->glGetUniformLocation(
|
||||
source.handle.Value, namePtr);
|
||||
}
|
||||
fixed (byte* namePtr = name2)
|
||||
{
|
||||
uniformHandle[(uint)1].Value = gl->glGetUniformLocation(
|
||||
source.handle.Value, namePtr);
|
||||
}
|
||||
convertedUniform[0] = Uniform<Matrix44>.FromHandle(uniformHandle[(uint)0]);
|
||||
convertedUniform[1] = Uniform<Matrix44>.FromHandle(uniformHandle[(uint)1]);
|
||||
break;
|
||||
case 1:
|
||||
name1 = Encoding.UTF8.GetBytes($"{uniformName[0]}.Perspective");
|
||||
name2 = Encoding.UTF8.GetBytes($"{uniformName[0]}.View");
|
||||
fixed (byte* namePtr = name1)
|
||||
{
|
||||
uniformHandle[(uint)0].Value = gl->glGetUniformLocation(
|
||||
source.handle.Value, namePtr);
|
||||
}
|
||||
fixed (byte* namePtr = name2)
|
||||
{
|
||||
uniformHandle[(uint)1].Value = gl->glGetUniformLocation(
|
||||
source.handle.Value, namePtr);
|
||||
}
|
||||
convertedUniform[0] = Uniform<Matrix44>.FromHandle(uniformHandle[(uint)0]);
|
||||
convertedUniform[1] = Uniform<Matrix44>.FromHandle(uniformHandle[(uint)1]);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
ShaderStruct IglConvertable.GetConvertedGLtype()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public unsafe void SetAllUniforms()
|
||||
{
|
||||
GL.SetValue(convertedUniform[0], _projection);
|
||||
GL.SetValue(convertedUniform[1], LookAt);
|
||||
}
|
||||
|
||||
~Camera()
|
||||
{
|
||||
if (uniformHandle != null)
|
||||
{
|
||||
uniformHandle.Release();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user