Added Support for SCISS SGC Warp/Blend

This commit is contained in:
Jonathan Fay 2017-08-08 10:42:48 -07:00
Родитель adc12c598e
Коммит bd1db0c74a
4 изменённых файлов: 4117 добавлений и 3439 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1501,6 +1501,13 @@ namespace TerraViewer
private void MakeDistortionGrid()
{
if (Config.UsingSgcWarpMap)
{
//MakeDistortionGridSgc();
MakeDistortionGridSgcWithBlend();
return;
}
Bitmap bmpBlend = new Bitmap(config.BlendFile);
FastBitmap fastBlend = new FastBitmap(bmpBlend);
Bitmap bmpDistort = new Bitmap(config.DistortionGrid);
@ -1608,6 +1615,318 @@ namespace TerraViewer
GC.SuppressFinalize(fastBlend);
}
private void MakeDistortionGridSgc()
{
int subX = config.DistortionGridWidth-1;
int subY = config.DistortionGridHeight-1;
if (distortIndexBuffer != null)
{
distortIndexBuffer.Dispose();
GC.SuppressFinalize(distortIndexBuffer);
}
if (distortVertexBuffer != null)
{
distortVertexBuffer.Dispose();
GC.SuppressFinalize(distortVertexBuffer);
}
distortIndexBuffer = new IndexBuffer11(typeof(int), (subX * subY * 6), RenderContext11.PrepDevice);
distortVertexBuffer = new PositionColorTexturedVertexBuffer11(((subX + 1) * (subY + 1)), RenderContext11.PrepDevice);
distortVertexCount = (subX + 1) * (subY + 1);
int index = 0;
// Create a vertex buffer
PositionColoredTextured[] verts = (PositionColoredTextured[])distortVertexBuffer.Lock(0, 0); // Lock the buffer (which will return our structs)
int x1, y1;
unsafe
{
double maxU = 0;
double maxV = 0;
double textureStepX = 1.0f / subX;
double textureStepY = 1.0f / subY;
for (y1 = 0; y1 <= subY; y1++)
{
double tv;
for (x1 = 0; x1 <= subX; x1++)
{
double tu;
index = y1 * (subX + 1) + x1;
Vector6 vec = config.DistortionGridVertices[x1, y1];
tu = vec.T;
tv = 1-vec.U;
//tu = (tu - .5f) * 1.7777778 + .5f;
if (tu > maxU)
{
maxU = tu;
}
if (tv > maxV)
{
maxV = tv;
}
float xx = ((float)x1 / subX) - .5f;
float yy = (((float)y1 / subY)) - .5f;
float difX = xx - vec.X;
float difY = vec.Y+yy;
verts[index].Position = new SharpDX.Vector4(xx,yy, .9f, 1f);
verts[index].Tu = (float)tu;
verts[index].Tv = (float)tv;
verts[index].Color = Color.FromArgb(255, 255, 255, 255);
}
}
distortVertexBuffer.Unlock();
distortTriangleCount = (subX) * (subY) * 2;
uint[] indexArray = (uint[])distortIndexBuffer.Lock();
index = 0;
for (y1 = 0; y1 < subY; y1++)
{
for (x1 = 0; x1 < subX; x1++)
{
// First triangle in quad
indexArray[index] = (uint)(y1 * (subX + 1) + x1);
indexArray[index + 1] = (uint)((y1 + 1) * (subX + 1) + x1);
indexArray[index + 2] = (uint)(y1 * (subX + 1) + (x1 + 1));
// Second triangle in quad
indexArray[index + 3] = (uint)(y1 * (subX + 1) + (x1 + 1));
indexArray[index + 4] = (uint)((y1 + 1) * (subX + 1) + x1);
indexArray[index + 5] = (uint)((y1 + 1) * (subX + 1) + (x1 + 1));
index += 6;
}
}
this.distortIndexBuffer.Unlock();
}
}
private void MakeDistortionGridSgcWithBlend()
{
Bitmap bmpBlend = new Bitmap(config.BlendFile);
FastBitmap fastBlend = new FastBitmap(bmpBlend);
fastBlend.LockBitmapRgb();
int subX = bmpBlend.Width - 1;
int subY = bmpBlend.Height -1;
if (distortIndexBuffer != null)
{
distortIndexBuffer.Dispose();
GC.SuppressFinalize(distortIndexBuffer);
}
if (distortVertexBuffer != null)
{
distortVertexBuffer.Dispose();
GC.SuppressFinalize(distortVertexBuffer);
}
GridSampler gridSampler = new GridSampler(bmpBlend.Width, bmpBlend.Height, config.DistortionGridWidth, config.DistortionGridHeight, config.DistortionGridVertices);
distortIndexBuffer = new IndexBuffer11(typeof(int), (subX * subY * 6), RenderContext11.PrepDevice);
distortVertexBuffer = new PositionColorTexturedVertexBuffer11(((subX + 1) * (subY + 1)), RenderContext11.PrepDevice);
distortVertexCount = (subX + 1) * (subY + 1);
int index = 0;
// Create a vertex buffer
PositionColoredTextured[] verts = (PositionColoredTextured[])distortVertexBuffer.Lock(0, 0); // Lock the buffer (which will return our structs)
int x1, y1;
unsafe
{
double maxU = 0;
double maxV = 0;
double textureStepX = 1.0f / subX;
double textureStepY = 1.0f / subY;
for (y1 = 0; y1 <= subY; y1++)
{
double tv;
for (x1 = 0; x1 <= subX; x1++)
{
double tu;
index = y1 * (subX + 1) + x1;
SharpDX.Vector2 sample = gridSampler.Sample(x1, y1);
tu = sample.X;
tv = 1-sample.Y;
if (tu > maxU)
{
maxU = tu;
}
if (tv > maxV)
{
maxV = tv;
}
verts[index].Position = new SharpDX.Vector4(((float)x1 / subX) - .5f, (((float)y1 / subY)) - .5f, .9f, 1f);
verts[index].Tu = (float)tu;
verts[index].Tv = (float)tv;
PixelDataRgb* pPixel = fastBlend.GetRgbPixel(x1, subY-y1);
verts[index].Color = Color.FromArgb(255, pPixel->red, pPixel->green, pPixel->blue);
}
}
distortVertexBuffer.Unlock();
distortTriangleCount = (subX) * (subY) * 2;
uint[] indexArray = (uint[])distortIndexBuffer.Lock();
index = 0;
for (y1 = 0; y1 < subY; y1++)
{
for (x1 = 0; x1 < subX; x1++)
{
// First triangle in quad
indexArray[index] = (uint)(y1 * (subX + 1) + x1);
indexArray[index + 1] = (uint)((y1 + 1) * (subX + 1) + x1);
indexArray[index + 2] = (uint)(y1 * (subX + 1) + (x1 + 1));
// Second triangle in quad
indexArray[index + 3] = (uint)(y1 * (subX + 1) + (x1 + 1));
indexArray[index + 4] = (uint)((y1 + 1) * (subX + 1) + x1);
indexArray[index + 5] = (uint)((y1 + 1) * (subX + 1) + (x1 + 1));
index += 6;
}
}
this.distortIndexBuffer.Unlock();
}
fastBlend.UnlockBitmap();
fastBlend.Dispose();
GC.SuppressFinalize(fastBlend);
}
private void MakeDistortionGridSgcWithBlend2()
{
Bitmap bmpBlend = new Bitmap(config.BlendFile);
FastBitmap fastBlend = new FastBitmap(bmpBlend);
fastBlend.LockBitmapRgb();
int subX = bmpBlend.Width - 1;
int subY = bmpBlend.Height - 1;
if (distortIndexBuffer != null)
{
distortIndexBuffer.Dispose();
GC.SuppressFinalize(distortIndexBuffer);
}
if (distortVertexBuffer != null)
{
distortVertexBuffer.Dispose();
GC.SuppressFinalize(distortVertexBuffer);
}
GridSampler gridSampler = new GridSampler(bmpBlend.Width, bmpBlend.Height, config.DistortionGridWidth, config.DistortionGridHeight, config.DistortionGridVertices);
distortIndexBuffer = new IndexBuffer11(typeof(int), (subX * subY * 6), RenderContext11.PrepDevice);
distortVertexBuffer = new PositionColorTexturedVertexBuffer11(((subX + 1) * (subY + 1)), RenderContext11.PrepDevice);
distortVertexCount = (subX + 1) * (subY + 1);
int index = 0;
// Create a vertex buffer
PositionColoredTextured[] verts = (PositionColoredTextured[])distortVertexBuffer.Lock(0, 0); // Lock the buffer (which will return our structs)
int x1, y1;
unsafe
{
double maxU = 0;
double maxV = 0;
double textureStepX = 1.0f / subX;
double textureStepY = 1.0f / subY;
for (y1 = 0; y1 <= subY; y1++)
{
double tv;
for (x1 = 0; x1 <= subX; x1++)
{
double tu;
index = y1 * (subX + 1) + x1;
SharpDX.Vector2 sample = gridSampler.Sample(x1, y1);
tu = sample.X;
tv = sample.Y;
if (tu > maxU)
{
maxU = tu;
}
if (tv > maxV)
{
maxV = tv;
}
verts[index].Position = new SharpDX.Vector4(((float)x1 / subX) - .5f, (1f - ((float)y1 / subY)) - .5f, .9f, 1f);
verts[index].Tu = (float)tu;
verts[index].Tv = (float)tv;
PixelDataRgb* pPixel = fastBlend.GetRgbPixel(x1, y1);
verts[index].Color = Color.FromArgb(255, pPixel->red, pPixel->green, pPixel->blue);
}
}
distortVertexBuffer.Unlock();
distortTriangleCount = (subX) * (subY) * 2;
uint[] indexArray = (uint[])distortIndexBuffer.Lock();
index = 0;
for (y1 = 0; y1 < subY; y1++)
{
for (x1 = 0; x1 < subX; x1++)
{
// First triangle in quad
indexArray[index] = (uint)(y1 * (subX + 1) + x1);
indexArray[index + 1] = (uint)((y1 + 1) * (subX + 1) + x1);
indexArray[index + 2] = (uint)(y1 * (subX + 1) + (x1 + 1));
// Second triangle in quad
indexArray[index + 3] = (uint)(y1 * (subX + 1) + (x1 + 1));
indexArray[index + 4] = (uint)((y1 + 1) * (subX + 1) + x1);
indexArray[index + 5] = (uint)((y1 + 1) * (subX + 1) + (x1 + 1));
index += 6;
}
}
this.distortIndexBuffer.Unlock();
}
fastBlend.UnlockBitmap();
fastBlend.Dispose();
GC.SuppressFinalize(fastBlend);
}
public static void BackgroundInit()
{
Grids.InitStarVertexBuffer(RenderContext11.PrepDevice);
@ -8083,6 +8402,7 @@ namespace TerraViewer
double right = m_nearPlane * 2 / (1 / Math.Tan((config.UpFov + config.DownFov) / 2 / 180 * Math.PI)) * aspect / 2;
double left = -right;
ProjMatrix = Matrix3d.PerspectiveOffCenterLH(
left,
right,

Просмотреть файл

@ -1,351 +1,599 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Windows.Forms;
namespace TerraViewer
{
public class Config
{
public Config()
{
if (File.Exists(@"c:\wwtconfig\config.xml"))
{
saveFilename = @"c:\wwtconfig\config.xml";
ReadFromXML(saveFilename);
}
else if (File.Exists(@"c:\config.xml"))
{
saveFilename = @"c:\config.xml";
ReadFromXML(saveFilename);
}
else if (File.Exists(@"c:\wwtconfig\config.xml"))
{
saveFilename = @"c:\wwtconfig\config.xml";
ReadFromXML(saveFilename);
}
}
public int MonitorCountX=1;
public int MonitorCountY=1;
public int MonitorX=0;
public int MonitorY=0;
public bool Master = true;
public int Width = 1920;
public int Height = 1200;
public double Bezel = 1.07;
public string ConfigFile;
public string BlendFile;
public string DistortionGrid;
public bool MultiProjector = false;
public bool MatrixValid = false;
private bool MultiChannelDome = false;
private bool multiChannelGlobe = false;
public bool MultiChannelDome1
{
get
{
return MultiChannelDome | (MultiProjector && !MatrixValid);
}
set { MultiChannelDome = value; }
}
public bool MultiChannelGlobe
{
get
{
return multiChannelGlobe;
}
set
{
multiChannelGlobe = value;
}
}
public bool UseDistrotionAndBlend
{
get
{
return !(String.IsNullOrEmpty(BlendFile) || String.IsNullOrEmpty(DistortionGrid));
}
}
//Frustum
public float Left;
public float Right;
public float Bottom;
public float Top;
public float Near;
public float Far;
public float Heading;
public float Pitch;
public float Roll;
public float DomeTilt;
public float DomeAngle;
public float DiffTilt;
public float UpFov;
public float DownFov;
public float Aspect = 1.39053104f;
public int NodeID = -1;
public int ClusterID = 0;
private string nodeDiplayName = "";
public float TotalDomeTilt
{
get
{
return DomeTilt + DiffTilt;
}
}
public string NodeDiplayName
{
get
{
if (nodeDiplayName == null)
{
return "Node " + NodeID;
}
return nodeDiplayName;
}
set { nodeDiplayName = value; }
}
public void ReadFromXML(string path)
{
XmlDocument doc;
if (!File.Exists(path))
{
return;
}
try
{
doc = new XmlDocument();
doc.Load(path);
XmlNode deviceConfigNode = doc.FirstChild.NextSibling;
XmlNode config = deviceConfigNode.FirstChild;
XmlNode deviceNode = config.FirstChild;
MonitorCountX = Convert.ToInt32(deviceNode.Attributes["MonitorCountX"].Value.ToString());
MonitorCountY = Convert.ToInt32(deviceNode.Attributes["MonitorCountY"].Value.ToString());
MonitorX = Convert.ToInt32(deviceNode.Attributes["MonitorX"].Value.ToString());
MonitorY = Convert.ToInt32(deviceNode.Attributes["MonitorY"].Value.ToString());
Master = Convert.ToBoolean(deviceNode.Attributes["Master"].Value.ToString());
if (deviceNode.Attributes["Width"] != null)
{
Width = Convert.ToInt32(deviceNode.Attributes["Width"].Value.ToString());
}
if (deviceNode.Attributes["Height"] != null)
{
Height = Convert.ToInt32(deviceNode.Attributes["Height"].Value.ToString());
}
if (deviceNode.Attributes["NodeID"] != null)
{
NodeID = Convert.ToInt32(deviceNode.Attributes["NodeID"].Value.ToString());
}
if (deviceNode.Attributes["ClusterID"] != null)
{
ClusterID = Convert.ToInt32(deviceNode.Attributes["ClusterID"].Value.ToString());
}
if (deviceNode.Attributes["NodeDiplayName"] != null)
{
NodeDiplayName = deviceNode.Attributes["NodeDiplayName"].Value;
}
if (deviceNode.Attributes["Bezel"] != null)
{
Bezel = Convert.ToDouble(deviceNode.Attributes["Bezel"].Value.ToString());
}
if (deviceNode.Attributes["Heading"] != null)
{
Heading = Convert.ToSingle(deviceNode.Attributes["Heading"].Value.ToString());
}
if (deviceNode.Attributes["Pitch"] != null)
{
Pitch = Convert.ToSingle(deviceNode.Attributes["Pitch"].Value.ToString());
}
if (deviceNode.Attributes["Roll"] != null)
{
Roll = Convert.ToSingle(deviceNode.Attributes["Roll"].Value.ToString());
}
if (deviceNode.Attributes["UpFov"] != null)
{
UpFov = Convert.ToSingle(deviceNode.Attributes["UpFov"].Value.ToString());
}
if (deviceNode.Attributes["DownFov"] != null)
{
DownFov = Convert.ToSingle(deviceNode.Attributes["DownFov"].Value.ToString());
}
if (deviceNode.Attributes["DomeTilt"] != null)
{
DomeTilt = Convert.ToSingle(deviceNode.Attributes["DomeTilt"].Value.ToString());
}
if (deviceNode.Attributes["DomeAngle"] != null)
{
DomeAngle = Convert.ToSingle(deviceNode.Attributes["DomeAngle"].Value.ToString());
}
if (deviceNode.Attributes["DiffTilt"] != null)
{
DiffTilt = Convert.ToSingle(deviceNode.Attributes["DiffTilt"].Value.ToString());
}
if (deviceNode.Attributes["Aspect"] != null)
{
Aspect = Convert.ToSingle(deviceNode.Attributes["Aspect"].Value.ToString());
}
if (deviceNode.Attributes["MultiChannelDome"] != null)
{
MultiChannelDome = Convert.ToBoolean(deviceNode.Attributes["MultiChannelDome"].Value.ToString());
}
if (deviceNode.Attributes["MultiChannelGlobe"] != null)
{
MultiChannelGlobe = Convert.ToBoolean(deviceNode.Attributes["MultiChannelGlobe"].Value.ToString());
}
if (deviceNode.Attributes["ConfigFile"] != null)
{
ConfigFile = deviceNode.Attributes["ConfigFile"].Value.ToString();
ParseConfigFile();
}
if (deviceNode.Attributes["BlendFile"] != null)
{
BlendFile = deviceNode.Attributes["BlendFile"].Value.ToString();
}
if (deviceNode.Attributes["DistortionGrid"] != null)
{
DistortionGrid = deviceNode.Attributes["DistortionGrid"].Value.ToString();
}
MultiProjector = !(String.IsNullOrEmpty(ConfigFile) || String.IsNullOrEmpty(BlendFile) || String.IsNullOrEmpty(DistortionGrid));
// UseDistrotionAndBlend = !( String.IsNullOrEmpty(BlendFile) || String.IsNullOrEmpty(DistortionGrid));
// MultiProjector = true;
}
catch
{
}
return;
}
public Matrix3d ViewMatrix = Matrix3d.Identity;
private void ParseConfigFile()
{
if (String.IsNullOrEmpty(ConfigFile))
{
return;
}
string[] configFileData = File.ReadAllLines(ConfigFile);
for (int i=0; i < configFileData.Length; i++)
{
configFileData[i] = configFileData[i].Trim();
}
for (int i=0; i < configFileData.Length; i++)
{
if (configFileData[i].StartsWith("Frustum"))
{
string[] frustParts = configFileData[i].Split( new char[] {' ',';'});
if (frustParts.Length == 8)
{
Left = Convert.ToSingle(frustParts[1]);
Right = Convert.ToSingle(frustParts[2]);
Bottom = Convert.ToSingle(frustParts[3]);
Top = Convert.ToSingle(frustParts[4]);
Near = Convert.ToSingle(frustParts[5]);
Far = Convert.ToSingle(frustParts[6]);
}
}
if (configFileData[i].StartsWith("Rotate"))
{
string[] frustParts = configFileData[i].Split(new char[] { ' ',';' });
float angle = 0;
float x = 0;
float y = 0;
float z = 0;
if (frustParts.Length == 6)
{
angle = (float)(Convert.ToDouble(frustParts[1])/180*Math.PI);
x = Convert.ToSingle(frustParts[2]);
y = Convert.ToSingle(frustParts[3]);
z = Convert.ToSingle(frustParts[4]);
Matrix3d mat = new Matrix3d();
mat.Matrix11 = SharpDX.Matrix.RotationAxis(new SharpDX.Vector3(x, y, z), angle);
ViewMatrix = mat * ViewMatrix;
}
}
}
MatrixValid = true;
}
string saveFilename = @"c:\wwtconfig\config.xml";
public bool SaveToXml()
{
try
{
StringBuilder sb = new StringBuilder();
sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n");
sb.Append("<DeviceConfig>\r\n");
{
sb.Append("<Config>\r\n");
sb.Append(String.Format("<Device ClusterID=\"{21}\" NodeID=\"{19}\" NodeDiplayName=\"{20}\" MonitorCountX=\"{0}\" MonitorCountY=\"{1}\" MonitorX=\"{2}\" MonitorY=\"{3}\" Master=\"{4}\" Width=\"{5}\" Height=\"{6}\" Bezel=\"{7}\" ConfigFile=\"{8}\" BlendFile=\"{9}\" DistortionGrid=\"{10}\" Heading=\"{11}\" Pitch=\"{12}\" Roll=\"{13}\" UpFov=\"{14}\" DownFov=\"{15}\" MultiChannelDome=\"{16}\" DomeTilt=\"{17}\" Aspect=\"{18}\" DiffTilt=\"{22}\" MultiChannelGlobe=\"{23}\" DomeAngle=\"{24}\"></Device>\r\n",
MonitorCountX.ToString(), MonitorCountY.ToString(), MonitorX, MonitorY, Master.ToString(), Width.ToString(), Height.ToString(), Bezel.ToString(), ConfigFile, BlendFile, DistortionGrid, Heading, Pitch, Roll, UpFov, DownFov, MultiChannelDome.ToString(), DomeTilt, Aspect, NodeID.ToString(), NodeDiplayName, ClusterID.ToString(), DiffTilt.ToString(), MultiChannelGlobe.ToString(), DomeAngle.ToString()));
sb.Append("</Config>\r\n");
}
sb.Append("</DeviceConfig>\r\n");
// Create the file.
using (FileStream fs = File.Create(saveFilename))
{
Byte[] info =
new UTF8Encoding(true).GetBytes(sb.ToString());
fs.Write(info, 0, info.Length);
}
return true;
}
catch
{
return false;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Windows.Forms;
namespace TerraViewer
{
public class Config
{
public Config()
{
if (File.Exists(@"c:\wwtconfig\config.xml"))
{
saveFilename = @"c:\wwtconfig\config.xml";
ReadFromXML(saveFilename);
}
else if (File.Exists(@"c:\config.xml"))
{
saveFilename = @"c:\config.xml";
ReadFromXML(saveFilename);
}
else if (File.Exists(@"c:\wwtconfig\config.xml"))
{
saveFilename = @"c:\wwtconfig\config.xml";
ReadFromXML(saveFilename);
}
}
public int MonitorCountX = 1;
public int MonitorCountY = 1;
public int MonitorX = 0;
public int MonitorY = 0;
public bool Master = true;
public int Width = 1920;
public int Height = 1200;
public double Bezel = 1.07;
public string ConfigFile;
public string BlendFile;
public string DistortionGrid;
public int DistortionGridWidth = 1;
public int DistortionGridHeight = 1;
public bool UsingSgcWarpMap = false;
public bool MultiProjector = false;
public bool MatrixValid = false;
private bool MultiChannelDome = false;
private bool multiChannelGlobe = false;
public bool MultiChannelDome1
{
get
{
return MultiChannelDome | (MultiProjector && !MatrixValid);
}
set { MultiChannelDome = value; }
}
public bool MultiChannelGlobe
{
get
{
return multiChannelGlobe;
}
set
{
multiChannelGlobe = value;
}
}
public bool UseDistrotionAndBlend
{
get
{
return !(String.IsNullOrEmpty(BlendFile) || String.IsNullOrEmpty(DistortionGrid));
}
}
//Frustum
public float Left;
public float Right;
public float Bottom;
public float Top;
public float Near;
public float Far;
public float Heading;
public float Pitch;
public float Roll;
public float DomeTilt;
public float DomeAngle;
public float DiffTilt;
public float UpFov;
public float DownFov;
public float LeftFov;
public float RightFov;
public float Aspect = 1.39053104f;
public int NodeID = -1;
public int ClusterID = 0;
private string nodeDiplayName = "";
public float TotalDomeTilt
{
get
{
return DomeTilt + DiffTilt;
}
}
public string NodeDiplayName
{
get
{
if (nodeDiplayName == null)
{
return "Node " + NodeID;
}
return nodeDiplayName;
}
set { nodeDiplayName = value; }
}
public void ReadFromXML(string path)
{
XmlDocument doc;
if (!File.Exists(path))
{
return;
}
try
{
doc = new XmlDocument();
doc.Load(path);
XmlNode deviceConfigNode = doc.FirstChild.NextSibling;
XmlNode config = deviceConfigNode.FirstChild;
XmlNode deviceNode = config.FirstChild;
MonitorCountX = Convert.ToInt32(deviceNode.Attributes["MonitorCountX"].Value.ToString());
MonitorCountY = Convert.ToInt32(deviceNode.Attributes["MonitorCountY"].Value.ToString());
MonitorX = Convert.ToInt32(deviceNode.Attributes["MonitorX"].Value.ToString());
MonitorY = Convert.ToInt32(deviceNode.Attributes["MonitorY"].Value.ToString());
Master = Convert.ToBoolean(deviceNode.Attributes["Master"].Value.ToString());
if (deviceNode.Attributes["Width"] != null)
{
Width = Convert.ToInt32(deviceNode.Attributes["Width"].Value.ToString());
}
if (deviceNode.Attributes["Height"] != null)
{
Height = Convert.ToInt32(deviceNode.Attributes["Height"].Value.ToString());
}
if (deviceNode.Attributes["NodeID"] != null)
{
NodeID = Convert.ToInt32(deviceNode.Attributes["NodeID"].Value.ToString());
}
if (deviceNode.Attributes["ClusterID"] != null)
{
ClusterID = Convert.ToInt32(deviceNode.Attributes["ClusterID"].Value.ToString());
}
if (deviceNode.Attributes["NodeDiplayName"] != null)
{
NodeDiplayName = deviceNode.Attributes["NodeDiplayName"].Value;
}
if (deviceNode.Attributes["Bezel"] != null)
{
Bezel = Convert.ToDouble(deviceNode.Attributes["Bezel"].Value.ToString());
}
if (deviceNode.Attributes["Heading"] != null)
{
Heading = Convert.ToSingle(deviceNode.Attributes["Heading"].Value.ToString());
}
if (deviceNode.Attributes["Pitch"] != null)
{
Pitch = Convert.ToSingle(deviceNode.Attributes["Pitch"].Value.ToString());
}
if (deviceNode.Attributes["Roll"] != null)
{
Roll = Convert.ToSingle(deviceNode.Attributes["Roll"].Value.ToString());
}
if (deviceNode.Attributes["UpFov"] != null)
{
UpFov = Convert.ToSingle(deviceNode.Attributes["UpFov"].Value.ToString());
}
if (deviceNode.Attributes["DownFov"] != null)
{
DownFov = Convert.ToSingle(deviceNode.Attributes["DownFov"].Value.ToString());
}
if (deviceNode.Attributes["DomeTilt"] != null)
{
DomeTilt = Convert.ToSingle(deviceNode.Attributes["DomeTilt"].Value.ToString());
}
if (deviceNode.Attributes["DomeAngle"] != null)
{
DomeAngle = Convert.ToSingle(deviceNode.Attributes["DomeAngle"].Value.ToString());
}
if (deviceNode.Attributes["DiffTilt"] != null)
{
DiffTilt = Convert.ToSingle(deviceNode.Attributes["DiffTilt"].Value.ToString());
}
if (deviceNode.Attributes["Aspect"] != null)
{
Aspect = Convert.ToSingle(deviceNode.Attributes["Aspect"].Value.ToString());
}
if (deviceNode.Attributes["MultiChannelDome"] != null)
{
MultiChannelDome = Convert.ToBoolean(deviceNode.Attributes["MultiChannelDome"].Value.ToString());
}
if (deviceNode.Attributes["MultiChannelGlobe"] != null)
{
MultiChannelGlobe = Convert.ToBoolean(deviceNode.Attributes["MultiChannelGlobe"].Value.ToString());
}
if (deviceNode.Attributes["ConfigFile"] != null)
{
ConfigFile = deviceNode.Attributes["ConfigFile"].Value.ToString();
ParseConfigFile();
}
if (deviceNode.Attributes["BlendFile"] != null)
{
BlendFile = deviceNode.Attributes["BlendFile"].Value.ToString();
}
if (deviceNode.Attributes["DistortionGrid"] != null)
{
DistortionGrid = deviceNode.Attributes["DistortionGrid"].Value.ToString();
}
MultiProjector = !(String.IsNullOrEmpty(ConfigFile) || String.IsNullOrEmpty(BlendFile) || String.IsNullOrEmpty(DistortionGrid));
// UseDistrotionAndBlend = !( String.IsNullOrEmpty(BlendFile) || String.IsNullOrEmpty(DistortionGrid));
// MultiProjector = true;
}
catch
{
}
return;
}
public Matrix3d ViewMatrix = Matrix3d.Identity;
private void ParseConfigFile()
{
if (String.IsNullOrEmpty(ConfigFile))
{
return;
}
if (ConfigFile.ToLower().EndsWith(".sgc"))
{
ReadSGCFile(ConfigFile);
return;
}
string[] configFileData = File.ReadAllLines(ConfigFile);
for (int i = 0; i < configFileData.Length; i++)
{
configFileData[i] = configFileData[i].Trim();
}
for (int i = 0; i < configFileData.Length; i++)
{
if (configFileData[i].StartsWith("Frustum"))
{
string[] frustParts = configFileData[i].Split(new char[] { ' ', ';' });
if (frustParts.Length == 8)
{
Left = Convert.ToSingle(frustParts[1]);
Right = Convert.ToSingle(frustParts[2]);
Bottom = Convert.ToSingle(frustParts[3]);
Top = Convert.ToSingle(frustParts[4]);
Near = Convert.ToSingle(frustParts[5]);
Far = Convert.ToSingle(frustParts[6]);
}
}
if (configFileData[i].StartsWith("Rotate"))
{
string[] frustParts = configFileData[i].Split(new char[] { ' ', ';' });
float angle = 0;
float x = 0;
float y = 0;
float z = 0;
if (frustParts.Length == 6)
{
angle = (float)(Convert.ToDouble(frustParts[1]) / 180 * Math.PI);
x = Convert.ToSingle(frustParts[2]);
y = Convert.ToSingle(frustParts[3]);
z = Convert.ToSingle(frustParts[4]);
Matrix3d mat = new Matrix3d();
mat.Matrix11 = SharpDX.Matrix.RotationAxis(new SharpDX.Vector3(x, y, z), angle);
ViewMatrix = mat * ViewMatrix;
}
}
}
MatrixValid = true;
}
//It's a binary file with the following format
//fileid: 3c
//version: B
//distortionType: I
//Quaternion: 4f
//position: 3f
//fov: 4f
//mesh width: I
//mesh height: I
//vertices: 3f per vertex
//numindices: I
//indices: I per index
public Vector6[,] DistortionGridVertices = null;
void ReadSGCFile(string filename)
{
FileStream s = new FileStream(filename, FileMode.Open);
BinaryReader br = new BinaryReader(s);
byte[] fileID = br.ReadBytes(3);
byte version = br.ReadByte();
Int32 distortionType = br.ReadInt32();
float[] quat = new float[4];
for (int i = 0; i < 4; i++)
{
quat[i] = br.ReadSingle();
}
float[] pos = new float[3];
for (int i = 0; i < 3; i++)
{
pos[i] = br.ReadSingle();
}
float up = br.ReadSingle();
float down = br.ReadSingle();
float left = br.ReadSingle();
float right = br.ReadSingle();
int meshWidth = br.ReadInt32();
int meshHeight = br.ReadInt32();
DistortionGridVertices = new Vector6[meshWidth, meshHeight];
Vector4d quaternion = new Vector4d(quat[0], quat[1], quat[2], quat[3]);
double roll=0;
double heading=0;
double pitch=0;
ToEulerianAngle(quaternion, out pitch, out roll, out heading);
float num2 = (float)(((2.0) / (1.0 / Math.Tan((Math.Abs(up) / 180.0) * Math.PI))) / 2.0);
float num3 = (float)(((2.0) / (1.0 / Math.Tan((Math.Abs(down) / 180.0) * Math.PI))) / 2.0);
float num4 = (float)(((2.0) / (1.0 / Math.Tan((Math.Abs(right) / 180.0) * Math.PI))) / 2.0);
float num5 = (float)(((2.0) / (1.0 / Math.Tan((Math.Abs(left) / 180.0) * Math.PI))) / 2.0);
Aspect = (num4 + num5) / (num2 + num3);
UpFov = Math.Abs(up);
DownFov = Math.Abs(down);
RightFov = Math.Abs(right);
LeftFov = Math.Abs(left);
Heading = (float)heading;
Pitch = (float)pitch;
Roll = -(float)roll;
DistortionGridWidth = meshWidth;
DistortionGridHeight = meshHeight;
UsingSgcWarpMap = true;
for (int y = 0; y < meshHeight; y++)
{
for (int x = 0; x < meshWidth; x++)
{
DistortionGridVertices[x, y] = new Vector6(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
}
}
int indexCount = br.ReadInt32();
int[] indices = new int[indexCount];
for (int i = 0; i < indexCount; i++)
{
indices[i] = br.ReadInt32();
}
int t = meshHeight * meshWidth;
br.Close();
}
static void ToEulerianAngle(Vector4d self, out double bank, out double attitude, out double heading)
{
double t = self.X * self.Y + self.Z * self.W;
if (t > 0.4999)
{
heading = 2 * Math.Atan2(self.X, self.W);
attitude = Math.PI / 2;
bank = 0;
}
else if (t < -0.4999)
{
heading = -2 * Math.Atan2(self.X, self.W);
attitude = -Math.PI / 2;
bank = 0;
}
else
{
double sqx = self.X * self.X;
double sqy = self.Y * self.Y;
double sqz = self.Z * self.Z;
heading = Math.Atan2(2 * self.Y * self.W - 2 * self.X * self.Z, 1 - 2 * sqy - 2 * sqz);
attitude = Math.Asin(2 * t);
bank = Math.Atan2(2 * self.X * self.W - 2 * self.Y * self.Z, 1 - 2 * sqx - 2 * sqz);
}
bank = bank / Math.PI * 180;
attitude = attitude / Math.PI * 180;
heading = heading / Math.PI * 180;
return;
//double ysqr = q.Y * q.Y;
//// roll (x-axis rotation)
//double t0 = +2.0 * (q.W * q.X + q.Y * q.Z);
//double t1 = +1.0 - 2.0 * (q.X * q.X + ysqr);
//roll = Math.Atan2(t0, t1) / Math.PI * 180;
//// pitch (y-axis rotation)
//double t2 = +2.0 * (q.W * q.Y - q.Z * q.X);
//t2 = ((t2 > 1.0) ? 1.0 : t2);
//t2 = ((t2 < -1.0) ? -1.0 : t2);
//pitch = Math.Asin(t2) / Math.PI * 180;
//// yaw (z-axis rotation)
//double t3 = +2.0 * (q.W * q.Z + q.X * q.Y);
//double t4 = +1.0 - 2.0 * (ysqr + q.Z * q.Z);
//yaw = Math.Atan2(t3, t4) / Math.PI * 180;
}
static void ToEulerianAngle2(Vector4d q, out double roll, out double pitch, out double yaw)
{
double ysqr = q.Y * q.Y;
// roll (x-axis rotation)
double t0 = +2.0 * (q.W * q.X + q.Y * q.Z);
double t1 = +1.0 - 2.0 * (q.X * q.X + ysqr);
roll = Math.Atan2(t0, t1) / Math.PI * 180;
// pitch (y-axis rotation)
double t2 = +2.0 * (q.W * q.Y - q.Z * q.X);
t2 = ((t2 > 1.0) ? 1.0 : t2);
t2 = ((t2 < -1.0) ? -1.0 : t2);
pitch = Math.Asin(t2) / Math.PI * 180;
// yaw (z-axis rotation)
double t3 = +2.0 * (q.W * q.Z + q.X * q.Y);
double t4 = +1.0 - 2.0 * (ysqr + q.Z * q.Z);
yaw = Math.Atan2(t3, t4) / Math.PI * 180;
}
string saveFilename = @"c:\wwtconfig\config.xml";
public bool SaveToXml()
{
try
{
StringBuilder sb = new StringBuilder();
sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n");
sb.Append("<DeviceConfig>\r\n");
{
sb.Append("<Config>\r\n");
sb.Append(String.Format("<Device ClusterID=\"{21}\" NodeID=\"{19}\" NodeDiplayName=\"{20}\" MonitorCountX=\"{0}\" MonitorCountY=\"{1}\" MonitorX=\"{2}\" MonitorY=\"{3}\" Master=\"{4}\" Width=\"{5}\" Height=\"{6}\" Bezel=\"{7}\" ConfigFile=\"{8}\" BlendFile=\"{9}\" DistortionGrid=\"{10}\" Heading=\"{11}\" Pitch=\"{12}\" Roll=\"{13}\" UpFov=\"{14}\" DownFov=\"{15}\" MultiChannelDome=\"{16}\" DomeTilt=\"{17}\" Aspect=\"{18}\" DiffTilt=\"{22}\" MultiChannelGlobe=\"{23}\" DomeAngle=\"{24}\"></Device>\r\n",
MonitorCountX.ToString(), MonitorCountY.ToString(), MonitorX, MonitorY, Master.ToString(), Width.ToString(), Height.ToString(), Bezel.ToString(), ConfigFile, BlendFile, DistortionGrid, Heading, Pitch, Roll, UpFov, DownFov, MultiChannelDome.ToString(), DomeTilt, Aspect, NodeID.ToString(), NodeDiplayName, ClusterID.ToString(), DiffTilt.ToString(), MultiChannelGlobe.ToString(), DomeAngle.ToString()));
sb.Append("</Config>\r\n");
}
sb.Append("</DeviceConfig>\r\n");
// Create the file.
using (FileStream fs = File.Create(saveFilename))
{
Byte[] info =
new UTF8Encoding(true).GetBytes(sb.ToString());
fs.Write(info, 0, info.Length);
}
return true;
}
catch
{
return false;
}
}
}
public struct Vector6
{
public float X;
public float Y;
public float Z;
public float T;
public float U;
public float V;
public Vector6(float x, float y, float z, float t, float u, float v)
{
X = x;
Y = y;
Z = z;
U = u;
V = v;
T = t;
}
}
public class GridSampler
{
Vector6[,] vertices = null;
public int Width = 0;
public int Height = 0;
public int GridWidth = 0;
public int GridHeight = 0;
public float xFac = 1;
public float yFac = 1;
public GridSampler(int width, int height, int gridWidth, int gridHeight, Vector6[,] verts)
{
vertices = verts;
Width = width;
Height = height;
GridHeight = gridHeight;
GridWidth = gridWidth;
xFac = ((float)GridWidth - 1) / (Width - 1);
yFac = ((float)GridHeight - 1) / (Height - 1);
}
public SharpDX.Vector2 Sample(int x, int y)
{
float xf = x * xFac;
float yf = y * yFac;
int x1 = (int)xf; // Whole part
int y1 = (int)yf; // Whole Part
float xa = xf - x1; //remainder
float ya = yf - y1; //remainder
//interpolate left to right
float ut = (vertices[x1, y1].T * (1 - xa)) + (vertices[Math.Min(GridWidth - 1, x1 + 1), y1].T * xa);
float ub = (vertices[x1, Math.Min(GridHeight - 1, y1 + 1)].T * (1 - xa)) + (vertices[Math.Min(GridWidth - 1, x1 + 1), Math.Min(GridHeight - 1, y1 + 1)].T * xa);
float vt = (vertices[x1, y1].U * (1 - xa)) + (vertices[Math.Min(GridWidth - 1, x1 + 1), y1].U * xa);
float vb = (vertices[x1, Math.Min(GridHeight - 1, y1 + 1)].U * (1 - xa)) + (vertices[Math.Min(GridWidth - 1, x1 + 1), Math.Min(GridHeight - 1, y1 + 1)].U * xa);
return new SharpDX.Vector2(ut * (1 - ya) + (ub * ya), vt * (1 - ya) + (vb * ya));
}
}
}

Просмотреть файл

@ -30,8 +30,8 @@ using System.Resources;
// Build Number
// Revision
//
[assembly: AssemblyVersion("5.5.22.1")]
[assembly: AssemblyFileVersion("5.5.22.1")]
[assembly: AssemblyVersion("5.5.24.1")]
[assembly: AssemblyFileVersion("5.5.24.1")]
[assembly: NeutralResourcesLanguageAttribute("en-US")]
[assembly: System.Windows.Media.DisableDpiAwareness]