update warp3d and xmlrpc

This commit is contained in:
UbitUmarov
2024-04-21 03:01:47 +01:00
parent d08459e971
commit f8d6fe296b
48 changed files with 3775 additions and 4398 deletions
@@ -35,5 +35,5 @@ using System.Security.Permissions;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.1")]
[assembly: AssemblyFileVersion("1.0.0.1")]
Binary file not shown.
File diff suppressed because it is too large Load Diff
+15 -152
View File
@@ -1,186 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{6E48530B-16AB-4861-9CED-97334739D675}</ProjectGuid>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Warp3D</RootNamespace>
<AssemblyName>Warp3D</AssemblyName>
<SignAssembly>true</SignAssembly>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>2.0</OldToolsVersion>
<TargetFrameworkProfile />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<ProduceReferenceAssembly>False</ProduceReferenceAssembly>
<RunAnalyzersDuringBuild>True</RunAnalyzersDuringBuild>
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RegisterForComInterop>false</RegisterForComInterop>
<Prefer32Bit>false</Prefer32Bit>
<IsPublishable>False</IsPublishable>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Original|AnyCPU' ">
<OutputPath>bin\Original\</OutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<RegisterForComInterop>true</RegisterForComInterop>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == '64Bit CPU%27s|AnyCPU' ">
<OutputPath>bin\64Bit CPU%27s\</OutputPath>
<Prefer32Bit>false</Prefer32Bit>
<IsPublishable>False</IsPublishable>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RegisterForComInterop>true</RegisterForComInterop>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Original|x64' ">
<OutputPath>bin\x64\Original\</OutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<RegisterForComInterop>true</RegisterForComInterop>
<PlatformTarget>x64</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == '64Bit CPU%27s|x64' ">
<OutputPath>bin\x64\64Bit CPU%27s\</OutputPath>
<PlatformTarget>x64</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Slixel Tester|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Slixel Tester\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RegisterForComInterop>true</RegisterForComInterop>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisRuleAssemblies>\rules</CodeAnalysisRuleAssemblies>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Slixel Tester|x64' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Slixel Tester\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RegisterForComInterop>true</RegisterForComInterop>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleAssemblies>\rules</CodeAnalysisRuleAssemblies>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<None Remove="System.Drawing.Common.dll" />
<None Remove="license.txt" />
</ItemGroup>
<ItemGroup>
<Compile Include="warp_3ds_Importer.cs" />
<Compile Include="warp_Camera.cs" />
<Compile Include="warp_Color.cs" />
<Compile Include="warp_CoreObject.cs" />
<Compile Include="warp_Edge.cs" />
<Compile Include="warp_Environment.cs" />
<Compile Include="warp_FXLensFlare .cs" />
<Compile Include="warp_FXPlugin.cs" />
<Compile Include="warp_Light.cs" />
<Compile Include="warp_Lightmap.cs" />
<Compile Include="warp_Material.cs" />
<Compile Include="warp_Math.cs" />
<Compile Include="warp_Matrix.cs" />
<Compile Include="warp_Object.cs" />
<Compile Include="warp_ObjectFactory.cs" />
<Compile Include="warp_Quaternion.cs" />
<Compile Include="warp_Rasterizer.cs" />
<Compile Include="warp_RenderPipeline.cs" />
<Compile Include="warp_Scene.cs" />
<Compile Include="warp_Screen.cs" />
<Compile Include="warp_Texture.cs" />
<Compile Include="warp_TextureFactory.cs" />
<Compile Include="warp_TextureProjector.cs" />
<Compile Include="warp_TextureSettings.cs" />
<Compile Include="warp_Triangle.cs" />
<Compile Include="warp_Vector.cs" />
<Compile Include="warp_Vertex.cs" />
<Compile Include="Warp3D.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Service Include="{94E38DFF-614B-4cbd-B67C-F211BB35CE8B}" />
<Reference Include="System.Drawing.Common">
<SpecificVersion>False</SpecificVersion>
<HintPath>System.Drawing.Common.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
+164 -163
View File
@@ -5,208 +5,209 @@ using System.Net;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_3ds_Importer.
/// </summary>
public class warp_3ds_Importer
{
private int currentJunkId;
private int nextJunkOffset;
/// <summary>
/// Summary description for warp_3ds_Importer.
/// </summary>
public class warp_3ds_Importer
{
private int currentJunkId;
private int nextJunkOffset;
private String currentObjectName = null;
private warp_Object currentObject = null;
private bool endOfStream = false;
private string currentObjectName = null;
private warp_Object currentObject = null;
private bool endOfStream = false;
private Hashtable _objects = new Hashtable();
private readonly Hashtable _objects = new Hashtable();
public warp_3ds_Importer()
{
}
public warp_3ds_Importer()
{
}
public Hashtable importFromFile( string name, String path )
{
Stream fs = null;
public Hashtable importFromFile(string name, String path)
{
Stream fs;
_objects.Clear();
if ( path.StartsWith( "http" ) )
if (path.StartsWith("http"))
{
WebRequest webrq = WebRequest.Create( path );
fs = webrq.GetResponse().GetResponseStream() ;
WebRequest webrq = WebRequest.Create(path);
fs = webrq.GetResponse().GetResponseStream();
}
else
{
fs = new FileStream( path, FileMode.Open );
fs = new FileStream(path, FileMode.Open);
}
BinaryReader br = new BinaryReader( fs );
return importFromStream( name, br );
}
BinaryReader br = new BinaryReader(fs);
return importFromStream(name, br);
}
public Hashtable importFromStream( string name, BinaryReader inStream )
{
public Hashtable importFromStream(string name, BinaryReader inStream)
{
_objects.Clear();
readJunkHeader(inStream);
if (currentJunkId != 0x4D4D)
{
return null;
}
try
{
for (;;)
{
readNextJunk( name, inStream);
}
}
catch(Exception)
{
readJunkHeader(inStream);
if (currentJunkId != 0x4D4D)
{
return null;
}
try
{
for (; ; )
{
readNextJunk(name, inStream);
}
}
catch (Exception)
{
// ignored
}
}
inStream.Close();
return _objects;
}
private void readJunkHeader(BinaryReader inStream)
{
currentJunkId = readShort(inStream);
nextJunkOffset = readInt(inStream);
endOfStream = currentJunkId < 0;
}
}
private int readInt(BinaryReader inStream)
{
return inStream.ReadByte() | (inStream.ReadByte() << 8) | (inStream.ReadByte() << 16) | (inStream.ReadByte() << 24);
}
private void readJunkHeader(BinaryReader inStream)
{
currentJunkId = readShort(inStream);
nextJunkOffset = readInt(inStream);
endOfStream = currentJunkId < 0;
}
private int readShort(BinaryReader inStream)
{
return (inStream.ReadByte() | (inStream.ReadByte() << 8));
}
private int readInt(BinaryReader inStream)
{
return inStream.ReadByte() | (inStream.ReadByte() << 8) | (inStream.ReadByte() << 16) | (inStream.ReadByte() << 24);
}
private void readNextJunk(string name, BinaryReader inStream)
{
readJunkHeader(inStream);
private int readShort(BinaryReader inStream)
{
return (inStream.ReadByte() | (inStream.ReadByte() << 8));
}
if (currentJunkId == 0x3D3D /* mesh block */)
{
return;
}
if (currentJunkId == 0x4000 /* object block */)
{
currentObjectName = readString(inStream);
return;
}
private void readNextJunk(string name, BinaryReader inStream)
{
readJunkHeader(inStream);
if (currentJunkId == 0x4100 /* triangular polygon object */)
{
currentObject = new warp_Object();
_objects.Add( name+"_"+currentObjectName, currentObject );
if (currentJunkId == 0x3D3D /* mesh block */)
{
return;
}
return;
}
if (currentJunkId == 0x4000 /* object block */)
{
currentObjectName = readString(inStream);
return;
}
if (currentJunkId == 0x4110 /* vertex list */)
{
readVertexList(inStream);
return;
}
if (currentJunkId == 0x4100 /* triangular polygon object */)
{
currentObject = new warp_Object();
_objects.Add(name + "_" + currentObjectName, currentObject);
if (currentJunkId == 0x4120 /* point list */)
{
readPointList(inStream);
return;
}
return;
}
if (currentJunkId == 0x4140 /* mapping coordinates */)
{
readMappingCoordinates(inStream);
return;
}
if (currentJunkId == 0x4110 /* vertex list */)
{
readVertexList(inStream);
return;
}
skipJunk(inStream);
}
if (currentJunkId == 0x4120 /* point list */)
{
readPointList(inStream);
return;
}
private string readString(BinaryReader inStream)
{
string result = "";
byte inByte;
while ( (inByte = (byte) inStream.ReadByte()) != 0)
{
result += (char) inByte;
}
if (currentJunkId == 0x4140 /* mapping coordinates */)
{
readMappingCoordinates(inStream);
return;
}
return result;
}
skipJunk(inStream);
}
private float readFloat(BinaryReader inStream)
{
int bits = readInt(inStream);
private string readString(BinaryReader inStream)
{
string result = "";
byte inByte;
while ((inByte = (byte)inStream.ReadByte()) != 0)
{
result += (char)inByte;
}
int s = ((bits >> 31) == 0) ? 1 : -1;
int e = ((bits >> 23) & 0xff);
int m = (e == 0) ? (bits & 0x7fffff) << 1 : (bits & 0x7fffff) | 0x800000;
return result;
}
double v = (double)s*(double)m*(Math.Pow(2, e-150));
return (float)v;
}
private float readFloat(BinaryReader inStream)
{
int bits = readInt(inStream);
private void skipJunk(BinaryReader inStream)
{
try
{
for (int i = 0; (i < nextJunkOffset - 6) && (!endOfStream); i++)
{
endOfStream = inStream.ReadByte() < 0;
}
}
catch(Exception){endOfStream=true;};
}
int s = ((bits >> 31) == 0) ? 1 : -1;
int e = ((bits >> 23) & 0xff);
int m = (e == 0) ? (bits & 0x7fffff) << 1 : (bits & 0x7fffff) | 0x800000;
private void readVertexList(BinaryReader inStream)
{
float x, y, z;
int vertices = readShort(inStream);
for (int i = 0; i < vertices; i++)
{
x = readFloat(inStream);
y = readFloat(inStream);
z = readFloat(inStream);
double v = (double)s * (double)m * (Math.Pow(2, e - 150));
currentObject.addVertex(x, -y, z);
}
}
return (float)v;
}
private void readPointList(BinaryReader inStream)
{
int v1, v2, v3;
int triangles = readShort(inStream);
for (int i = 0; i < triangles; i++)
{
v1 = readShort(inStream);
v2 = readShort(inStream);
v3 = readShort(inStream);
private void skipJunk(BinaryReader inStream)
{
try
{
for (int i = 0; (i < nextJunkOffset - 6) && (!endOfStream); i++)
{
endOfStream = inStream.ReadByte() < 0;
}
}
catch (Exception) { endOfStream = true; };
}
readShort(inStream);
private void readVertexList(BinaryReader inStream)
{
float x, y, z;
int vertices = readShort(inStream);
for (int i = 0; i < vertices; i++)
{
x = readFloat(inStream);
y = readFloat(inStream);
z = readFloat(inStream);
currentObject.addTriangle(currentObject.vertex(v1),
currentObject.vertex(v2),
currentObject.vertex(v3));
}
}
currentObject.addVertex(x, -y, z);
}
}
private void readMappingCoordinates(BinaryReader inStream)
{
int vertices = readShort(inStream);
for (int i = 0; i < vertices; i++)
{
currentObject.vertex(i).u = readFloat(inStream);
currentObject.vertex(i).v = readFloat(inStream);
}
}
}
private void readPointList(BinaryReader inStream)
{
int v1, v2, v3;
int triangles = readShort(inStream);
for (int i = 0; i < triangles; i++)
{
v1 = readShort(inStream);
v2 = readShort(inStream);
v3 = readShort(inStream);
readShort(inStream);
currentObject.addTriangle(currentObject.vertex(v1),
currentObject.vertex(v2),
currentObject.vertex(v3));
}
}
private void readMappingCoordinates(BinaryReader inStream)
{
int vertices = readShort(inStream);
for (int i = 0; i < vertices; i++)
{
float u = readFloat(inStream);
float v = readFloat(inStream);
currentObject.vertex(i).setUV(u, v);
}
}
}
}
+35 -18
View File
@@ -1,4 +1,5 @@
using System;
using System.Runtime.CompilerServices;
namespace Warp3D
{
@@ -8,15 +9,15 @@ namespace Warp3D
///
public class warp_Camera
{
public warp_Matrix matrix = new warp_Matrix();
public warp_Matrix projmatrix = new warp_Matrix();
public warp_Matrix normalmatrix = new warp_Matrix();
public warp_Matrix matrix = new();
public warp_Matrix projmatrix = new();
public warp_Matrix normalmatrix = new();
bool needsRebuild = true; // Flag indicating changes on matrix
// Camera settings
public warp_Vector pos = new warp_Vector(0f, 0f, 0f);
public warp_Vector lookat = new warp_Vector(0f, 0f, 0f);
public warp_Vector pos = warp_Vector.Zero;
public warp_Vector lookat = warp_Vector.Zero;
public float rollfactor = 0f;
public float fovfact; // Field of View factor
@@ -39,12 +40,14 @@ namespace Warp3D
setFov(fov);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Matrix getMatrix()
{
rebuildMatrices();
return matrix;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Matrix getNormalMatrix()
{
rebuildMatrices();
@@ -59,20 +62,19 @@ namespace Warp3D
warp_Vector forward, up, right;
forward = warp_Vector.sub(lookat, pos);
if(Math.Abs(forward.x) < 0.001f && Math.Abs(forward.z) < 0.001f)
forward = warp_Vector.sub(ref lookat, ref pos);
if(MathF.Abs(forward.x) < 0.001f && MathF.Abs(forward.z) < 0.001f)
{
right = new warp_Vector(1f, 0f, 0f);
if(forward.y < 0)
up = new warp_Vector(0f, 0f, 1f);
else
up = new warp_Vector(0f, 0f, -1f);
up = new warp_Vector(0f, 0f, forward.y < 0 ? 1f : -1f);
}
else
{
up = new warp_Vector(0f, 1f, 0f);
right = warp_Vector.getNormal(up, forward);
up = warp_Vector.getNormal(forward, right);
right = warp_Vector.vectorProduct(ref up, ref forward);
right.normalize();
up = warp_Vector.vectorProduct(ref forward, ref right);
up.normalize();
}
forward.normalize();
@@ -104,9 +106,10 @@ namespace Warp3D
matrix = warp_Matrix.multiply(projmatrix, matrix);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setFov(float fov)
{
fovfact = (float)Math.Tan(warp_Math.deg2rad(fov) / 2);
fovfact = MathF.Tan(warp_Math.deg2rad(fov) / 2);
isOrthographic = false;
needsRebuild = true;
}
@@ -126,36 +129,42 @@ namespace Warp3D
needsRebuild = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void roll(float angle)
{
rollfactor += angle;
needsRebuild = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setPos(float px, float py, float pz)
{
pos = new warp_Vector(px, py, pz);
needsRebuild = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setPos(warp_Vector p)
{
pos = p;
needsRebuild = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void lookAt(float px, float py, float pz)
{
lookat = new warp_Vector(px, py, pz);
needsRebuild = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void lookAt(warp_Vector p)
{
lookat = p;
needsRebuild = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setScreensize(int w, int h)
{
screenwidth = w;
@@ -166,6 +175,7 @@ namespace Warp3D
needsRebuild = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void shift(float dx, float dy, float dz)
{
pos.x += dx;
@@ -177,46 +187,53 @@ namespace Warp3D
needsRebuild = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void shift(warp_Vector v)
{
shift(v.x, v.y, v.z);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void rotate(float dx, float dy, float dz)
{
pos = pos.transform(warp_Matrix.rotateMatrix(dx, dy, dz));
needsRebuild = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void rotate(warp_Vector v)
{
rotate(v.x, v.y, v.z);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static warp_Camera FRONT()
{
warp_Camera cam = new warp_Camera();
warp_Camera cam = new();
cam.setPos(0, 0, -2f);
return cam;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static warp_Camera LEFT()
{
warp_Camera cam = new warp_Camera();
warp_Camera cam = new();
cam.setPos(2f, 0, 0);
return cam;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static warp_Camera RIGHT()
{
warp_Camera cam = new warp_Camera();
warp_Camera cam = new();
cam.setPos(-2f, 0, 0);
return cam;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static warp_Camera TOP()
{
warp_Camera cam = new warp_Camera();
warp_Camera cam = new();
cam.setPos(0, -2f, 0);
return cam;
}
+92 -156
View File
@@ -1,4 +1,5 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Warp3D
@@ -8,66 +9,65 @@ namespace Warp3D
/// </summary>
public class warp_Color
{
public static int MASKALPHA = unchecked((int)0xFF000000); // alpha mask
public static int MASKHALFALPHA = unchecked((int)0x7F000000); // alpha mask
public static int MASKRED = unchecked((int)0xFF0000); // red mask
public static int MASKGREEN = unchecked((int)0xFF00); // green mask
public static int MASKBLUE = unchecked((int)0xFF); // blue mask
public static int MASKRB = unchecked((int)0x00FF00FF); // mask for additive/subtractive shading
public static int MASKAG = unchecked((int)0xFF00FF00); // mask for additive/subtractive shading
public static int RBHALF = unchecked((int)0x00800080);
public static int MASKRBHALF = unchecked((int)0xFF80FF80);
public static int MASKRBOVER = unchecked((int)0x01000100);
public static int MASK7Bit = unchecked((int)0x00FEFEFF); // mask for additive/subtractive shading
public static int MASK6Bit = unchecked((int)0x00FCFCFC); // mask for additive/subtractive shading
public static int MASK7BitA = unchecked((int)0x00FEFEFF); // mask for additive/subtractive shading
public static int MASK6BitA = unchecked((int)0x00FCFCFC); // mask for additive/subtractive shading
public static int MASKRGB = unchecked((int)0x00FFFFFF); // rgb mask
public const int MASKALPHA = unchecked((int)0xFF000000); // alpha mask
public const int MASKHALFALPHA = unchecked((int)0x7F000000); // alpha mask
public const int MASKRED = unchecked((int)0xFF0000); // red mask
public const int MASKGREEN = unchecked((int)0xFF00); // green mask
public const int MASKBLUE = unchecked((int)0xFF); // blue mask
public const int MASKRB = unchecked((int)0x00FF00FF); // mask for additive/subtractive shading
public const int MASKAG = unchecked((int)0xFF00FF00); // mask for additive/subtractive shading
public const int RBHALF = unchecked((int)0x00800080);
public const int MASKRBHALF = unchecked((int)0xFF80FF80);
public const int MASKRBOVER = unchecked((int)0x01000100);
public const int MASK7Bit = unchecked((int)0x00FEFEFF); // mask for additive/subtractive shading
public const int MASK6Bit = unchecked((int)0x00FCFCFC); // mask for additive/subtractive shading
public const int MASK7BitA = unchecked((int)0x00FEFEFF); // mask for additive/subtractive shading
public const int MASK6BitA = unchecked((int)0x00FCFCFC); // mask for additive/subtractive shading
public const int MASKRGB = unchecked((int)0x00FFFFFF); // rgb mask
public static int White = unchecked((int)0xFFFFFFFF);
public static int Grey = unchecked((int)0xFF7F7F7F);
public static int Black = unchecked((int)0xFF000000);
public const int White = unchecked((int)0xFFFFFFFF);
public const int Grey = unchecked((int)0xFF7F7F7F);
public const int Black = unchecked((int)0xFF000000);
public static int random(int color, int delta)
{
Random rnd = new Random();
int r = (color >> 16) & 0xff;
int g = (color >> 8) & 0xff;
int b = color & 0xff;
r += (int)(rnd.NextDouble() * (float)delta);
g += (int)(rnd.NextDouble() * (float)delta);
b += (int)(rnd.NextDouble() * (float)delta);
float df = delta;
r += (int)(Random.Shared.NextSingle() * df);
g += (int)(Random.Shared.NextSingle() * df);
b += (int)(Random.Shared.NextSingle() * df);
return getCropColor(r, g, b);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int random()
{
Random rnd = new Random();
return (int)(rnd.NextDouble() * 16777216);
return (int)(Random.Shared.NextSingle() * 16777216f);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int getAlpha(int c)
{
return (c >> 24) & 0xff;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int getRed(int c)
{
return (c >> 16) & 0xff;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int getGreen(int c)
{
return (c >> 8) & 0xff;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int getBlue(int c)
{
return c & 0xff;
@@ -77,49 +77,50 @@ namespace Warp3D
{
int[] pal = new int[size];
int c1, c2, pos1, pos2, range;
int r, g, b, r1, g1, b1, r2, g2, b2, dr, dg, db;
if(colors.GetLength(0) == 1)
int r1, g1, b1, r2, g2, b2, dr, dg, db;
int clen = colors.GetLength(0) - 1;
if (clen == 0)
{
c1 = colors[0];
for(int i = 0; i < size; i++)
for(int i = 0; i < pal.Length; i++)
{
pal[i] = c1;
}
return pal;
}
for(int c = 0; c < colors.GetLength(0) - 1; c++)
ref int cref = ref MemoryMarshal.GetArrayDataReference(colors);
ref int palref = ref MemoryMarshal.GetArrayDataReference(pal);
int invclenm1 = 1 / clen;
for (int c = 0; c < clen; c++)
{
c1 = colors[c];
c2 = colors[c + 1];
pos1 = size * c / (colors.GetLength(0) - 1);
pos2 = size * (c + 1) / (colors.GetLength(0) - 1);
c1 = Unsafe.As<int, int>(ref Unsafe.Add(ref cref, c));
c2 = Unsafe.As<int, int>(ref Unsafe.Add(ref cref, c + 1));
pos1 = size * c * invclenm1;
pos2 = size * (c + 1) * invclenm1;
range = pos2 - pos1;
range = 1 / range;
r1 = warp_Color.getRed(c1) << 16;
g1 = warp_Color.getGreen(c1) << 16;
b1 = warp_Color.getBlue(c1) << 16;
r2 = warp_Color.getRed(c2) << 16;
g2 = warp_Color.getGreen(c2) << 16;
b2 = warp_Color.getBlue(c2) << 16;
dr = (r2 - r1) / range;
dg = (g2 - g1) / range;
db = (b2 - b1) / range;
r = r1;
g = g1;
b = b1;
dr = (r2 - r1) * range;
dg = (g2 - g1) * range;
db = (b2 - b1) * range;
for(int i = pos1; i < pos2; i++)
{
pal[i] = getColor(r >> 16, g >> 16, b >> 16);
r += dr;
g += dg;
b += db;
Unsafe.As<int, int>(ref Unsafe.Add(ref palref, i)) = getColor(r1 >> 16, g1 >> 16, b1 >> 16);
r1 += dr;
g1 += dg;
b1 += db;
}
}
return pal;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int add(int color1, int color2)
{
int t1,t2,t3,t4;
@@ -139,57 +140,24 @@ namespace Warp3D
return (t4 << 8) | t3;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int avg2c(int color1, int color2)
{
int t1,t2,t3,t4;
int t1 = (color1 & MASKRB) + (color2 & MASKRB);
t1 >>= 1;
t1 &= MASKRB;
t1 = color1 & MASKRB;
t2 = color2 & MASKRB;
t3 = t1 + t2 + 0x00010001;
t3 >>= 1;
t3 &= MASKRB;
long t2 = (color1 & MASKAG) + (color2 & MASKAG);
t2 >>= 1;
t2 &= MASKAG;
t1 = (color1 >> 8) & MASKRB;
t2 = (color2 >> 8) & MASKRB;
t4 = t1 + t2 + 0x00010001;
t4 >>= 1;
t4 &= MASKRB;
return (t4 << 8) | t3;
return (int)t2 | t1;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static int avg4c(int color1, int color2, int color3, int color4)
{
int t1,t2,t3,t4;
t1 = color1 & MASKRB;
t2 = color2 & MASKRB;
t3 = t1 + t2;
t1 = color3 & MASKRB;
t2 = color4 & MASKRB;
t3 += t1 + t2 + 0x00020002;
t3 >>= 2;
t3 &= MASKRB;
t1 = (color1 >> 8) & MASKRB;
t2 = (color2 >> 8) & MASKRB;
t4 = t1 + t2 + 0x00020002;;
t1 = (color3 >> 8) & MASKRB;
t2 = (color4 >> 8) & MASKRB;
t4 += t1 + t2;
t4 >>= 2;
t4 &= MASKRB;
return (t4 << 8) | t3;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int sub(int color1, int color2)
// Substracts color2 from color1
{
int t1,t2,t3,t4;
t1 = color1 & MASKRB;
@@ -205,15 +173,8 @@ namespace Warp3D
t4 &= MASKRB;
return (t4 << 8) | t3;
/*
int pixel = (color1 & MASK7Bit) + (~color2 & MASK7Bit);
int overflow = ~pixel & 0x1010100;
overflow = overflow - (overflow >> 8);
return ALPHA | (~overflow & pixel);
*/
}
/*
/*
public static int subneg(int color1, int color2)
// Substracts the negative of color2 from color1
{
@@ -229,15 +190,15 @@ namespace Warp3D
color = (~color) & RGB;
return ALPHA | color;
}
*/
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
*/
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int mix(int color1, int color2)
// Returns the averidge color from 2 colors
{
return MASKALPHA | (((color1 & MASK7Bit) >> 1) + ((color2 & MASK7Bit) >> 1));
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int scale(int color, int factor)
{
if(factor == 255)
@@ -256,7 +217,7 @@ namespace Warp3D
return a | RB | b;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int multiply(int color1, int color2)
{
int t1, t2, t3, t4;
@@ -276,46 +237,25 @@ namespace Warp3D
t4 = (t1 & 0xff) * (t2 & 0xff); // g on g
t4 |= (t1 & MASKRED) * ((t2 >> 16) & 0xff); // a on a
t4 += RBHALF; // add halfbit
t4 = (t4 + ((t4 >> 8) & MASKRB));
t4 += (t4 >> 8) & MASKRB;
t4 &= MASKAG;
return t3 | t4;
/*
int a;
int r = (color1 >> 24 ) & 0xff;
int g = (color2 >> 24 ) & 0xff;
if( r == 0xff && g == 0xff)
a = ALPHA;
else
{
a = ((r * g)) & 0xff00;
a <<= 16;
}
if((color1 & RGB) == 0 && (color2 & RGB) == 0)
return a;
r = unchecked((((color1 >> 16) & 0xff) * ((color2 >> 16) & 0xff)) & 0xff00);
g = (((color1 >> 8) & 0xff) * ((color2 >> 8) & 0xff)) & 0xff00;
int b = ((color1 & 0xff) * (color2 & 0xff)) >> 8;
return a | r << 8 | g | b;
*/
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int transparency(int bkgrd, int color, int alpha)
{
if(alpha == 0)
switch(alpha)
{
return bkgrd;
}
if(alpha == 255)
{
return color;
}
if(alpha == 127)
{
return mix(bkgrd, color);
case 0:
return bkgrd;
case 255:
return color;
case 127:
return mix(bkgrd, color);
default:
break;
}
int colorRB = bkgrd & 0xff00ff;
@@ -329,22 +269,21 @@ namespace Warp3D
return MASKALPHA | colorRB | colorg;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
// blends color alpha, but result image is solid
public static int overSolid(int bkgrd, int color)
{
int alpha = color & MASKALPHA;
if(alpha == 0)
switch(alpha)
{
return bkgrd;
}
if(alpha == Black)
{
return color;
}
if(alpha == MASKHALFALPHA)
{
return mix(bkgrd, color);
case 0:
return bkgrd;
case Black:
return color;
case MASKHALFALPHA:
return mix(bkgrd, color);
default:
break;
}
alpha = (alpha >> 24) & 0xff;
int colorRB = bkgrd & MASKRB;
@@ -358,34 +297,31 @@ namespace Warp3D
return MASKALPHA | colorRB | colorg;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int getCropColor(int r, int g, int b)
{
return MASKALPHA | (warp_Math.crop(r, 0, 255) << 16) | (warp_Math.crop(g, 0, 255) << 8) | warp_Math.crop(b, 0, 255);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int getCropColor(int r, int g, int b, int a)
{
return (warp_Math.crop(a , 0, 255) << 24) |
(warp_Math.crop(r, 0, 255) << 16) |
(warp_Math.crop(g, 0, 255) << 8) |
warp_Math.crop(b, 0, 255);
return (warp_Math.crop(a, 0, 255) << 24) | (warp_Math.crop(r, 0, 255) << 16) | (warp_Math.crop(g, 0, 255) << 8) | warp_Math.crop(b, 0, 255);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int getColor(int r, int g, int b)
{
return MASKALPHA | (r << 16) | (g << 8) | b;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int getColor(int r, int g, int b, int a)
{
return (a << 24) | (r << 16) | (g << 8) | b;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int getGray(int color)
{
int r = ((color & MASKRED) >> 16);
@@ -395,7 +331,7 @@ namespace Warp3D
return (color & MASKALPHA) | (Y << 16) | (Y << 8) | Y;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int getAverage(int color)
{
return (((color & MASKRED) >> 16) + ((color & MASKGREEN) >> 8) + (color & MASKBLUE)) / 3;
+113 -94
View File
@@ -1,115 +1,134 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_CoreObject.
/// </summary>
///
/// <summary>
/// Summary description for warp_CoreObject.
/// </summary>
///
public class warp_CoreObject
{
public warp_Matrix matrix=new warp_Matrix();
public warp_Matrix normalmatrix=new warp_Matrix();
public class warp_CoreObject
{
public warp_Matrix matrix = new();
public warp_Matrix normalmatrix = new();
public void transform(warp_Matrix m)
{
matrix.transform(m);
normalmatrix.transform(m);
}
public void shift(float dx, float dy, float dz)
{
matrix.shift(dx,dy,dz);
}
public void shift( warp_Vector v )
{
matrix.shift(v.x,v.y,v.z);
}
public void scale(float d)
{
matrix.scale(d);
}
public void scale(float dx, float dy, float dz)
{
matrix.scale(dx,dy,dz);
}
public void scaleSelf(float d)
{
matrix.scaleSelf(d);
}
public void scaleSelf(float dx, float dy, float dz)
{
matrix.scaleSelf(dx,dy,dz);
}
public void rotate(warp_Vector d)
{
rotateSelf(d.x,d.y,d.z);
}
public void rotateSelf(warp_Vector d)
{
rotateSelf(d.x,d.y,d.z);
}
public void rotate(float dx, float dy, float dz)
{
matrix.rotate(dx,dy,dz);
normalmatrix.rotate(dx,dy,dz);
}
public void rotate( warp_Quaternion quat, float x, float y, float z )
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void transform(warp_Matrix m)
{
matrix.rotate( quat , x, y, z);
normalmatrix.rotate( quat , x, y, z);
matrix.transform(m);
normalmatrix.transform(m);
}
public void rotate( warp_Matrix m )
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void shift(float dx, float dy, float dz)
{
matrix.rotate( m );
normalmatrix.rotate( m );
matrix.shift(dx, dy, dz);
}
public void rotateSelf(float dx, float dy, float dz)
{
matrix.rotateSelf(dx,dy,dz);
normalmatrix.rotateSelf(dx,dy,dz);
}
public void rotateSelf( warp_Quaternion quat )
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void shift(warp_Vector v)
{
matrix.rotateSelf( quat );
normalmatrix.rotateSelf( quat );
matrix.shift(v.x, v.y, v.z);
}
public void rotateSelf( warp_Matrix m )
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void scale(float d)
{
matrix.rotateSelf( m );
normalmatrix.rotateSelf( m );
matrix.scale(d);
}
public void setPos( float x, float y, float z )
{
matrix.m03=x;
matrix.m13=y;
matrix.m23=z;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void scale(float dx, float dy, float dz)
{
matrix.scale(dx, dy, dz);
}
public void setPos(warp_Vector v)
{
setPos(v.x,v.y,v.z);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void scaleSelf(float d)
{
matrix.scaleSelf(d);
}
public warp_Vector getPos()
{
return new warp_Vector(matrix.m03,matrix.m13,matrix.m23);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void scaleSelf(float dx, float dy, float dz)
{
matrix.scaleSelf(dx, dy, dz);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void rotate(warp_Vector d)
{
rotateSelf(d.x, d.y, d.z);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void rotateSelf(warp_Vector d)
{
rotateSelf(d.x, d.y, d.z);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void rotate(float dx, float dy, float dz)
{
matrix.rotate(dx, dy, dz);
normalmatrix.rotate(dx, dy, dz);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void rotate(warp_Quaternion quat, float x, float y, float z)
{
matrix.rotate(quat, x, y, z);
normalmatrix.rotate(quat, x, y, z);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void rotate(warp_Matrix m)
{
matrix.rotate(m);
normalmatrix.rotate(m);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void rotateSelf(float dx, float dy, float dz)
{
matrix.rotateSelf(dx, dy, dz);
normalmatrix.rotateSelf(dx, dy, dz);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void rotateSelf(warp_Quaternion quat)
{
matrix.rotateSelf(quat);
normalmatrix.rotateSelf(quat);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void rotateSelf(warp_Matrix m)
{
matrix.rotateSelf(m);
normalmatrix.rotateSelf(m);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setPos(float x, float y, float z)
{
matrix.m03 = x;
matrix.m13 = y;
matrix.m23 = z;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setPos(warp_Vector v)
{
setPos(v.x, v.y, v.z);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Vector getPos()
{
return new warp_Vector(matrix.m03, matrix.m13, matrix.m23);
}
}
}
+25 -25
View File
@@ -2,32 +2,32 @@ using System;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_Edge.
/// </summary>
///
public class warp_Edge
{
warp_Vertex a,b;
/// <summary>
/// Summary description for warp_Edge.
/// </summary>
///
public class warp_Edge
{
warp_Vertex a, b;
public warp_Edge()
{
}
public warp_Edge()
{
}
public warp_Edge(warp_Vertex v1, warp_Vertex v2)
{
a=v1;
b=v2;
}
public warp_Edge(warp_Vertex v1, warp_Vertex v2)
{
a = v1;
b = v2;
}
public warp_Vertex start()
{
return a;
}
public warp_Vertex end()
{
return b;
}
}
public warp_Vertex start()
{
return a;
}
public warp_Vertex end()
{
return b;
}
}
}
+15 -15
View File
@@ -2,21 +2,21 @@ using System;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_Environment.
/// </summary>
public class warp_Environment
{
public int ambient=0;
public int fogcolor=0;
public int fogfact=0;
public int bgcolor= warp_Color.White;
/// <summary>
/// Summary description for warp_Environment.
/// </summary>
public class warp_Environment
{
public int ambient = 0;
public int fogcolor = 0;
public int fogfact = 0;
public int bgcolor = warp_Color.White;
public warp_Texture background=null;
public warp_Texture background = null;
public void setBackground(warp_Texture t)
{
background=t;
}
}
public void setBackground(warp_Texture t)
{
background = t;
}
}
}
+310 -311
View File
@@ -6,347 +6,346 @@ namespace Warp3D
{
public class warp_FXLensFlare : warp_FXPlugin
{
public warp_Object flareObject;
private int flares=0;
private bool zBufferSensitive=true;
private warp_Texture[] flare;
private float[] flareDist;
private warp_FXLensFlare(warp_Scene scene) : base( scene )
{
}
public warp_Object flareObject;
public warp_FXLensFlare( String name, warp_Scene scene, bool zBufferSensitive ) : base( scene )
{
private int flares = 0;
private bool zBufferSensitive = true;
private warp_Texture[] flare;
private float[] flareDist;
private warp_FXLensFlare(warp_Scene scene) : base(scene)
{
}
public warp_FXLensFlare(string name, warp_Scene scene, bool zBufferSensitive) : base(scene)
{
this.zBufferSensitive = zBufferSensitive;
flareObject=new warp_Object();
flareObject.addVertex(new warp_Vertex(1f,1f,1f));
flareObject.rebuild();
flareObject = new();
flareObject.addVertex(new warp_Vertex(1f, 1f, 1f));
flareObject.rebuild();
scene.addObject(name, flareObject);
}
public void preset1()
{
clear();
scene.addObject(name, flareObject);
}
addGlow(144,0x330099);
addStrike(320,48,0x003366);
addStrike(48,240,0x660033);
addRing(120,0x660000);
addRays(320, 32, 20, 0x111111);
addSecs(12,100,64,0x6633cc,64);
}
public void preset2()
{
clear();
addGlow(144,0x995500);
addStrike(640,64,0xCC0000);
addStrike(32,480,0x0000FF);
addStrike(64,329,0x330099);
addRing(160,0x990000);
addRays(320, 24, 32, 0x332211);
addSecs(12,100,64,0x333333,100);
addSecs(12,60,40,0x336699,80);
}
public void preset3()
{
clear();
addGlow(144,0x993322);
addStrike(400,200,0xCC00FF);
addStrike(480,32,0x0000FF);
addRing(180,0x990000);
addRays(240, 32, 48, 0x332200);
addSecs(12,80,64,0x555555,50);
addSecs(12,60,40,0x336699,80);
}
public void setPos(warp_Vector pos)
{
flareObject.fastvertex[0].pos=pos;
}
public void clear()
{
flares=0;
flare=null;
flareDist=null;
}
public void addGlow(int size, int color)
{
addFlare(createGlow(size,size,color,256),0f);
}
public void addStrike(int width, int height, int color)
{
addFlare(createGlow(width,height,color,48),0f);
}
public void addRing(int size, int color)
{
addFlare(createRing(size,color),0f);
}
public void addRays(int size, int num, int rad, int color)
{
addFlare(createRays(size, num, rad, color),0f);
}
public void addSecs( int count, int averidgeSize, int sizeDelta, int averidgeColor, int colorDelta )
public void preset1()
{
for ( int i = 0; i < count; i++ )
clear();
addGlow(144, 0x330099);
addStrike(320, 48, 0x003366);
addStrike(48, 240, 0x660033);
addRing(120, 0x660000);
addRays(320, 32, 20, 0x111111);
addSecs(12, 100, 64, 0x6633cc, 64);
}
public void preset2()
{
clear();
addGlow(144, 0x995500);
addStrike(640, 64, 0xCC0000);
addStrike(32, 480, 0x0000FF);
addStrike(64, 329, 0x330099);
addRing(160, 0x990000);
addRays(320, 24, 32, 0x332211);
addSecs(12, 100, 64, 0x333333, 100);
addSecs(12, 60, 40, 0x336699, 80);
}
public void preset3()
{
clear();
addGlow(144, 0x993322);
addStrike(400, 200, 0xCC00FF);
addStrike(480, 32, 0x0000FF);
addRing(180, 0x990000);
addRays(240, 32, 48, 0x332200);
addSecs(12, 80, 64, 0x555555, 50);
addSecs(12, 60, 40, 0x336699, 80);
}
public void setPos(warp_Vector pos)
{
flareObject.vertexData[0].pos = pos;
}
public void clear()
{
flares = 0;
flare = null;
flareDist = null;
}
public void addGlow(int size, int color)
{
addFlare(createGlow(size, size, color, 256), 0f);
}
public void addStrike(int width, int height, int color)
{
addFlare(createGlow(width, height, color, 48), 0f);
}
public void addRing(int size, int color)
{
addFlare(createRing(size, color), 0f);
}
public void addRays(int size, int num, int rad, int color)
{
addFlare(createRays(size, num, rad, color), 0f);
}
public void addSecs(int count, int averidgeSize, int sizeDelta, int averidgeColor, int colorDelta)
{
for (int i = 0; i < count; i++)
{
addFlare( createSec( averidgeSize, sizeDelta, averidgeColor, colorDelta ), warp_Math.random( -0.5f, 3f ) );
addFlare(createSec(averidgeSize, sizeDelta, averidgeColor, colorDelta), warp_Math.random(-0.5f, 3f));
}
}
override public void apply()
{
int px = flareObject.fastvertex[ 0 ].x;
int py = flareObject.fastvertex[ 0 ].y;
if ( !flareObject.fastvertex[ 0 ].visible )
{
override public void apply()
{
if (flareObject.vertexData[0].clipcode > 0)
return;
}
if ( zBufferSensitive && ( flareObject.fastvertex[ 0 ].z > scene.renderPipeline.zBuffer[ px + py * screen.width ] ) )
int px = flareObject.vertexData[0].x;
int py = flareObject.vertexData[0].y;
if (zBufferSensitive && (flareObject.vertexData[0].z > scene.renderPipeline.zBuffer[px + py * screen.width]))
{
return;
}
int cx=screen.width/2;
int cy=screen.height/2;
int cx = screen.width / 2;
int cy = screen.height / 2;
float dx=(float)(cx-px);
float dy=(float)(cy-py);
int posx,posy,xsize,ysize;
float zoom;
for (int i=0; i<flares;i++)
{
zoom=warp_Math.pythagoras(dx,dy)/warp_Math.pythagoras(cx,cy);
zoom=(1-zoom)/2+1;
xsize=flare[i].width;
ysize=flare[i].height;
posx=px+(int)(dx*flareDist[i]);
posy=py+(int)(dy*flareDist[i]);
float dx = (float)(cx - px);
float dy = (float)(cy - py);
int posx, posy, xsize, ysize;
float zoom;
screen.add(flare[i],posx-xsize/2,posy-ysize/2,xsize,ysize);
}
}
private void addFlare(warp_Texture texture, float relPos)
{
flares++;
if (flares == 1)
{
flare=new warp_Texture[1];
flareDist=new float[1];
}
else
{
warp_Texture[] temp1=new warp_Texture[flares];
System.Array.Copy(flare,0,temp1,0,flares-1); // check this
flare=temp1;
float[] temp2=new float[flares];
System.Array.Copy(flareDist, 0, temp2, 0, flares - 1 );
flareDist=temp2;
}
flare[flares-1]=texture;
flareDist[flares-1]=relPos;
}
private warp_Texture createRadialTexture(int w, int h, int[] colormap, int[] alphamap)
{
int offset;
float relX,relY;
warp_Texture newTexture=new warp_Texture(w,h);
int[] palette=getPalette(colormap, alphamap);
for(int y=h-1;y>=0;y--)
{
offset=y*w;
for (int x=w-1;x>=0;x--)
{
relX=(float)(x-(w>>1))/(float)(w>>1);
relY=(float)(y-(h>>1))/(float)(h>>1);
newTexture.pixel[offset+x]=palette[warp_Math.crop((int)(255*Math.Sqrt(relX*relX+relY*relY)),0,255)];
}
}
for (int i = 0; i < flares; i++)
{
zoom = warp_Math.pythagoras(dx, dy) / warp_Math.pythagoras(cx, cy);
zoom = (1 - zoom) / 2 + 1;
xsize = flare[i].width;
ysize = flare[i].height;
posx = px + (int)(dx * flareDist[i]);
posy = py + (int)(dy * flareDist[i]);
return newTexture;
}
private int[] getPalette(int[] color, int[] alpha)
{
int r,g,b;
int[] palette=new int[256];
for (int i=255;i>=0;i--)
{
r=(((color[i]>>16)&255)*alpha[i])>>8;
g=(((color[i]>>8)&255)*alpha[i])>>8;
b=((color[i]&255)*alpha[i])>>8;
palette[i]=warp_Color.getColor(r,g,b);
}
return palette;
}
private warp_Texture createGlow(int w, int h, int color, int alpha)
{
return createRadialTexture(w,h,getGlowPalette(color),getConstantAlpha(alpha));
}
private warp_Texture createRing(int size, int color)
{
return createRadialTexture(size,size,getColorPalette(color,color),getRingAlpha(40));
}
private warp_Texture createSec(int size, int sizedelta, int color, int colordelta)
{
int s=(int)warp_Math.randomWithDelta(size,sizedelta);
int c1=warp_Color.random(color,colordelta);
int c2=warp_Color.random(color,colordelta);
return createRadialTexture(s,s,getColorPalette(c1,c2),getSecAlpha());
}
private warp_Texture createRays(int size, int rays, int rad, int color)
{
int pos;
float relPos;
warp_Texture texture=new warp_Texture(size,size);
int[] radialMap=new int [1024];
warp_Math.clearBuffer(radialMap, 0);
screen.add(flare[i], posx - xsize / 2, posy - ysize / 2, xsize, ysize);
}
}
for (int i=0;i<rays;i++)
{
pos=(int)warp_Math.random(rad,1023-rad);
for (int k=pos-rad; k<=pos+rad; k++)
{
relPos=(float)(k-pos+rad)/(float)(rad*2);
radialMap[k]+=(int)(255*(1+Math.Sin((relPos-0.25)*3.14159*2))/2);
}
}
private void addFlare(warp_Texture texture, float relPos)
{
flares++;
int angle,offset,reldist;
float xrel,yrel;
for (int y=size-1;y>=0;y--)
{
offset=y*size;
for (int x=size-1;x>=0;x--)
{
xrel=(float)(2*x-size)/(float)size;
yrel=(float)(2*y-size)/(float)size;
angle=(int)(1023*Math.Atan2(xrel,yrel)/3.14159/2)&1023;
reldist=Math.Max((int)(255-255*warp_Math.pythagoras(xrel,yrel)),0);
texture.pixel[x+offset]=warp_Color.scale(color, radialMap[angle]*reldist/255);
}
}
if (flares == 1)
{
flare = new warp_Texture[1];
flareDist = new float[1];
}
else
{
warp_Texture[] temp1 = new warp_Texture[flares];
System.Array.Copy(flare, 0, temp1, 0, flares - 1); // check this
flare = temp1;
return texture;
}
private int[] getGlowPalette(int color)
{
int r,g,b;
float relDist,diffuse,specular;
int[] palette=new int[256];
int cr=(color>>16)&255;
int cg=(color>>8)&255;
int cb=color&255;
for (int i=255;i>=0;i--)
{
relDist=(float)i/255;
diffuse=(float)Math.Cos(relDist*1.57);
specular=(float)(255/Math.Pow(2.718,relDist*2.718)-(float)i/16);
r=(int)((float)cr*diffuse+specular);
g=(int)((float)cg*diffuse+specular);
b=(int)((float)cb*diffuse+specular);
palette[i]=warp_Color.getCropColor(r,g,b);
}
float[] temp2 = new float[flares];
System.Array.Copy(flareDist, 0, temp2, 0, flares - 1);
flareDist = temp2;
}
flare[flares - 1] = texture;
flareDist[flares - 1] = relPos;
}
private warp_Texture createRadialTexture(int w, int h, int[] colormap, int[] alphamap)
{
int offset;
float relX, relY;
warp_Texture newTexture = new warp_Texture(w, h);
int[] palette = getPalette(colormap, alphamap);
for (int y = h - 1; y >= 0; y--)
{
offset = y * w;
for (int x = w - 1; x >= 0; x--)
{
relX = (float)(x - (w >> 1)) / (float)(w >> 1);
relY = (float)(y - (h >> 1)) / (float)(h >> 1);
newTexture.pixel[offset + x] = palette[warp_Math.crop((int)(255 * Math.Sqrt(relX * relX + relY * relY)), 0, 255)];
}
}
return newTexture;
}
private int[] getPalette(int[] color, int[] alpha)
{
int r, g, b;
int[] palette = new int[256];
for (int i = 255; i >= 0; i--)
{
r = (((color[i] >> 16) & 255) * alpha[i]) >> 8;
g = (((color[i] >> 8) & 255) * alpha[i]) >> 8;
b = ((color[i] & 255) * alpha[i]) >> 8;
palette[i] = warp_Color.getColor(r, g, b);
}
return palette;
}
private int[] getConstantAlpha(int alpha)
{
int[] alphaPalette=new int[256];
for (int i=255;i>=0;i--) alphaPalette[i]=alpha;
return alphaPalette;
}
private int[] getLinearAlpha()
{
int[] alphaPalette=new int[256];
for ( int i = 255; i >= 0; i-- )
}
private warp_Texture createGlow(int w, int h, int color, int alpha)
{
return createRadialTexture(w, h, getGlowPalette(color), getConstantAlpha(alpha));
}
private warp_Texture createRing(int size, int color)
{
return createRadialTexture(size, size, getColorPalette(color, color), getRingAlpha(40));
}
private warp_Texture createSec(int size, int sizedelta, int color, int colordelta)
{
int s = (int)warp_Math.randomWithDelta(size, sizedelta);
int c1 = warp_Color.random(color, colordelta);
int c2 = warp_Color.random(color, colordelta);
return createRadialTexture(s, s, getColorPalette(c1, c2), getSecAlpha());
}
private warp_Texture createRays(int size, int rays, int rad, int color)
{
int pos;
float relPos;
warp_Texture texture = new warp_Texture(size, size);
int[] radialMap = new int[1024];
warp_Math.clearBuffer(radialMap, 0);
for (int i = 0; i < rays; i++)
{
alphaPalette[ i ] = 255 - i;
}
return alphaPalette;
}
private int[] getRingAlpha(int ringsize)
{
int[] alphaPalette=new int[256];
float angle;
for ( int i = 0; i < 256; i++ )
{
alphaPalette[ i ] = 0;
pos = (int)warp_Math.random(rad, 1023 - rad);
for (int k = pos - rad; k <= pos + rad; k++)
{
relPos = (float)(k - pos + rad) / (float)(rad * 2);
radialMap[k] += (int)(255 * (1f + MathF.Sin((relPos - 0.25f) * 3.14159f * 2f)) / 2f);
}
}
for (int i=0;i<ringsize;i++)
{
angle=3.14159f/180*(float)(180*i/ringsize);
alphaPalette[255-ringsize+i]=(int)(64*Math.Sin(angle));
}
return alphaPalette;
}
private int[] getSecAlpha()
{
int[] alphaPalette=getRingAlpha((int)warp_Math.random(0,255));
for ( int i = 0; i < 256; i++ )
int angle, offset, reldist;
float xrel, yrel;
for (int y = size - 1; y >= 0; y--)
{
alphaPalette[ i ] = ( alphaPalette[ i ] + 255 - i ) >> 2;
offset = y * size;
for (int x = size - 1; x >= 0; x--)
{
xrel = (float)(2 * x - size) / (float)size;
yrel = (float)(2 * y - size) / (float)size;
angle = (int)(1023 * MathF.Atan2(xrel, yrel) / 3.14159 / 2) & 1023;
reldist = Math.Max((int)(255 - 255 * warp_Math.pythagoras(xrel, yrel)), 0);
texture.pixel[x + offset] = warp_Color.scale(color, radialMap[angle] * reldist / 255);
}
}
return texture;
}
private int[] getGlowPalette(int color)
{
int r, g, b;
float relDist, diffuse, specular;
int[] palette = new int[256];
int cr = (color >> 16) & 255;
int cg = (color >> 8) & 255;
int cb = color & 255;
for (int i = 255; i >= 0; i--)
{
relDist = (float)i / 255f;
diffuse = MathF.Cos(relDist * 1.57f);
specular = (float)(255f / MathF.Pow(2.718f, relDist * 2.718f) - (float)i / 16f);
r = (int)((float)cr * diffuse + specular);
g = (int)((float)cg * diffuse + specular);
b = (int)((float)cb * diffuse + specular);
palette[i] = warp_Color.getCropColor(r, g, b);
}
return palette;
}
private int[] getConstantAlpha(int alpha)
{
int[] alphaPalette = new int[256];
for (int i = 255; i >= 0; i--) alphaPalette[i] = alpha;
return alphaPalette;
}
private int[] getColorPalette(int color1, int color2)
{
int[] palette=new int[256];
}
int r1=(color1>>16)&255;
int g1=(color1>>8)&255;
int b1=color1&255;
int r2=(color2>>16)&255;
int g2=(color2>>8)&255;
int b2=color2&255;
int dr=r2-r1;
int dg=g2-g1;
int db=b2-b1;
int r=r1<<8;
int g=g1<<8;
int b=b1<<8;
private int[] getLinearAlpha()
{
int[] alphaPalette = new int[256];
for (int i = 255; i >= 0; i--)
{
alphaPalette[i] = 255 - i;
}
for (int i=0;i<256;i++)
{
palette[i]=warp_Color.getColor(r>>8,g>>8,b>>8);
r+=dr; g+=dg; b+=db;
}
return palette;
}
return alphaPalette;
}
private int[] getRingAlpha(int ringsize)
{
int[] alphaPalette = new int[256];
float angle;
for (int i = 0; i < 256; i++)
{
alphaPalette[i] = 0;
}
for (int i = 0; i < ringsize; i++)
{
angle = 3.14159f / 180 * (float)(180 * i / ringsize);
alphaPalette[255 - ringsize + i] = (int)(64 * MathF.Sin(angle));
}
return alphaPalette;
}
private int[] getSecAlpha()
{
int[] alphaPalette = getRingAlpha((int)warp_Math.random(0, 255));
for (int i = 0; i < 256; i++)
{
alphaPalette[i] = (alphaPalette[i] + 255 - i) >> 2;
}
return alphaPalette;
}
private int[] getColorPalette(int color1, int color2)
{
int[] palette = new int[256];
int r1 = (color1 >> 16) & 255;
int g1 = (color1 >> 8) & 255;
int b1 = color1 & 255;
int r2 = (color2 >> 16) & 255;
int g2 = (color2 >> 8) & 255;
int b2 = color2 & 255;
int dr = r2 - r1;
int dg = g2 - g1;
int db = b2 - b1;
int r = r1 << 8;
int g = g1 << 8;
int b = b1 << 8;
for (int i = 0; i < 256; i++)
{
palette[i] = warp_Color.getColor(r >> 8, g >> 8, b >> 8);
r += dr; g += dg; b += db;
}
return palette;
}
}
}
+7 -7
View File
@@ -9,12 +9,12 @@ namespace Warp3D
public warp_Scene scene = null;
public warp_Screen screen = null;
public warp_FXPlugin( warp_Scene scene )
{
this.scene = scene;
screen = scene.renderPipeline.screen;
}
public abstract void apply();
public warp_FXPlugin(warp_Scene scene)
{
this.scene = scene;
screen = scene.renderPipeline.screen;
}
public abstract void apply();
}
}
+53 -53
View File
@@ -2,65 +2,65 @@ using System;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_Light.
/// </summary>
public class warp_Light
{
// F I E L D S
/// <summary>
/// Summary description for warp_Light.
/// </summary>
public class warp_Light
{
// F I E L D S
public warp_Vector v; //Light direction
public warp_Vector v2; //projected Light direction
public int diffuse = 0;
public int specular = 0;
public int highlightSheen = 0;
public int highlightSpread = 0;
public warp_Vector v; //Light direction
public warp_Vector v2; //projected Light direction
public int diffuse = 0;
public int specular = 0;
public int highlightSheen = 0;
public int highlightSpread = 0;
warp_Matrix matrix2;
warp_Matrix matrix2;
private warp_Light()
// Default constructor not accessible
{
}
private warp_Light()
// Default constructor not accessible
{
}
public warp_Light(warp_Vector direction)
{
v = direction.getClone();
v.normalize();
}
public warp_Light(warp_Vector direction)
{
v = direction.getClone();
v.normalize();
}
public warp_Light(warp_Vector direction, int diffuse)
{
v = direction.getClone();
v.normalize();
this.diffuse = diffuse;
}
public warp_Light(warp_Vector direction, int diffuse)
{
v = direction.getClone();
v.normalize();
this.diffuse = diffuse;
}
public warp_Light(warp_Vector direction, int color, int highlightSheen, int highlightSpread)
{
v = direction.getClone();
v.normalize();
this.diffuse = color;
this.specular = color;
this.highlightSheen = highlightSheen;
this.highlightSpread = highlightSpread;
}
public warp_Light(warp_Vector direction, int color, int highlightSheen, int highlightSpread)
{
v = direction.getClone();
v.normalize();
diffuse = color;
specular = color;
this.highlightSheen = highlightSheen;
this.highlightSpread = highlightSpread;
}
public warp_Light(warp_Vector direction, int diffuse, int specular,int highlightSheen, int highlightSpread)
{
v = direction.getClone();
v.normalize();
this.diffuse = diffuse;
this.specular = specular;
this.highlightSheen = highlightSheen;
this.highlightSpread = highlightSpread;
}
public warp_Light(warp_Vector direction, int diffuse, int specular, int highlightSheen, int highlightSpread)
{
v = direction.getClone();
v.normalize();
this.diffuse = diffuse;
this.specular = specular;
this.highlightSheen = highlightSheen;
this.highlightSpread = highlightSpread;
}
public void project(warp_Matrix m)
{
matrix2 = m.getClone();
matrix2.transform(m);
v2 = v.transform(matrix2);
}
}
public void project(warp_Matrix m)
{
matrix2 = m.getClone();
matrix2.transform(m);
v2 = v.transform(matrix2);
}
}
}
+29 -22
View File
@@ -1,4 +1,6 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Warp3D
{
@@ -9,21 +11,20 @@ namespace Warp3D
{
public int[] diffuse = new int[65536];
public int[] specular = new int[65536];
private float[] sphere = new float[65536];
private warp_Light[] light;
private int lights;
private int ambient;
private readonly float[] sphere = new float[65536];
private readonly warp_Light[] light;
private readonly int ambient;
private int pos;
const float inv128 = 1.0f/128f;
const float inv255 = 1.0f/255f;
const float inv128 = 1.0f / 128f;
const float inv255 = 1.0f / 255f;
const float inv4096 = 1.0f / 4096f;
public warp_Lightmap(warp_Scene scene)
{
scene.rebuild();
light = scene.light;
lights = scene.lights;
ambient = scene.environment.ambient;
buildSphereMap();
@@ -35,30 +36,36 @@ namespace Warp3D
float fnx, fny, fnz;
float fnySQ;
int pos;
for(int ny = -128; ny < 128; ny++)
ref float sphereref = ref MemoryMarshal.GetArrayDataReference(sphere);
for (int ny = -128; ny < 128; ny++)
{
fny = ny * inv128;
fnySQ = fny * fny;
pos = (ny + 128) << 8;
for(int nx = -128; nx < 128; nx++, pos++)
for (int nx = -128; nx < 128; nx++, pos++)
{
fnx = nx * inv128;
fnz = (float)(1 - Math.Sqrt(fnx * fnx + fnySQ));
sphere[pos] = (fnz > 0) ? fnz : 0;
fnz = 1f - MathF.Sqrt(fnx * fnx + fnySQ);
Unsafe.As<float, float>(ref Unsafe.Add(ref sphereref, pos)) = (fnz > 0) ? fnz : 0;
}
}
}
public void rebuildLightmap()
{
warp_Vector l;
float fnx, fny, phongfact, sheen, spread;
int diffuse, specular, cos, dr, dg, db, sr, sg, sb;
for(int ny = -128; ny < 128; ny++)
ref int difuseref = ref MemoryMarshal.GetArrayDataReference(this.diffuse);
ref int specularref = ref MemoryMarshal.GetArrayDataReference(this.specular);
ref float sphereref = ref MemoryMarshal.GetArrayDataReference(sphere);
for (int ny = -128; ny < 128; ny++)
{
fny = ny * inv128;
pos = (ny + 128) << 8;
for(int nx = -128; nx < 128; nx++, pos++)
for (int nx = -128; nx < 128; nx++, pos++)
{
fnx = nx * inv128;
sr = sg = sb = 0;
@@ -67,26 +74,26 @@ namespace Warp3D
dg = warp_Color.getGreen(ambient);
db = warp_Color.getBlue(ambient);
for(int i = 0; i < lights; i++)
for (int i = 0; i < light.Length; i++)
{
l = light[i].v;
diffuse = light[i].diffuse;
specular = light[i].specular;
sheen = (float)light[i].highlightSheen * inv255;
spread = (float)light[i].highlightSpread / 4096;
sheen = light[i].highlightSheen * inv255;
spread = light[i].highlightSpread * inv4096;
spread = (spread < 0.01f) ? 0.01f : spread;
cos = (int)(255 * warp_Vector.vectorsCos(light[i].v, new warp_Vector(fnx, fny, sphere[pos])));
warp_Vector tmp = new warp_Vector(fnx, fny, Unsafe.As<float, float>(ref Unsafe.Add(ref sphereref, pos)));
cos = (int)(255 * warp_Vector.vectorsCos(ref light[i].v, ref tmp));
cos = (cos > 0) ? cos : 0;
dr += (warp_Color.getRed(diffuse) * cos) >> 8;
dg += (warp_Color.getGreen(diffuse) * cos) >> 8;
db += (warp_Color.getBlue(diffuse) * cos) >> 8;
phongfact = sheen * (float)Math.Pow((float)cos * inv255, 1 / spread);
phongfact = sheen * (float)MathF.Pow((float)cos * inv255, 1 / spread);
sr += (int)((float)warp_Color.getRed(specular) * phongfact);
sg += (int)((float)warp_Color.getGreen(specular) * phongfact);
sb += (int)((float)warp_Color.getBlue(specular) * phongfact);
}
this.diffuse[pos] = warp_Color.getCropColor(dr, dg, db);
this.specular[pos] = warp_Color.getCropColor(sr, sg, sb);
Unsafe.As<int, int>(ref Unsafe.Add(ref difuseref, pos)) = warp_Color.getCropColor(dr, dg, db);
Unsafe.As<int, int>(ref Unsafe.Add(ref specularref, pos)) = warp_Color.getCropColor(sr, sg, sb);
}
}
}
+229 -214
View File
@@ -1,241 +1,256 @@
using System;
using System.Drawing;
using System.IO;
using System.Runtime.CompilerServices;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_Material.
/// </summary>
public class warp_Material
{
public int color = warp_Color.White;
public int reflectivity=255;
public int type=0;
public warp_Texture texture=null;
public warp_Texture envmap=null;
public bool flat=false;
public bool wireframe=false;
public String texturePath=null;
public String envmapPath=null;
public warp_TextureSettings textureSettings=null;
public warp_TextureSettings envmapSettings=null;
public double rwx = 500.00;
public double rwy = 500.00;
public Point pt = new Point(0,0);
public int offset = 0;
/// <summary>
/// Summary description for warp_Material.
/// </summary>
public class warp_Material
{
public int color = warp_Color.White;
public int reflectivity = 255;
public int type = 0;
public warp_Texture texture = null;
public warp_Texture envmap = null;
public bool flat = false;
public bool wireframe = false;
public string texturePath = null;
public string envmapPath = null;
public warp_TextureSettings textureSettings = null;
public warp_TextureSettings envmapSettings = null;
public double rwx = 500.00;
public double rwy = 500.00;
public Point pt = new(0, 0);
public int offset = 0;
public warp_Material()
{
//
// TODO: Add constructor logic here
//
}
public warp_Material(int c)
{
color = c;
}
public warp_Material(warp_Texture t)
{
setTexture(t);
reflectivity=255;
}
public warp_Material(String path)
{
using(FileStream fs = new FileStream(path,FileMode.Open))
{
using(BinaryReader br = new BinaryReader(fs))
importFromStream(br);
}
}
private void importFromStream(BinaryReader inStream)
{
readSettings(inStream);
readTexture(inStream, true);
readTexture(inStream, false);
}
private void readSettings(BinaryReader inStream)
{
setColor(readInt(inStream));
setReflectivity(inStream.ReadByte());
setFlat(inStream.ReadBoolean());
}
private int readInt(BinaryReader inStream)
{
return (inStream.ReadByte() << 24) | (inStream.ReadByte() << 16) | (inStream.ReadByte() << 8) | inStream.ReadByte();
}
private string readString(BinaryReader inStream)
{
string result = "";
byte inByte;
while ( (inByte = (byte) inStream.ReadByte()) != 60)
{
result += (char) inByte;
}
return result;
}
private void readTexture(BinaryReader inStream, bool textureId)
{
warp_Texture t = null;
int id = inStream.ReadSByte();
if (id == 1)
{
t = new warp_Texture( "c:/source/Warp3D/materials/skymap.jpg" );
if (t != null && textureId)
{
texturePath = t.path;
textureSettings = null;
setTexture(t);
}
if (t != null && !textureId)
{
envmapPath = t.path;
envmapSettings = null;
setEnvmap(t);
}
}
if (id == 2)
{
int w = readInt(inStream);
int h = readInt(inStream);
int type = inStream.ReadSByte();
float persistency = readInt(inStream);
float density = readInt(inStream);
persistency = .5f;
density = .5f;
int samples = inStream.ReadByte();
int numColors = inStream.ReadByte();
int[] colors = new int[numColors];
for (int i = 0; i < numColors; i++)
{
colors[i] = readInt(inStream);
}
if (type == 1)
{
t = warp_TextureFactory.PERLIN(w, h, persistency, density, samples, 1024).colorize(warp_Color.makeGradient(colors, 1024));
}
if (type == 2)
{
t = warp_TextureFactory.WAVE(w, h, persistency, density, samples, 1024).colorize(warp_Color.makeGradient(colors, 1024));
}
if (type == 3)
{
t = warp_TextureFactory.GRAIN(w, h, persistency, density, samples, 20, 1024).colorize(warp_Color.makeGradient(colors, 1024));
}
if (textureId)
{
texturePath = null;
textureSettings = new warp_TextureSettings(t, w, h, type, persistency, density, samples, colors);
setTexture(t);
}
else
{
envmapPath = null;
envmapSettings = new warp_TextureSettings(t, w, h, type, persistency, density, samples, colors);
setEnvmap(t);
}
}
}
public void setTexture(warp_Texture t)
{
texture=t;
if (texture!=null)
texture.resize();
}
public void setEnvmap(warp_Texture env)
{
envmap=env;
env.resize(256,256);
}
public void setColor(int c)
{
color = c;
}
public bool opaque
public warp_Material()
{
//
// TODO: Add constructor logic here
//
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Material(int c)
{
color = c;
}
public warp_Material(warp_Texture t)
{
setTexture(t);
reflectivity = 255;
}
public warp_Material(string path)
{
using FileStream fs = new(path, FileMode.Open);
using BinaryReader br = new(fs);
importFromStream(br);
}
private void importFromStream(BinaryReader inStream)
{
readSettings(inStream);
readTexture(inStream, true);
readTexture(inStream, false);
}
private void readSettings(BinaryReader inStream)
{
setColor(readInt(inStream));
setReflectivity(inStream.ReadByte());
setFlat(inStream.ReadBoolean());
}
private int readInt(BinaryReader inStream)
{
return (inStream.ReadByte() << 24) | (inStream.ReadByte() << 16) | (inStream.ReadByte() << 8) | inStream.ReadByte();
}
private string readString(BinaryReader inStream)
{
string result = "";
byte inByte;
while ((inByte = (byte)inStream.ReadByte()) != 60)
{
result += (char)inByte;
}
return result;
}
private void readTexture(BinaryReader inStream, bool textureId)
{
warp_Texture t = null;
int id = inStream.ReadSByte();
if (id == 1)
{
t = new warp_Texture("c:/source/Warp3D/materials/skymap.jpg");
if (t != null && textureId)
{
texturePath = t.path;
textureSettings = null;
setTexture(t);
}
if (t != null && !textureId)
{
envmapPath = t.path;
envmapSettings = null;
setEnvmap(t);
}
}
if (id == 2)
{
int w = readInt(inStream);
int h = readInt(inStream);
int type = inStream.ReadSByte();
float persistency = readInt(inStream);
float density = readInt(inStream);
persistency = .5f;
density = .5f;
int samples = inStream.ReadByte();
int numColors = inStream.ReadByte();
int[] colors = new int[numColors];
for (int i = 0; i < numColors; i++)
{
colors[i] = readInt(inStream);
}
if (type == 1)
{
t = warp_TextureFactory.PERLIN(w, h, persistency, density, samples, 1024).colorize(warp_Color.makeGradient(colors, 1024));
}
if (type == 2)
{
t = warp_TextureFactory.WAVE(w, h, persistency, density, samples, 1024).colorize(warp_Color.makeGradient(colors, 1024));
}
if (type == 3)
{
t = warp_TextureFactory.GRAIN(w, h, persistency, density, samples, 20, 1024).colorize(warp_Color.makeGradient(colors, 1024));
}
if (textureId)
{
texturePath = null;
textureSettings = new warp_TextureSettings(t, w, h, type, persistency, density, samples, colors);
setTexture(t);
}
else
{
envmapPath = null;
envmapSettings = new warp_TextureSettings(t, w, h, type, persistency, density, samples, colors);
setEnvmap(t);
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setTexture(warp_Texture t)
{
texture = t;
texture?.resize();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setEnvmap(warp_Texture env)
{
envmap = env;
envmap?.resize(256, 256);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setColor(int c)
{
color = c;
}
public bool opaque
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
if((color & warp_Color.MASKALPHA) != warp_Color.MASKALPHA)
if ((color & warp_Color.MASKALPHA) != warp_Color.MASKALPHA)
return false;
if(texture != null)
if (texture is not null)
return texture.opaque;
return true;
}
}
public void setReflectivity(int factor)
{
reflectivity=warp_Math.crop(factor,0,255);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setReflectivity(int factor)
{
reflectivity = warp_Math.crop(factor, 0, 255);
}
public void setFlat(bool flat)
{
this.flat=flat;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setFlat(bool flat)
{
this.flat = flat;
}
public void setWireframe(bool wireframe)
{
this.wireframe=wireframe;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setWireframe(bool wireframe)
{
this.wireframe = wireframe;
}
public void setType(int type)
{
this.type = type;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setType(int type)
{
this.type = type;
}
public warp_Texture getTexture()
{
return texture;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Texture getTexture()
{
return texture;
}
public warp_Texture getEnvmap()
{
return envmap;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Texture getEnvmap()
{
return envmap;
}
public int getColor()
{
return color;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int getColor()
{
return color;
}
public int getReflectivity()
{
return reflectivity;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int getReflectivity()
{
return reflectivity;
}
public int getType()
{
return type;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int getType()
{
return type;
}
public bool isFlat()
{
return flat;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool isFlat()
{
return flat;
}
public bool isWireframe()
{
return wireframe;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool isWireframe()
{
return wireframe;
}
}
}
+35 -141
View File
@@ -1,4 +1,5 @@
using System;
using System.Runtime.CompilerServices;
namespace Warp3D
{
@@ -7,218 +8,111 @@ namespace Warp3D
/// </summary>
public class warp_Math
{
// private static float[] sinus;
// private static float[] cosinus;
// private static bool trig=false;
public static float pi = 3.1415926535f;
// private static float rad2scale=4096f/3.14159265f/2f;
// private static float pad=256*3.14159265f;
private static int[] fastRandoms;
private static int fastRndPointer = 0;
private static bool fastRndInit = false;
private static Random _rnd = new Random();
public warp_Math()
{
//
// TODO: Add constructor logic here
//
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float interpolate(float a, float b, float d)
{
float f = (1 - cos(d * pi)) * 0.5f;
float f = (1f - MathF.Cos(d * MathF.PI)) * 0.5f;
return a + f * (b - a);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float random()
{
Random rnd = new Random();
return (float)(rnd.NextDouble() * 2 - 1);
return Random.Shared.NextSingle();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float random(float min, float max)
{
//Random rnd = new Random();
return (float)(_rnd.NextDouble() * (max - min) + min);
return Random.Shared.NextSingle() * (max - min) + min;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float randomWithDelta(float averidge, float delta)
{
return averidge + random() * delta;
}
public static int fastRnd(int bits)
{
if (bits < 1)
{
return 0;
}
fastRndPointer = (fastRndPointer + 1) & 31;
if (!fastRndInit)
{
fastRandoms = new int[32];
for (int i = 0; i < 32; i++)
{
fastRandoms[i] = (int)random(0, 0xFFFFFF);
}
fastRndInit = true;
}
return fastRandoms[fastRndPointer] & (1 << (bits - 1));
}
public static int fastRndBit()
{
return fastRnd(1);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float deg2rad(float deg)
{
return deg * 0.0174532925194f;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float rad2deg(float rad)
{
return rad * 57.295779514719f;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float sin(float angle)
{
return (float)Math.Sin(angle);
// if(!trig) buildTrig();
// return sinus[(int)((angle+pad)*rad2scale)&0xFFF];
return MathF.Sin(angle);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float cos(float angle)
{
return (float)Math.Cos(angle);
// if(!trig) buildTrig();
// return cosinus[(int)((angle+pad)*rad2scale)&0xFFF];
return MathF.Cos(angle);
}
/*
private static void buildTrig()
{
sinus=new float[4096];
cosinus=new float[4096];
for (int i=0;i<4096;i++)
{
sinus[i]=(float)Math.Sin((float)i/rad2scale);
cosinus[i]=(float)Math.Cos((float)i/rad2scale);
}
trig=true;
}
*/
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float pythagoras(float a, float b)
{
return (float)Math.Sqrt(a * a + b * b);
return MathF.Sqrt(a * a + b * b);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int pythagoras(int a, int b)
{
return (int)Math.Sqrt(a * a + b * b);
return (int)MathF.Sqrt(a * a + b * b);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int crop(int num, int min, int max)
{
return (num < min) ? min : (num > max) ? max : num;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float crop(float num, float min, float max)
{
return (num < min) ? min : (num > max) ? max : num;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool inrange(int num, int min, int max)
{
return ((num >= min) && (num < max));
}
unsafe public static void clearBuffer(int[] buffer, int c)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void clearBuffer(int[] buffer, int c)
{
/*
for (int idx = 0; idx < buffer.Length; idx++)
{
buffer[idx] = c;
}
*/
fixed (int* pC = buffer)
{
int* pClear = pC;
for (int i = 0; i < buffer.GetLength(0) / 4; i++)
{
*pClear++ = c;
*pClear++ = c;
*pClear++ = c;
*pClear++ = c;
}
}
if (c == 0)
Array.Clear(buffer);
else
Array.Fill(buffer, c);
}
unsafe public static void clearBuffer(long[] buffer, int c)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void clearBuffer(byte[] buffer, byte c)
{
/* for (int idx = 0; idx < buffer.Length; idx++)
{
buffer[idx] = c;
}*/
fixed (long* pC = buffer)
{
long* pClear = pC;
for (int i = 0; i < buffer.GetLength(0) / 4; i++)
{
*pClear++ = c;
*pClear++ = c;
*pClear++ = c;
*pClear++ = c;
}
}
}
public static void clearBuffer(byte[] buffer, byte value)
{
System.Array.Clear(buffer, 0, buffer.GetLength(0));
}
public static void cropBuffer(int[] buffer, int min, int max)
{
for (int i = buffer.GetLength(0) - 1; i >= 0; i--) buffer[i] = crop(buffer[i], min, max);
if (c == 0)
Array.Clear(buffer);
else
Array.Fill(buffer, c);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void copyBuffer(int[] source, int[] target)
{
System.Array.Copy(source, 0, target, 0, crop(source.GetLength(0), 0, target.GetLength(0)));
Array.Copy(source, target, crop(source.GetLength(0), 0, target.GetLength(0)));
}
/*
public static float random()
{
return (float)(Math.r.random()*2-1);
}
public static float random(float min, float max)
{
return (float)(Math.random()*(max-min)+min);
}
public static float randomWithDelta(float averidge, float delta)
{
return averidge+random()*delta;
}
*/
}
}
+390 -337
View File
@@ -2,57 +2,55 @@ using System;
namespace Warp3D
{
public class warp_Matrix
{
public float m00=1, m01=0, m02=0, m03=0;
public float m10=0, m11=1, m12=0, m13=0;
public float m20=0, m21=0, m22=1, m23=0;
public float m30=0, m31=0, m32=0, m33=1;
public class warp_Matrix
{
public float m00 = 1, m01 = 0, m02 = 0, m03 = 0;
public float m10 = 0, m11 = 1, m12 = 0, m13 = 0;
public float m20 = 0, m21 = 0, m22 = 1, m23 = 0;
public float m30 = 0, m31 = 0, m32 = 0, m33 = 1;
public warp_Matrix(warp_Vector right, warp_Vector up, warp_Vector forward)
{
m00=right.x;
m10=right.y;
m20=right.z;
m01=up.x;
m11=up.y;
m21=up.z;
m02=forward.x;
m12=forward.y;
m22=forward.z;
}
public warp_Matrix(warp_Vector right, warp_Vector up, warp_Vector forward)
{
m00 = right.x;
m10 = right.y;
m20 = right.z;
m01 = up.x;
m11 = up.y;
m21 = up.z;
m02 = forward.x;
m12 = forward.y;
m22 = forward.z;
}
public float this[ int column, int row ]
public float this[int column, int row]
{
get
{
switch ( row )
switch (row)
{
case 0:
if ( column == 0 ) return m00;
if ( column == 1 ) return m01;
if ( column == 2 ) return m02;
if ( column == 3 ) return m03;
if (column == 0) return m00;
if (column == 1) return m01;
if (column == 2) return m02;
if (column == 3) return m03;
break;
case 1:
if ( column == 0 ) return m11;
if ( column == 1 ) return m11;
if ( column == 2 ) return m12;
if ( column == 3 ) return m13;
if (column == 0) return m11;
if (column == 1) return m11;
if (column == 2) return m12;
if (column == 3) return m13;
break;
case 2:
if ( column == 0 ) return m20;
if ( column == 1 ) return m21;
if ( column == 2 ) return m22;
if ( column == 3 ) return m23;
if (column == 0) return m20;
if (column == 1) return m21;
if (column == 2) return m22;
if (column == 3) return m23;
break;
case 3:
if ( column == 0 ) return m30;
if ( column == 1 ) return m31;
if ( column == 2 ) return m32;
if ( column == 3 ) return m33;
if (column == 0) return m30;
if (column == 1) return m31;
if (column == 2) return m32;
if (column == 3) return m33;
break;
default:
@@ -63,343 +61,398 @@ namespace Warp3D
}
}
public warp_Matrix()
{
//
// TODO: Add constructor logic here
//
}
public static warp_Matrix shiftMatrix(float dx, float dy, float dz)
// matrix for shifting
{
warp_Matrix m=new warp_Matrix();
m.m03=dx;
m.m13=dy;
m.m23=dz;
return m;
}
public static warp_Matrix quaternionMatrix( warp_Quaternion quat )
public warp_Matrix()
{
warp_Matrix m = new warp_Matrix();
//
// TODO: Add constructor logic here
//
}
float xx = quat.X * quat.X;
float xy = quat.X * quat.Y;
float xz = quat.X * quat.Z;
float xw = quat.X * quat.W;
float yy = quat.Y * quat.Y;
float yz = quat.Y * quat.Z;
float yw = quat.Y * quat.W;
float zz = quat.Z * quat.Z;
float zw = quat.Z * quat.W;
m.m00 = 1 - 2 * ( yy + zz );
m.m01 = 2 * ( xy - zw) ;
m.m02 = 2*(xz + yw);
m.m10 = 2*(xy + zw);
m.m11 = 1 - 2* ( xx + zz );
m.m12 = 2*(yz - xw);
m.m20 = 2*(xz - yw);
m.m21 = 2*(yz + xw);
m.m22 = 1 - 2 * ( xx + yy );
m.m03 = m.m13 = m.m23 = m.m30 = m.m31 = m.m32 = 0;
m.m33 = 1;
public static warp_Matrix shiftMatrix(float dx, float dy, float dz)
// matrix for shifting
{
warp_Matrix m = new()
{
m03 = dx,
m13 = dy,
m23 = dz
};
return m;
}
public warp_Matrix rotateMatrix( warp_Quaternion quat )
public static warp_Matrix quaternionMatrix(warp_Quaternion quat)
{
float x2 = quat.X + quat.X;
float y2 = quat.Y + quat.Y;
float z2 = quat.Z + quat.Z;
float wx2 = quat.W * x2;
float wy2 = quat.W * y2;
float wz2 = quat.W * z2;
float xx2 = quat.X * x2;
float xy2 = quat.X * y2;
float xz2 = quat.X * z2;
float yy2 = quat.Y * y2;
float yz2 = quat.Y * z2;
float zz2 = quat.Z * z2;
return new()
{
m00 = 1.0f - yy2 - zz2,
m01 = xy2 - wz2,
m02 = xz2 + wy2,
m03 = 0f,
m10 = xy2 + wz2,
m11 = 1.0f - xx2 - zz2,
m12 = yz2 - wx2,
m13 = 0f,
m20 = xz2 - wy2,
m21 = yz2 + wx2,
m22 = 1.0f - xx2 - yy2,
m23 = 0f,
m30 = 0f,
m31 = 0f,
m32 = 0f,
m33 = 1f
};
}
public warp_Matrix rotateMatrix(warp_Quaternion quat)
{
reset();
warp_Matrix temp = warp_Matrix.quaternionMatrix( quat );
warp_Matrix result = warp_Matrix.multiply( this, temp );
warp_Matrix temp = warp_Matrix.quaternionMatrix(quat);
warp_Matrix result = warp_Matrix.multiply(this, temp);
return result;
return result;
}
public static warp_Matrix scaleMatrix(float dx, float dy, float dz)
{
warp_Matrix m=new warp_Matrix();
m.m00=dx;
m.m11=dy;
m.m22=dz;
return m;
}
public static warp_Matrix scaleMatrix(float d)
{
return warp_Matrix.scaleMatrix(d,d,d);
}
public static warp_Matrix rotateMatrix(float dx, float dy, float dz)
{
warp_Matrix res=new warp_Matrix();
float SIN;
float COS;
if (dx!=0)
{
warp_Matrix m = new warp_Matrix();
SIN=warp_Math.sin(dx);
COS=warp_Math.cos(dx);
m.m11=COS;
m.m12=SIN;
m.m21=-SIN;
m.m22=COS;
res.transform(m);
}
if (dy!=0)
{
warp_Matrix m =new warp_Matrix();
SIN=warp_Math.sin(dy);
COS=warp_Math.cos(dy);
m.m00=COS;
m.m02=SIN;
m.m20=-SIN;
m.m22=COS;
res.transform(m);
}
if (dz!=0)
{
warp_Matrix m =new warp_Matrix();
SIN=warp_Math.sin(dz);
COS=warp_Math.cos(dz);
m.m00=COS;
m.m01=SIN;
m.m10=-SIN;
m.m11=COS;
res.transform(m);
}
return res;
}
public void shift(float dx, float dy, float dz)
{
m03 += dx;
m13 += dy;
m23 += dz;
}
public void scale(float dx, float dy, float dz)
{
// transform(scaleMatrix(dx,dy,dz));
m00 *= dx;
m01 *= dx;
m02 *= dx;
m03 *= dx;
m10 *= dy;
m11 *= dy;
m12 *= dy;
m13 *= dy;
m20 *= dz;
m21 *= dz;
m22 *= dz;
m23 *= dz;
}
public void scale(float d)
{
m00 *= d;
m01 *= d;
m02 *= d;
m03 *= d;
m10 *= d;
m11 *= d;
m12 *= d;
m13 *= d;
m20 *= d;
m21 *= d;
m22 *= d;
m23 *= d;
}
public void rotate(float dx, float dy, float dz)
{
transform(rotateMatrix(dx,dy,dz));
}
public void rotate( warp_Quaternion quat, float x, float y, float z )
public static warp_Matrix scaleMatrix(float dx, float dy, float dz)
{
transform( rotateMatrix( quat ) );
warp_Matrix m = new()
{
m00 = dx,
m11 = dy,
m22 = dz
};
return m;
}
public void rotate( warp_Matrix m )
public static warp_Matrix scaleMatrix(float d)
{
transform( m );
return warp_Matrix.scaleMatrix(d, d, d);
}
public void scaleSelf( float dx, float dy, float dz )
{
m00 *= dx;
m01 *= dy;
m02 *= dz;
m10 *= dx;
m11 *= dy;
m12 *= dz;
m20 *= dx;
m21 *= dy;
m22 *= dz;
}
public void scaleSelf(float d)
{
m00 *= d;
m01 *= d;
m02 *= d;
m10 *= d;
m11 *= d;
m12 *= d;
m20 *= d;
m21 *= d;
m22 *= d;
}
public void shiftSelf( float dx, float dy, float dz )
public static warp_Matrix rotateMatrix(float dx, float dy, float dz)
{
m03 += m00 * dx + m01 * dy + m02 * dz;
m13 += m10 * dx + m11 * dy + m12 * dz;
m23 += m20 * dx + m21 * dx + m22 * dx;
warp_Matrix res = new warp_Matrix();
float SIN;
float COS;
if (dx != 0)
{
warp_Matrix m = new warp_Matrix();
SIN = warp_Math.sin(dx);
COS = warp_Math.cos(dx);
m.m11 = COS;
m.m12 = SIN;
m.m21 = -SIN;
m.m22 = COS;
res.transform(m);
}
if (dy != 0)
{
warp_Matrix m = new warp_Matrix();
SIN = warp_Math.sin(dy);
COS = warp_Math.cos(dy);
m.m00 = COS;
m.m02 = SIN;
m.m20 = -SIN;
m.m22 = COS;
res.transform(m);
}
if (dz != 0)
{
warp_Matrix m = new warp_Matrix();
SIN = warp_Math.sin(dz);
COS = warp_Math.cos(dz);
m.m00 = COS;
m.m01 = SIN;
m.m10 = -SIN;
m.m11 = COS;
res.transform(m);
}
return res;
}
public void rotateSelf( float dx, float dy, float dz )
public void shift(float dx, float dy, float dz)
{
preTransform( rotateMatrix( dx, dy, dz ) );
m03 += dx;
m13 += dy;
m23 += dz;
}
public void rotateSelf( warp_Matrix m )
{
preTransform( m );
}
public void rotateSelf( warp_Quaternion quat )
public void scale(float dx, float dy, float dz)
{
preTransform(rotateMatrix( quat) );
// transform(scaleMatrix(dx,dy,dz));
m00 *= dx;
m01 *= dx;
m02 *= dx;
m03 *= dx;
m10 *= dy;
m11 *= dy;
m12 *= dy;
m13 *= dy;
m20 *= dz;
m21 *= dz;
m22 *= dz;
m23 *= dz;
}
public void scale(float d)
{
m00 *= d;
m01 *= d;
m02 *= d;
m03 *= d;
m10 *= d;
m11 *= d;
m12 *= d;
m13 *= d;
m20 *= d;
m21 *= d;
m22 *= d;
m23 *= d;
}
public void transform(warp_Matrix n)
{
warp_Matrix m=this.getClone();
public void rotate(float dx, float dy, float dz)
{
transform(rotateMatrix(dx, dy, dz));
}
m00 = n.m00*m.m00 + n.m01*m.m10 + n.m02*m.m20;
m01 = n.m00*m.m01 + n.m01*m.m11 + n.m02*m.m21;
m02 = n.m00*m.m02 + n.m01*m.m12 + n.m02*m.m22;
m03 = n.m00*m.m03 + n.m01*m.m13 + n.m02*m.m23 + n.m03;
m10 = n.m10*m.m00 + n.m11*m.m10 + n.m12*m.m20;
m11 = n.m10*m.m01 + n.m11*m.m11 + n.m12*m.m21;
m12 = n.m10*m.m02 + n.m11*m.m12 + n.m12*m.m22;
m13 = n.m10*m.m03 + n.m11*m.m13 + n.m12*m.m23 + n.m13;
m20 = n.m20*m.m00 + n.m21*m.m10 + n.m22*m.m20;
m21 = n.m20*m.m01 + n.m21*m.m11 + n.m22*m.m21;
m22 = n.m20*m.m02 + n.m21*m.m12 + n.m22*m.m22;
m23 = n.m20*m.m03 + n.m21*m.m13 + n.m22*m.m23 + n.m23;
}
public void rotate(warp_Quaternion quat, float x, float y, float z)
{
transform(rotateMatrix(quat));
}
public void preTransform(warp_Matrix n)
{
warp_Matrix m=this.getClone();
public void rotate(warp_Matrix m)
{
transform(m);
}
m00 = m.m00*n.m00 + m.m01*n.m10 + m.m02*n.m20;
m01 = m.m00*n.m01 + m.m01*n.m11 + m.m02*n.m21;
m02 = m.m00*n.m02 + m.m01*n.m12 + m.m02*n.m22;
m03 = m.m00*n.m03 + m.m01*n.m13 + m.m02*n.m23 + m.m03;
m10 = m.m10*n.m00 + m.m11*n.m10 + m.m12*n.m20;
m11 = m.m10*n.m01 + m.m11*n.m11 + m.m12*n.m21;
m12 = m.m10*n.m02 + m.m11*n.m12 + m.m12*n.m22;
m13 = m.m10*n.m03 + m.m11*n.m13 + m.m12*n.m23 + m.m13;
m20 = m.m20*n.m00 + m.m21*n.m10 + m.m22*n.m20;
m21 = m.m20*n.m01 + m.m21*n.m11 + m.m22*n.m21;
m22 = m.m20*n.m02 + m.m21*n.m12 + m.m22*n.m22;
m23 = m.m20*n.m03 + m.m21*n.m13 + m.m22*n.m23 + m.m23;
}
public void scaleSelf(float dx, float dy, float dz)
{
m00 *= dx;
m01 *= dy;
m02 *= dz;
m10 *= dx;
m11 *= dy;
m12 *= dz;
m20 *= dx;
m21 *= dy;
m22 *= dz;
}
public static warp_Matrix multiply(warp_Matrix m1, warp_Matrix m2)
{
warp_Matrix m=new warp_Matrix();
public void scaleSelf(float d)
{
m00 *= d;
m01 *= d;
m02 *= d;
m10 *= d;
m11 *= d;
m12 *= d;
m20 *= d;
m21 *= d;
m22 *= d;
}
m.m00 = m1.m00*m2.m00 + m1.m01*m2.m10 + m1.m02*m2.m20;
m.m01 = m1.m00*m2.m01 + m1.m01*m2.m11 + m1.m02*m2.m21;
m.m02 = m1.m00*m2.m02 + m1.m01*m2.m12 + m1.m02*m2.m22;
m.m03 = m1.m00*m2.m03 + m1.m01*m2.m13 + m1.m02*m2.m23 + m1.m03;
m.m10 = m1.m10*m2.m00 + m1.m11*m2.m10 + m1.m12*m2.m20;
m.m11 = m1.m10*m2.m01 + m1.m11*m2.m11 + m1.m12*m2.m21;
m.m12 = m1.m10*m2.m02 + m1.m11*m2.m12 + m1.m12*m2.m22;
m.m13 = m1.m10*m2.m03 + m1.m11*m2.m13 + m1.m12*m2.m23 + m1.m13;
m.m20 = m1.m20*m2.m00 + m1.m21*m2.m10 + m1.m22*m2.m20;
m.m21 = m1.m20*m2.m01 + m1.m21*m2.m11 + m1.m22*m2.m21;
m.m22 = m1.m20*m2.m02 + m1.m21*m2.m12 + m1.m22*m2.m22;
m.m23 = m1.m20*m2.m03 + m1.m21*m2.m13 + m1.m22*m2.m23 + m1.m23;
return m;
}
public void shiftSelf(float dx, float dy, float dz)
{
m03 += m00 * dx + m01 * dy + m02 * dz;
m13 += m10 * dx + m11 * dy + m12 * dz;
m23 += m20 * dx + m21 * dx + m22 * dx;
}
/*
public string toString()
{
// todo
}
*/
public warp_Matrix getClone()
{
warp_Matrix m=new warp_Matrix();
public void rotateSelf(float dx, float dy, float dz)
{
preTransform(rotateMatrix(dx, dy, dz));
}
public void rotateSelf(warp_Matrix m)
{
preTransform(m);
}
m.m00=m00; m.m01=m01; m.m02=m02; m.m03=m03;
m.m10=m10; m.m11=m11; m.m12=m12; m.m13=m13;
m.m20=m20; m.m21=m21; m.m22=m22; m.m23=m23;
m.m30=m30; m.m31=m31; m.m32=m32; m.m33=m33;
return m;
}
public void rotateSelf(warp_Quaternion quat)
{
preTransform(rotateMatrix(quat));
}
public warp_Matrix inverse()
{
warp_Matrix m=new warp_Matrix();
public void transform(warp_Matrix n)
{
warp_Matrix m = getClone();
float q1 = m12; float q6 = m10*m01; float q7 = m10*m21; float q8 = m02;
float q13 = m20*m01; float q14 = m20*m11; float q21 = m02*m21; float q22 = m03*m21;
float q25 = m01*m12; float q26 = m01*m13; float q27 = m02*m11; float q28 = m03*m11;
float q29 = m10*m22; float q30 = m10*m23; float q31 = m20*m12; float q32 = m20*m13;
float q35 = m00*m22; float q36 = m00*m23; float q37 = m20*m02; float q38 = m20*m03;
float q41 = m00*m12; float q42 = m00*m13; float q43 = m10*m02; float q44 = m10*m03;
float q45 = m00*m11; float q48 = m00*m21;
float q49 = q45*m22-q48*q1-q6*m22+q7*q8;
float q50 = q13*q1-q14*q8;
float q51 = 1/(q49+q50);
m00 = n.m00 * m.m00 + n.m01 * m.m10 + n.m02 * m.m20;
m01 = n.m00 * m.m01 + n.m01 * m.m11 + n.m02 * m.m21;
m02 = n.m00 * m.m02 + n.m01 * m.m12 + n.m02 * m.m22;
m03 = n.m00 * m.m03 + n.m01 * m.m13 + n.m02 * m.m23 + n.m03;
m10 = n.m10 * m.m00 + n.m11 * m.m10 + n.m12 * m.m20;
m11 = n.m10 * m.m01 + n.m11 * m.m11 + n.m12 * m.m21;
m12 = n.m10 * m.m02 + n.m11 * m.m12 + n.m12 * m.m22;
m13 = n.m10 * m.m03 + n.m11 * m.m13 + n.m12 * m.m23 + n.m13;
m20 = n.m20 * m.m00 + n.m21 * m.m10 + n.m22 * m.m20;
m21 = n.m20 * m.m01 + n.m21 * m.m11 + n.m22 * m.m21;
m22 = n.m20 * m.m02 + n.m21 * m.m12 + n.m22 * m.m22;
m23 = n.m20 * m.m03 + n.m21 * m.m13 + n.m22 * m.m23 + n.m23;
}
m.m00 = (m11*m22*m33-m11*m23*m32-m21*m12*m33+m21*m13*m32+m31*m12*m23-m31*m13*m22)*q51;
m.m01 = -(m01*m22*m33-m01*m23*m32-q21*m33+q22*m32)*q51;
m.m02 = (q25*m33-q26*m32-q27*m33+q28*m32)*q51;
m.m03 = -(q25*m23-q26*m22-q27*m23+q28*m22+q21*m13-q22*m12)*q51;
m.m10 = -(q29*m33-q30*m32-q31*m33+q32*m32)*q51;
m.m11 = (q35*m33-q36*m32-q37*m33+q38*m32)*q51;
m.m12 = -(q41*m33-q42*m32-q43*m33+q44*m32)*q51;
m.m13 = (q41*m23-q42*m22-q43*m23+q44*m22+q37*m13-q38*m12)*q51;
m.m20 = (q7*m33-q30*m31-q14*m33+q32*m31)*q51;
m.m21 = -(q48*m33-q36*m31-q13*m33+q38*m31)*q51;
m.m22 = (q45*m33-q42*m31-q6*m33+q44*m31)*q51;
m.m23 = -(q45*m23-q42*m21-q6*m23+q44*m21+q13*m13-q38*m11)*q51;
public static warp_Matrix transform(warp_Matrix m, warp_Matrix n)
{
return new warp_Matrix
{
m00 = n.m00 * m.m00 + n.m01 * m.m10 + n.m02 * m.m20,
m01 = n.m00 * m.m01 + n.m01 * m.m11 + n.m02 * m.m21,
m02 = n.m00 * m.m02 + n.m01 * m.m12 + n.m02 * m.m22,
m03 = n.m00 * m.m03 + n.m01 * m.m13 + n.m02 * m.m23 + n.m03,
m10 = n.m10 * m.m00 + n.m11 * m.m10 + n.m12 * m.m20,
m11 = n.m10 * m.m01 + n.m11 * m.m11 + n.m12 * m.m21,
m12 = n.m10 * m.m02 + n.m11 * m.m12 + n.m12 * m.m22,
m13 = n.m10 * m.m03 + n.m11 * m.m13 + n.m12 * m.m23 + n.m13,
m20 = n.m20 * m.m00 + n.m21 * m.m10 + n.m22 * m.m20,
m21 = n.m20 * m.m01 + n.m21 * m.m11 + n.m22 * m.m21,
m22 = n.m20 * m.m02 + n.m21 * m.m12 + n.m22 * m.m22,
m23 = n.m20 * m.m03 + n.m21 * m.m13 + n.m22 * m.m23 + n.m23,
};
}
return m;
}
public void SetFromtransform(warp_Matrix m, warp_Matrix n)
{
m00 = n.m00 * m.m00 + n.m01 * m.m10 + n.m02 * m.m20;
m01 = n.m00 * m.m01 + n.m01 * m.m11 + n.m02 * m.m21;
m02 = n.m00 * m.m02 + n.m01 * m.m12 + n.m02 * m.m22;
m03 = n.m00 * m.m03 + n.m01 * m.m13 + n.m02 * m.m23 + n.m03;
m10 = n.m10 * m.m00 + n.m11 * m.m10 + n.m12 * m.m20;
m11 = n.m10 * m.m01 + n.m11 * m.m11 + n.m12 * m.m21;
m12 = n.m10 * m.m02 + n.m11 * m.m12 + n.m12 * m.m22;
m13 = n.m10 * m.m03 + n.m11 * m.m13 + n.m12 * m.m23 + n.m13;
m20 = n.m20 * m.m00 + n.m21 * m.m10 + n.m22 * m.m20;
m21 = n.m20 * m.m01 + n.m21 * m.m11 + n.m22 * m.m21;
m22 = n.m20 * m.m02 + n.m21 * m.m12 + n.m22 * m.m22;
m23 = n.m20 * m.m03 + n.m21 * m.m13 + n.m22 * m.m23 + n.m23;
}
public void reset()
{
m00=1; m01=0; m02=0; m03=0;
m10=0; m11=1; m12=0; m13=0;
m20=0; m21=0; m22=1; m23=0;
m30=0; m31=0; m32=0; m33=1;
}
}
public void preTransform(warp_Matrix n)
{
warp_Matrix m = this.getClone();
m00 = m.m00 * n.m00 + m.m01 * n.m10 + m.m02 * n.m20;
m01 = m.m00 * n.m01 + m.m01 * n.m11 + m.m02 * n.m21;
m02 = m.m00 * n.m02 + m.m01 * n.m12 + m.m02 * n.m22;
m03 = m.m00 * n.m03 + m.m01 * n.m13 + m.m02 * n.m23 + m.m03;
m10 = m.m10 * n.m00 + m.m11 * n.m10 + m.m12 * n.m20;
m11 = m.m10 * n.m01 + m.m11 * n.m11 + m.m12 * n.m21;
m12 = m.m10 * n.m02 + m.m11 * n.m12 + m.m12 * n.m22;
m13 = m.m10 * n.m03 + m.m11 * n.m13 + m.m12 * n.m23 + m.m13;
m20 = m.m20 * n.m00 + m.m21 * n.m10 + m.m22 * n.m20;
m21 = m.m20 * n.m01 + m.m21 * n.m11 + m.m22 * n.m21;
m22 = m.m20 * n.m02 + m.m21 * n.m12 + m.m22 * n.m22;
m23 = m.m20 * n.m03 + m.m21 * n.m13 + m.m22 * n.m23 + m.m23;
}
public static warp_Matrix multiply(warp_Matrix m1, warp_Matrix m2)
{
return new warp_Matrix
{
m00 = m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20,
m01 = m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21,
m02 = m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22,
m03 = m1.m00 * m2.m03 + m1.m01 * m2.m13 + m1.m02 * m2.m23 + m1.m03,
m10 = m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20,
m11 = m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21,
m12 = m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22,
m13 = m1.m10 * m2.m03 + m1.m11 * m2.m13 + m1.m12 * m2.m23 + m1.m13,
m20 = m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20,
m21 = m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21,
m22 = m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22,
m23 = m1.m20 * m2.m03 + m1.m21 * m2.m13 + m1.m22 * m2.m23 + m1.m23
};
}
/*
public string toString()
{
// todo
}
*/
public warp_Matrix getClone()
{
return new warp_Matrix()
{
m00 = m00,
m01 = m01,
m02 = m02,
m03 = m03,
m10 = m10,
m11 = m11,
m12 = m12,
m13 = m13,
m20 = m20,
m21 = m21,
m22 = m22,
m23 = m23,
m30 = m30,
m31 = m31,
m32 = m32,
m33 = m33
};
}
public warp_Matrix inverse()
{
warp_Matrix m = new warp_Matrix();
float q1 = m12; float q6 = m10 * m01; float q7 = m10 * m21; float q8 = m02;
float q13 = m20 * m01; float q14 = m20 * m11; float q21 = m02 * m21; float q22 = m03 * m21;
float q25 = m01 * m12; float q26 = m01 * m13; float q27 = m02 * m11; float q28 = m03 * m11;
float q29 = m10 * m22; float q30 = m10 * m23; float q31 = m20 * m12; float q32 = m20 * m13;
float q35 = m00 * m22; float q36 = m00 * m23; float q37 = m20 * m02; float q38 = m20 * m03;
float q41 = m00 * m12; float q42 = m00 * m13; float q43 = m10 * m02; float q44 = m10 * m03;
float q45 = m00 * m11; float q48 = m00 * m21;
float q49 = q45 * m22 - q48 * q1 - q6 * m22 + q7 * q8;
float q50 = q13 * q1 - q14 * q8;
float q51 = 1 / (q49 + q50);
m.m00 = (m11 * m22 * m33 - m11 * m23 * m32 - m21 * m12 * m33 + m21 * m13 * m32 + m31 * m12 * m23 - m31 * m13 * m22) * q51;
m.m01 = -(m01 * m22 * m33 - m01 * m23 * m32 - q21 * m33 + q22 * m32) * q51;
m.m02 = (q25 * m33 - q26 * m32 - q27 * m33 + q28 * m32) * q51;
m.m03 = -(q25 * m23 - q26 * m22 - q27 * m23 + q28 * m22 + q21 * m13 - q22 * m12) * q51;
m.m10 = -(q29 * m33 - q30 * m32 - q31 * m33 + q32 * m32) * q51;
m.m11 = (q35 * m33 - q36 * m32 - q37 * m33 + q38 * m32) * q51;
m.m12 = -(q41 * m33 - q42 * m32 - q43 * m33 + q44 * m32) * q51;
m.m13 = (q41 * m23 - q42 * m22 - q43 * m23 + q44 * m22 + q37 * m13 - q38 * m12) * q51;
m.m20 = (q7 * m33 - q30 * m31 - q14 * m33 + q32 * m31) * q51;
m.m21 = -(q48 * m33 - q36 * m31 - q13 * m33 + q38 * m31) * q51;
m.m22 = (q45 * m33 - q42 * m31 - q6 * m33 + q44 * m31) * q51;
m.m23 = -(q45 * m23 - q42 * m21 - q6 * m23 + q44 * m21 + q13 * m13 - q38 * m11) * q51;
return m;
}
public void reset()
{
m00 = 1f; m01 = 0f; m02 = 0f; m03 = 0f;
m10 = 0f; m11 = 1f; m12 = 0f; m13 = 0f;
m20 = 0f; m21 = 0f; m22 = 1f; m23 = 0f;
m30 = 0f; m31 = 0f; m32 = 0f; m33 = 1f;
}
}
}
+90 -220
View File
@@ -1,60 +1,49 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_Object.
/// </summary>
public class warp_Object: warp_CoreObject
public class warp_Object : warp_CoreObject
{
public Object userData = null; // Can be freely used
public String user = null; // Can be freely used
public List<warp_Vertex> vertexData = new List<warp_Vertex>(1024);
public List<warp_Triangle> triangleData = new List<warp_Triangle>(1024);
public List<warp_Vertex> vertexData;
public List<warp_Triangle> triangleData;
public int id; // This object's index
public String name = ""; // This object's name
public string name = ""; // This object's name
public bool visible = true; // Visibility tag
public warp_Scene parent = null;
private bool dirty = true; // Flag for dirty handling
public warp_Vertex[] fastvertex;
public warp_Triangle[] fasttriangle;
public int vertices = 0;
public int triangles = 0;
public warp_Vector fastMin;
public warp_Vector fastMax;
public warp_Material material = null;
public int projectedmaxMips = 0;
public int fastcolor;
public int fastreflectivity;
public int[] fastenvmappixels;
public warp_Texture fasttexture;
public int[] fasttpixels;
public int fasttw;
public int fastth;
public int fasttbitw;
public int fasttbith;
public int fastmode;
public warp_Object()
{
vertexData = new List<warp_Vertex>(256);
triangleData = new(256);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Vertex vertex(int id)
{
return (warp_Vertex)vertexData[id];
return vertexData[id];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Triangle triangle(int id)
{
return (warp_Triangle)triangleData[id];
return triangleData[id];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void addVertex(warp_Vertex newVertex)
{
newVertex.parent = this;
@@ -62,6 +51,7 @@ namespace Warp3D
dirty = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void addTriangle(warp_Triangle newTriangle)
{
newTriangle.parent = this;
@@ -69,31 +59,42 @@ namespace Warp3D
dirty = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void addTriangle(int v1, int v2, int v3)
{
addTriangle(vertex(v1), vertex(v2), vertex(v3));
dirty = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void removeVertex(warp_Vertex v)
{
vertexData.Remove(v);
dirty = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void removeTriangle(warp_Triangle t)
{
triangleData.Remove(t);
dirty = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void removeVertexAt(int pos)
{
vertexData.RemoveAt(pos);
dirty = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void removeTriangleAt(int pos)
{
triangleData.RemoveAt(pos);
dirty = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setMaterial(warp_Material m)
{
material = m;
@@ -101,27 +102,46 @@ namespace Warp3D
public void rebuild()
{
if(!dirty)
if (!dirty)
return;
dirty = false;
vertices = vertexData.Count;
fastvertex = vertexData.ToArray();
float minX = 0;
float maxX = minX;
float minY = 0;
float maxY = minY;
float minZ = 0;
float maxZ = minZ;
float t;
// Generate faster structure for triangles
triangles = triangleData.Count;
fasttriangle = triangleData.ToArray();
for(int i = vertices - 1; i >= 0; i--)
for (int i = 0; i < vertexData.Count; i++)
{
fastvertex[i].id = i;
fastvertex[i].resetNeighbors();
vertexData[i].id = i;
vertexData[i].resetNeighbors();
t = vertexData[i].pos.x;
if (t < minX)
minX = t;
if (t > maxX)
maxX = t;
t = vertexData[i].pos.y;
if (t < minY)
minY = t;
if (t > maxY)
maxY = t;
t = vertexData[i].pos.z;
if (t < minZ)
minZ = t;
if (t > maxZ)
maxZ = t;
}
fastMin = new warp_Vector(minX, minY, minZ);
fastMax = new warp_Vector(maxX, maxY, maxZ);
warp_Triangle tri;
for(int i = triangles - 1; i >= 0; i--)
for (int i = 0; i < triangleData.Count; i++)
{
tri = fasttriangle[i];
warp_Triangle tri = triangleData[i];
tri.id = i;
tri.p1.registerNeighbor(tri);
tri.p2.registerNeighbor(tri);
@@ -129,92 +149,54 @@ namespace Warp3D
}
regenerate();
dirty = false;
}
/*
public void rebuild()
{
if (!dirty) return;
dirty=false;
Enumeration enum;
// Generate faster structure for vertices
vertices=vertexData.size();
vertex=new warp_Vertex[vertices];
enum=vertexData.elements();
for (int i=vertices-1;i>=0;i--) vertex[i]=(warp_Vertex)enum.nextElement();
// Generate faster structure for triangles
triangles=triangleData.size();
triangle=new warp_Triangle[triangles];
enum=triangleData.elements();
for (int i=triangles-1;i>=0;i--)
{
triangle[i]=(warp_Triangle)enum.nextElement();
triangle[i].id=i;
}
for (int i=vertices-1;i>=0;i--)
{
vertex[i].id=i;
vertex[i].resetNeighbors();
}
warp_Triangle tri;
for (int i=triangles-1;i>=0;i--)
{
tri=triangle[i];
tri.p1.registerNeighbor(tri);
tri.p2.registerNeighbor(tri);
tri.p3.registerNeighbor(tri);
}
regenerate();
}
*/
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void addVertex(float x, float y, float z)
{
addVertex(new warp_Vertex(x, y, z));
addVertex(new(x, y, z));
dirty = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void addVertex(float x, float y, float z, float u, float v)
{
warp_Vertex vert = new warp_Vertex(x, y, z);
vert.setUV(u, v);
addVertex(vert);
addVertex(new warp_Vertex(x, y, z, u, v));
dirty = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void addTriangle(warp_Vertex a, warp_Vertex b, warp_Vertex c)
{
addTriangle(new warp_Triangle(a, b, c));
dirty = true;
}
public void regenerate()
// Regenerates the vertex normals
{
for(int i = 0; i < triangles; i++)
fasttriangle[i].regenerateNormal();
for(int i = 0; i < vertices; i++)
fastvertex[i].regenerateNormal();
for (int i = 0; i < triangleData.Count; i++)
triangleData[i].regenerateNormal();
for (int i = 0; i < vertexData.Count; i++)
vertexData[i].regenerateNormal();
}
/*
public void remapUV(int w, int h, float sx, float sy)
{
rebuild();
for(int j = 0, p = 0; j < h; j++)
for (int j = 0, p = 0; j < h; j++)
{
float v = ((float)j / (float)(h - 1)) * sy;
for(int i = 0; i < w; i++)
for (int i = 0; i < w; i++)
{
float u = ((float)i / (float)(w - 1)) * sx;
fastvertex[p++].setUV(u, v);
vertexData[p++].setUV(u, v);
}
}
}
*/
/*
public void tilt(float fact)
{
@@ -226,46 +208,6 @@ namespace Warp3D
}
*/
public warp_Vector minimum()
{
if(vertices == 0)
return new warp_Vector(0f, 0f, 0f);
float minX = fastvertex[0].pos.x;
float minY = fastvertex[0].pos.y;
float minZ = fastvertex[0].pos.z;
for(int i = 1; i < vertices; i++)
{
if(fastvertex[i].pos.x < minX)
minX = fastvertex[i].pos.x;
if(fastvertex[i].pos.y < minY)
minY = fastvertex[i].pos.y;
if(fastvertex[i].pos.z < minZ)
minZ = fastvertex[i].pos.z;
}
return new warp_Vector(minX, minY, minZ);
}
public warp_Vector maximum()
{
if(vertices == 0)
return new warp_Vector(0f, 0f, 0f);
float maxX = fastvertex[0].pos.x;
float maxY = fastvertex[0].pos.y;
float maxZ = fastvertex[0].pos.z;
for(int i = 1; i < vertices; i++)
{
if(fastvertex[i].pos.x > maxX)
maxX = fastvertex[i].pos.x;
if(fastvertex[i].pos.y > maxY)
maxY = fastvertex[i].pos.y;
if(fastvertex[i].pos.z > maxZ)
maxZ = fastvertex[i].pos.z;
}
return new warp_Vector(maxX, maxY, maxZ);
}
public void detach()
// Centers the object in its coordinate system
// The offset from origin to object center will be transfered to the matrix,
@@ -274,11 +216,11 @@ namespace Warp3D
{
warp_Vector center = getCenter();
for(int i = 0; i < vertices; i++)
for (int i = 0; i < vertexData.Count; i++)
{
fastvertex[i].pos.x -= center.x;
fastvertex[i].pos.y -= center.y;
fastvertex[i].pos.z -= center.z;
vertexData[i].pos.x -= center.x;
vertexData[i].pos.y -= center.y;
vertexData[i].pos.z -= center.z;
}
shift(center);
@@ -287,19 +229,13 @@ namespace Warp3D
public warp_Vector getCenter()
// Returns the center of this object
{
warp_Vector max = maximum();
warp_Vector min = minimum();
return new warp_Vector((max.x + min.x) / 2, (max.y + min.y) / 2, (max.z + min.z) / 2);
return new warp_Vector((fastMax.x + fastMin.x) / 2, (fastMax.y + fastMin.y) / 2, (fastMax.z + fastMin.z) / 2);
}
public warp_Vector getDimension()
// Returns the x,y,z - Dimension of this object
{
warp_Vector max = maximum();
warp_Vector min = minimum();
return new warp_Vector(max.x - min.x, max.y - min.y, max.z - min.z);
return new warp_Vector(fastMax.x - fastMin.x, fastMax.y - fastMin.y, fastMax.z - fastMin.z);
}
public void matrixMeltdown()
@@ -307,14 +243,13 @@ namespace Warp3D
// and resets the matrix to untransformed.
{
rebuild();
for(int i = vertices - 1; i >= 0; i--)
fastvertex[i].pos = fastvertex[i].pos.transform(matrix);
for (int i = 0; i < vertexData.Count; i++)
vertexData[i].pos = vertexData[i].pos.transform(matrix);
regenerate();
matrix.reset();
normalmatrix.reset();
}
public void destroy()
{
name = null;
@@ -323,22 +258,17 @@ namespace Warp3D
normalmatrix = null;
parent = null;
fastvertex = null;
fasttriangle = null;
vertexData.Clear();
triangleData.Clear();
vertexData = null;
triangleData = null;
}
public warp_Object getClone()
{
warp_Object obj = new warp_Object();
warp_Object obj = new();
rebuild();
for(int i = 0; i < vertices; i++)
obj.addVertex(fastvertex[i].getClone());
for(int i = 0; i < triangles; i++)
obj.addTriangle(fasttriangle[i].getClone());
for (int i = 0; i < vertexData.Count; i++)
obj.addVertex(vertexData[i].getClone());
for (int i = 0; i < triangleData.Count; i++)
obj.addTriangle(triangleData[i].getClone());
obj.name = name + " [cloned]";
obj.material = material;
obj.matrix = matrix.getClone();
@@ -347,66 +277,6 @@ namespace Warp3D
return obj;
}
private const int F = 0; // FLAT
private const int W = 1; // WIREFRAME
private const int P = 2; // PHONG
private const int E = 4; // ENVMAP
private const int T = 8; // TEXTURED
public void cacheMaterialData()
{
fastcolor = material.color;
fastreflectivity = material.reflectivity;
fasttexture = material.texture;
if(material.envmap != null)
fastenvmappixels = material.envmap.pixel;
else
fastenvmappixels = null;
if(fasttexture != null)
{
if(projectedmaxMips < 2)
{
fastcolor = warp_Color.multiply(fastcolor, fasttexture.averageColor);
fasttexture = null;
}
else
{
int mip = projectedmaxMips - 2;
// int mip = fasttexture.maxmips;
if(mip < fasttexture.maxmips)
{
if(!fasttexture.hasmips)
fasttexture.GenMips();
fasttpixels = fasttexture.mips[mip];
fasttbitw = fasttexture.mipsBitWidth[mip];
fasttbith = fasttexture.mipsBitHeight[mip];
fasttw = fasttexture.mipstw[mip] - 1;
fastth = fasttexture.mipsth[mip] - 1;
}
else
{
fasttpixels = fasttexture.pixel;
fasttw = fasttexture.width - 1;
fastth = fasttexture.height - 1;
fasttbitw = fasttexture.bitWidth;
fasttbith = fasttexture.bitHeight;
}
}
}
int m = 0;
if(!material.flat)
m |= P;
if(fastenvmappixels != null)
m |= E;
if(fasttexture != null)
m |= T;
if(material.wireframe)
m |= W;
fastmode = m;
}
/*
public void removeDuplicateVertices()
+269 -266
View File
@@ -2,308 +2,311 @@ using System;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_ObjectFactory.
/// </summary>
public class warp_ObjectFactory
{
public static double pi = 3.1415926535;
public static double deg2rad = pi / 180;
/// <summary>
/// Summary description for warp_ObjectFactory.
/// </summary>
public class warp_ObjectFactory
{
public static warp_Object SIMPLEPLANE(float size, bool doubleSided)
{
warp_Object newObject = new();
public static warp_Object SIMPLEPLANE(float size, bool doubleSided)
{
warp_Object newObject = new warp_Object();
newObject.addVertex(new(-size, 0f, size, 0, 0));
newObject.addVertex(new(size, 0f, size, 1f, 0));
newObject.addVertex(new(size, 0f, -size, 1f, 1f));
newObject.addVertex(new(-size, 0f, -size, 0, 1f));
newObject.addVertex( new warp_Vertex( -size, 0f, size, 0, 0 ) );
newObject.addVertex( new warp_Vertex( size, 0f, size, 1f, 0 ) );
newObject.addVertex( new warp_Vertex( size, 0f, -size, 1f, 1f ) );
newObject.addVertex( new warp_Vertex( -size, 0f, -size, 0, 1f ) );
newObject.addTriangle(0, 3, 2);
newObject.addTriangle(0, 2, 1);
newObject.addTriangle(0, 3, 2);
newObject.addTriangle(0, 2, 1);
if (doubleSided)
{
newObject.addTriangle(0, 2, 3);
newObject.addTriangle(0, 1, 2);
}
if(doubleSided)
{
newObject.addTriangle(0, 2, 3);
newObject.addTriangle(0, 1, 2);
}
return newObject;
}
return newObject;
}
public static warp_Object CUBE(float size)
{
return BOX(size, size, size);
}
public static warp_Object CUBE(float size)
{
return BOX(size, size, size);
}
public static warp_Object BOX(warp_Vector size)
{
return BOX(size.x, size.y, size.z);
}
public static warp_Object BOX(warp_Vector size)
{
return BOX(size.x, size.y, size.z);
}
public static warp_Object BOX(float xsize, float ysize, float zsize)
{
float x = MathF.Abs(xsize) * 0.5f;
float y = MathF.Abs(ysize) * 0.5f;
float z = MathF.Abs(zsize) * 0.5f;
public static warp_Object BOX(float xsize, float ysize, float zsize)
{
float x = (float) Math.Abs(xsize / 2);
float y = (float) Math.Abs(ysize / 2);
float z = (float) Math.Abs(zsize / 2);
float xx, yy, zz;
float xx, yy, zz;
warp_Object n = new();
int[] xflag = new int[6];
int[] yflag = new int[6];
int[] zflag = new int[6];
warp_Object n = new warp_Object();
int[] xflag = new int[6];
int[] yflag = new int[6];
int[] zflag = new int[6];
xflag[0] = 10;
yflag[0] = 3;
zflag[0] = 0;
xflag[1] = 10;
yflag[1] = 15;
zflag[1] = 3;
xflag[2] = 15;
yflag[2] = 3;
zflag[2] = 10;
xflag[3] = 10;
yflag[3] = 0;
zflag[3] = 12;
xflag[4] = 0;
yflag[4] = 3;
zflag[4] = 5;
xflag[5] = 5;
yflag[5] = 3;
zflag[5] = 15;
xflag[0] = 10;
yflag[0] = 3;
zflag[0] = 0;
xflag[1] = 10;
yflag[1] = 15;
zflag[1] = 3;
xflag[2] = 15;
yflag[2] = 3;
zflag[2] = 10;
xflag[3] = 10;
yflag[3] = 0;
zflag[3] = 12;
xflag[4] = 0;
yflag[4] = 3;
zflag[4] = 5;
xflag[5] = 5;
yflag[5] = 3;
zflag[5] = 15;
for (int side = 0; side < 6; side++)
{
for (int i = 0; i < 4; i++)
{
xx = ((xflag[side] & (1 << i)) > 0) ? x : -x;
yy = ((yflag[side] & (1 << i)) > 0) ? y : -y;
zz = ((zflag[side] & (1 << i)) > 0) ? z : -z;
n.addVertex(xx, yy, zz, i & 1, (i & 2) >> 1);
}
int t = side << 2;
n.addTriangle(t, t + 2, t + 3);
n.addTriangle(t, t + 3, t + 1);
}
for (int side = 0; side < 6; side++)
{
for (int i = 0; i < 4; i++)
{
xx = ( (xflag[side] & (1 << i)) > 0) ? x : -x;
yy = ( (yflag[side] & (1 << i)) > 0) ? y : -y;
zz = ( (zflag[side] & (1 << i)) > 0) ? z : -z;
n.addVertex(xx, yy, zz, i & 1, (i & 2) >> 1);
}
int t = side << 2;
n.addTriangle(t, t + 2, t + 3);
n.addTriangle(t, t + 3, t + 1);
}
return n;
}
return n;
}
public static warp_Object CONE(float height, float radius, int segments)
{
warp_Vector[] path = new warp_Vector[4];
float h = height * 0.5f;
path[0] = new warp_Vector(0, h, 0);
path[1] = new warp_Vector(radius, -h, 0);
path[2] = new warp_Vector(radius, -h, 0);
path[3] = new warp_Vector(0, -h, 0);
public static warp_Object CONE(float height, float radius, int segments)
{
warp_Vector[] path = new warp_Vector[4];
float h = height / 2;
path[0] = new warp_Vector(0, h, 0);
path[1] = new warp_Vector(radius, -h, 0);
path[2] = new warp_Vector(radius, -h, 0);
path[3] = new warp_Vector(0, -h, 0);
return ROTATIONOBJECT(path, segments);
}
return ROTATIONOBJECT(path, segments);
}
public static warp_Object CYLINDER(float height, float radius, int segments)
{
warp_Vector[] path = new warp_Vector[6];
float h = height * 0.5f;
path[0] = new warp_Vector(0, h, 0);
path[1] = new warp_Vector(radius, h, 0);
path[2] = new warp_Vector(radius, h, 0);
path[3] = new warp_Vector(radius, -h, 0);
path[4] = new warp_Vector(radius, -h, 0);
path[5] = new warp_Vector(0, -h, 0);
public static warp_Object CYLINDER(float height, float radius,int segments)
{
warp_Vector[] path = new warp_Vector[6];
float h = height / 2;
path[0] = new warp_Vector(0, h, 0);
path[1] = new warp_Vector(radius, h, 0);
path[2] = new warp_Vector(radius, h, 0);
path[3] = new warp_Vector(radius, -h, 0);
path[4] = new warp_Vector(radius, -h, 0);
path[5] = new warp_Vector(0, -h, 0);
return ROTATIONOBJECT(path, segments);
}
return ROTATIONOBJECT(path, segments);
}
public static warp_Object SPHERE(float radius, int segments)
{
warp_Vector[] path = new warp_Vector[segments];
public static warp_Object SPHERE(float radius, int segments)
{
warp_Vector[] path = new warp_Vector[segments];
float x, y, angle;
float x, y, angle;
path[0] = new warp_Vector(0, radius, 0);
path[segments - 1] = new warp_Vector(0, -radius, 0);
path[0] = new warp_Vector(0, radius, 0);
path[segments - 1] = new warp_Vector(0, -radius, 0);
for (int i = 1; i < segments - 1; i++)
{
angle = (((float)i / (float)(segments - 2)) - 0.5f) * -3.14159265f;
x = MathF.Cos(angle) * radius;
y = MathF.Sin(angle) * radius;
path[i] = new warp_Vector(x, y, 0);
}
for (int i = 1; i < segments - 1; i++)
{
angle = - ( ( (float) i / (float) (segments - 2)) - 0.5f) *
3.14159265f;
x = (float) Math.Cos(angle) * radius;
y = (float) Math.Sin(angle) * radius;
path[i] = new warp_Vector(x, y, 0);
}
return ROTATIONOBJECT(path, segments);
}
return ROTATIONOBJECT(path, segments);
}
public static warp_Object ROTATIONOBJECT(warp_Vector[] path, int sides)
{
int steps = sides + 1;
warp_Object newObject = new();
double alpha = 2 * Math.PI / ((double)steps - 1);
float qx, qz;
int nodes = path.GetLength(0);
warp_Vertex vertex;
float u, v; // Texture coordinates
public static warp_Object ROTATIONOBJECT(warp_Vector[] path, int sides)
{
int steps = sides + 1;
warp_Object newObject = new warp_Object();
double alpha = 2 * pi / ( (double) steps - 1);
float qx, qz;
int nodes = path.GetLength(0);
warp_Vertex vertex = null;
float u, v; // Texture coordinates
for (int j = 0; j < steps; j++)
{
u = (float)(steps - j - 1) / (float)(steps - 1);
for (int i = 0; i < nodes; i++)
{
v = (float)i / (float)(nodes - 1);
qx = (float)(path[i].x * Math.Cos(j * alpha) +
path[i].z * Math.Sin(j * alpha));
qz = (float)(path[i].z * Math.Cos(j * alpha) -
path[i].x * Math.Sin(j * alpha));
vertex = new warp_Vertex(qx, path[i].y, qz)
{
u = u,
v = v
};
newObject.addVertex(vertex);
}
}
for (int j = 0; j < steps; j++)
{
u = (float) (steps - j - 1) / (float) (steps - 1);
for (int i = 0; i < nodes; i++)
{
v = (float) i / (float) (nodes - 1);
qx = (float) (path[i].x * Math.Cos(j * alpha) +
path[i].z * Math.Sin(j * alpha));
qz = (float) (path[i].z * Math.Cos(j * alpha) -
path[i].x * Math.Sin(j * alpha));
vertex = new warp_Vertex(qx, path[i].y, qz);
vertex.u = u;
vertex.v = v;
newObject.addVertex(vertex);
}
}
for (int j = 0; j < steps - 1; j++)
{
for (int i = 0; i < nodes - 1; i++)
{
newObject.addTriangle(i + nodes * j, i + nodes * (j + 1),
i + 1 + nodes * j);
newObject.addTriangle(i + nodes * (j + 1),
i + 1 + nodes * (j + 1),
i + 1 + nodes * j);
}
}
for (int j = 0; j < steps - 1; j++)
{
for (int i = 0; i < nodes - 1; i++)
{
newObject.addTriangle(i + nodes * j, i + nodes * (j + 1),
i + 1 + nodes * j);
newObject.addTriangle(i + nodes * (j + 1),
i + 1 + nodes * (j + 1),
i + 1 + nodes * j);
for (int i = 0; i < nodes - 1; i++)
{
newObject.addTriangle(i + nodes * (steps - 1), i,
i + 1 + nodes * (steps - 1));
newObject.addTriangle(i, i + 1, i + 1 + nodes * (steps - 1));
}
return newObject;
}
}
}
for (int i = 0; i < nodes - 1; i++)
{
newObject.addTriangle(i + nodes * (steps - 1), i,
i + 1 + nodes * (steps - 1));
newObject.addTriangle(i, i + 1, i + 1 + nodes * (steps - 1));
}
return newObject;
/*
public static warp_Object TORUSKNOT(float p, float q, float r_tube, float r_out, float r_in, float h, int segments, int steps)
{
float x, y, z, r, t, theta;
}
warp_Vector[] path = new warp_Vector[segments + 1];
for (int i = 0; i < segments + 1; i++)
{
t = 2f * 3.14159265f * i / (float)segments;
r = r_out + r_in * MathF.Cos(p * t);
z = h * MathF.Sin(p * t);
theta = q * t;
x = r * MathF.Cos(theta);
y = r * MathF.Sin(theta);
path[i] = new warp_Vector(x, y, z);
}
return TUBE(path, r_tube, steps, true);
}
*/
/*
public static warp_Object SPIRAL(float h, float r_out, float r_in,
float r_tube, float w, float f,
int segments, int steps)
{
float x, y, z, r, t, theta;
public static warp_Object TORUSKNOT(float p, float q, float r_tube,float r_out, float r_in, float h,int segments, int steps)
{
float x, y, z, r, t, theta;
warp_Vector[] path = new warp_Vector[segments + 1];
for (int i = 0; i < segments + 1; i++)
{
t = (float)i / (float)segments;
r = r_out + r_in * MathF.Sin(2f * 3.14159265f * f * t);
z = (h * 0.5f) + h * t;
theta = 2f * 3.14159265f * w * t;
x = r * MathF.Cos(theta);
y = r * MathF.Sin(theta);
path[i] = new warp_Vector(x, y, z);
}
return TUBE(path, r_tube, steps, false);
}
*/
warp_Vector[] path = new warp_Vector[segments + 1];
for (int i = 0; i < segments + 1; i++)
{
t = 2 * 3.14159265f * i / (float) segments;
r = r_out + r_in * warp_Math.cos(p * t);
z = h * warp_Math.sin(p * t);
theta = q * t;
x = r * warp_Math.cos(theta);
y = r * warp_Math.sin(theta);
path[i] = new warp_Vector(x, y, z);
}
return TUBE(path, r_tube, steps, true);
}
/*
public static warp_Object TUBE(warp_Vector[] path, float r, int steps, bool closed)
{
warp_Vector[] circle = new warp_Vector[steps];
float angle;
for (int i = 0; i < steps; i++)
{
angle = 2f * 3.14159265f * (float)i / (float)steps;
circle[i] = new warp_Vector(r * MathF.Cos(angle), r * MathF.Sin(angle), 0f);
}
public static warp_Object SPIRAL(float h, float r_out, float r_in,
float r_tube, float w, float f,
int segments, int steps)
{
float x, y, z, r, t, theta;
warp_Object newObject = new();
int segments = path.GetLength(0);
warp_Vector forward, up, right;
warp_Matrix frenetmatrix;
warp_Vertex tempvertex;
float relx, rely;
int a, b, c, d;
warp_Vector[] path = new warp_Vector[segments + 1];
for (int i = 0; i < segments + 1; i++)
{
t = (float) i / (float) segments;
r = r_out + r_in * warp_Math.sin(2 * 3.14159265f * f * t);
z = (h / 2) + h * t;
theta = 2 * 3.14159265f * w * t;
x = r * warp_Math.cos(theta);
y = r * warp_Math.sin(theta);
path[i] = new warp_Vector(x, y, z);
}
return TUBE(path, r_tube, steps, false);
}
for (int i = 0; i < segments; i++)
{
// Calculate frenet frame matrix
public static warp_Object TUBE(warp_Vector[] path, float r, int steps, bool closed)
{
warp_Vector[] circle = new warp_Vector[steps];
float angle;
for (int i = 0; i < steps; i++)
{
angle = 2 * 3.14159265f * (float) i / (float) steps;
circle[i] = new warp_Vector(r * warp_Math.cos(angle),
r * warp_Math.sin(angle), 0f);
}
if (i != segments - 1)
{
forward = warp_Vector.sub(ref path[i + 1], ref path[i]);
}
else
{
if (!closed)
{
forward = warp_Vector.sub(ref path[i], ref path[i - 1]);
}
else
{
forward = warp_Vector.sub(ref path[1], ref path[0]);
}
}
warp_Object newObject = new warp_Object();
int segments = path.GetLength(0);
warp_Vector forward, up, right;
warp_Matrix frenetmatrix;
warp_Vertex tempvertex;
float relx, rely;
int a, b, c, d;
forward.normalize();
up = new warp_Vector(0f, 0f, 1f);
right = warp_Vector.getPlaneNormal(ref forward, ref up);
up = warp_Vector.getPlaneNormal(ref forward, ref right);
frenetmatrix = new warp_Matrix(right, up, forward);
frenetmatrix.shift(path[i].x, path[i].y, path[i].z);
for (int i = 0; i < segments; i++)
{
// Calculate frenet frame matrix
// Add nodes
if (i != segments - 1)
{
forward = warp_Vector.sub(path[i + 1], path[i]);
}
else
{
if (!closed)
{
forward = warp_Vector.sub(path[i], path[i - 1]);
}
else
{
forward = warp_Vector.sub(path[1], path[0]);
}
}
relx = (float)i / (float)(segments - 1);
for (int k = 0; k < steps; k++)
{
rely = (float)k / (float)steps;
tempvertex = new warp_Vertex(circle[k].transform(frenetmatrix))
{
u = relx,
v = rely
};
newObject.addVertex(tempvertex);
}
}
forward.normalize();
up = new warp_Vector(0f, 0f, 1f);
right = warp_Vector.getNormal(forward, up);
up = warp_Vector.getNormal(forward, right);
frenetmatrix = new warp_Matrix(right, up, forward);
frenetmatrix.shift(path[i].x, path[i].y, path[i].z);
for (int i = 0; i < segments - 1; i++)
{
for (int k = 0; k < steps - 1; k++)
{
a = i * steps + k;
b = a + 1;
c = a + steps;
d = b + steps;
newObject.addTriangle(a, c, b);
newObject.addTriangle(b, c, d);
}
a = (i + 1) * steps - 1;
b = a + 1 - steps;
c = a + steps;
d = b + steps;
newObject.addTriangle(a, c, b);
newObject.addTriangle(b, c, d);
}
// Add nodes
relx = (float) i / (float) (segments - 1);
for (int k = 0; k < steps; k++)
{
rely = (float) k / (float) steps;
tempvertex = new warp_Vertex(circle[k].transform(frenetmatrix));
tempvertex.u = relx;
tempvertex.v = rely;
newObject.addVertex(tempvertex);
}
}
for (int i = 0; i < segments - 1; i++)
{
for (int k = 0; k < steps - 1; k++)
{
a = i * steps + k;
b = a + 1;
c = a + steps;
d = b + steps;
newObject.addTriangle(a, c, b);
newObject.addTriangle(b, c, d);
}
a = (i + 1) * steps - 1;
b = a + 1 - steps;
c = a + steps;
d = b + steps;
newObject.addTriangle(a, c, b);
newObject.addTriangle(b, c, d);
}
return newObject;
}
}
return newObject;
}
*/
}
}
+51 -69
View File
@@ -1,49 +1,44 @@
using System;
using System.Collections;
using System.Text;
using System.Diagnostics;
using System.Diagnostics;
namespace Warp3D
{
public class warp_Quaternion
public struct warp_Quaternion
{
public float X;
public float Y;
public float Z;
public float W;
public float X = 0;
public float Y = 0;
public float Z = 0;
public float W = 1;
public warp_Quaternion()
{
}
public warp_Quaternion( float x, float y, float z, float w )
public warp_Quaternion(float x, float y, float z, float w)
{
this.X = x;
this.Y = y;
this.Z = z;
this.W = w;
X = x;
Y = y;
Z = z;
W = w;
}
public warp_Quaternion getClone()
static public warp_Quaternion matrix(warp_Matrix xfrm)
{
return new warp_Quaternion( this.X, this.Y, this.Z, this.W );
}
static public warp_Quaternion matrix( warp_Matrix xfrm )
{
warp_Quaternion quat = new warp_Quaternion();
warp_Quaternion quat = new();
// Check the sum of the diagonal
float tr = xfrm[ 0, 0 ] + xfrm[ 1, 1 ] + xfrm[ 2, 2 ];
if ( tr > 0.0f )
float tr = xfrm[0, 0] + xfrm[1, 1] + xfrm[2, 2];
if (tr > 0.0f)
{
// The sum is positive
// 4 muls, 1 div, 6 adds, 1 trig function call
float s = ( float )Math.Sqrt( tr + 1.0f );
float s = MathF.Sqrt(tr + 1.0f);
quat.W = s * 0.5f;
s = 0.5f / s;
quat.X = ( xfrm[ 1, 2 ] - xfrm[ 2, 1 ] ) * s;
quat.Y = ( xfrm[ 2, 0 ] - xfrm[ 0, 2 ] ) * s;
quat.Z = ( xfrm[ 0, 1 ] - xfrm[ 1, 0 ] ) * s;
quat.X = (xfrm[1, 2] - xfrm[2, 1]) * s;
quat.Y = (xfrm[2, 0] - xfrm[0, 2]) * s;
quat.Z = (xfrm[0, 1] - xfrm[1, 0]) * s;
}
else
{
@@ -52,70 +47,57 @@ namespace Warp3D
int[] nIndex = { 1, 2, 0 };
int i, j, k;
i = 0;
if ( xfrm[ 1, 1 ] > xfrm[ i, i ] )
if (xfrm[1, 1] > xfrm[i, i])
i = 1;
if ( xfrm[ 2, 2 ] > xfrm[ i, i ] )
if (xfrm[2, 2] > xfrm[i, i])
i = 2;
j = nIndex[ i ];
k = nIndex[ j ];
j = nIndex[i];
k = nIndex[j];
float s = ( float )Math.Sqrt( ( xfrm[ i, i ] - ( xfrm[ j, j ] + xfrm[ k, k ] ) ) + 1.0f );
quat[ i ] = s * 0.5f;
if ( s != 0.0 )
float s = MathF.Sqrt((xfrm[i, i] - (xfrm[j, j] + xfrm[k, k])) + 1.0f);
quat[i] = s * 0.5f;
if (s != 0.0)
{
s = 0.5f / s;
}
quat[ j ] = ( xfrm[ i, j ] + xfrm[ j, i ] ) * s;
quat[ k ] = ( xfrm[ i, k ] + xfrm[ k, i ] ) * s;
quat[ 3 ] = ( xfrm[ j, k ] - xfrm[ k, j ] ) * s;
quat[j] = (xfrm[i, j] + xfrm[j, i]) * s;
quat[k] = (xfrm[i, k] + xfrm[k, i]) * s;
quat[3] = (xfrm[j, k] - xfrm[k, j]) * s;
}
return quat;
}
public float this[ int index ]
public float this[int index]
{
get
{
Debug.Assert( 0 <= index && index <= 3 );
if ( index <= 1 )
Debug.Assert(0 <= index && index <= 3);
return index switch
{
if ( index == 0 )
{
return this.X;
}
return this.Y;
}
if ( index == 2 )
{
return this.Z;
}
return this.W;
0 => X,
1 => Y,
2 => Z,
_ => W,
};
}
set
{
Debug.Assert( 0 <= index && index <= 3 );
if ( index <= 1 )
Debug.Assert(0 <= index && index <= 3);
switch (index)
{
if ( index == 0 )
{
this.X = value;
}
else
{
this.Y = value;
}
}
else
{
if ( index == 2 )
{
this.Z = value;
}
else
{
this.W = value;
}
case 0:
X = value;
break;
case 1:
Y = value;
break;
case 2:
Z = value;
break;
case 3:
W = value;
break;
}
}
}
+373 -289
View File
@@ -1,4 +1,6 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Warp3D
{
@@ -32,15 +34,14 @@ namespace Warp3D
private const int P = 2; // PHONG
private const int E = 4; // ENVMAP
private const int T = 8; // TEXTURED
private int SHADED = 0;
private const int OPAQUE = 16; // opace
private int
y, z, dx, dy, dz, offset,
xL, xR, xBase, zBase, xMax, dxL, dxR, dzBase,
nxBase, nyBase,
dnx, dny, nx, ny,
dnxBase, dnyBase,
shademode;
dnxBase, dnyBase;
private float
txBase, tyBase,
@@ -56,8 +57,6 @@ namespace Warp3D
// Constructor
public warp_Rasterizer(warp_RenderPipeline pipeline)
{
SHADED = P | E | T;
rebuildReferences(pipeline);
loadLightmap(pipeline.lightmap);
}
@@ -75,6 +74,10 @@ namespace Warp3D
{
screen = null;
zBuffer = null;
tpixels = null;
envmap = null;
diffuse = null;
specular = null;
}
// Lightmap loader
@@ -95,12 +98,9 @@ namespace Warp3D
color = material.color;
reflectivity = material.reflectivity;
texture = material.texture;
if (material.envmap != null)
envmap = material.envmap.pixel;
else
envmap = null;
envmap = material.envmap is null ? null : envmap = material.envmap.pixel;
if (texture != null)
if (texture is not null)
{
if (obj.projectedmaxMips < 2)
{
@@ -109,12 +109,12 @@ namespace Warp3D
}
else
{
int mip = obj.projectedmaxMips - 1;
if (mip > texture.maxmips)
mip = texture.maxmips;
if (texture.mips[mip] != null)
int mip = obj.projectedmaxMips - 2;
if (mip < texture.maxmips)
{
if (!texture.hasmips)
texture.GenMips();
tpixels = texture.mips[mip];
tbitW = texture.mipsBitWidth[mip];
tbitH = texture.mipsBitHeight[mip];
@@ -135,43 +135,22 @@ namespace Warp3D
mode = 0;
if (!material.flat)
mode |= P;
if (envmap != null)
if (envmap is not null)
mode |= E;
if (texture != null)
if (texture is not null)
mode |= T;
if (material.wireframe)
mode |= W;
if (material.opaque)
mode |= OPAQUE;
shademode = mode & SHADED;
materialLoaded = true;
ready = lightmapLoaded;
}
public void loadFastMaterial(warp_Object obj)
{
color = obj.fastcolor;
reflectivity = obj.fastreflectivity;
texture = obj.fasttexture;
envmap = obj.fastenvmappixels;
if (texture != null)
{
tpixels = obj.fasttpixels;
tw = obj.fasttw;
th = obj.fastth;
tbitW = obj.fasttbitw;
tbitH = obj.fasttbith;
}
mode = obj.fastmode;
shademode = mode & SHADED;
materialLoaded = true;
ready = lightmapLoaded;
}
public void render(warp_Triangle tri)
{
if (!ready || tri.parent == null)
if (!ready || tri.parent is null)
return;
if ((mode & W) != 0)
@@ -183,30 +162,34 @@ namespace Warp3D
}
}
warp_Vertex p1;
warp_Vertex p2;
warp_Vertex p1 = tri.p1;
warp_Vertex p2 = tri.p2;
warp_Vertex p3 = tri.p3;
warp_Vertex tempVertex;
if (tri.p1.y > tri.p2.y)
{
p1 = tri.p2;
p2 = tri.p1;
}
else
{
p1 = tri.p1;
p2 = tri.p2;
}
if (p1.y > p2.y)
warp_Vertex p3;
if (p2.y > tri.p3.y)
{
tempVertex = p1;
p1 = p2;
p2 = tempVertex;
}
if (p2.y > p3.y)
{
tempVertex = p2;
p2 = p3;
p3 = tempVertex;
}
if (p1.y > p2.y)
{
tempVertex = p1;
p1 = p2;
p2 = tempVertex;
p3 = p2;
if (p1.y > tri.p3.y)
{
p2 = p1;
p1 = tri.p3;
}
else
p2 = tri.p3;
}
else
p3 = tri.p3;
if (p1.y >= height)
return;
@@ -217,7 +200,7 @@ namespace Warp3D
if (p1.y == p3.y)
return;
if (mode == F)
if ((mode & 0x0f) == F)
{
int lutID = (int)(tri.n2.x * 127 + 127) + ((int)(tri.n2.y * 127 + 127) << 8);
int c = warp_Color.multiply(color, diffuse[lutID]);
@@ -236,6 +219,7 @@ namespace Warp3D
int dy31 = y3 - y1;
float tf = (float)dy / dy31;
int x4 = x1 + (int)((x3 - x1) * tf);
dx = (x4 - x2) >> 8;
@@ -270,29 +254,28 @@ namespace Warp3D
int ny2 = p2.ny;
dny = (ny4 - ny2) / dx;
float tx1 = p1.tx * tw;
float tx3 = p3.tx * tw;
float tx4 = tx1 + ((tx3 - tx1) * tf);
float tx2 = p2.tx * tw;
dtx = (tx4 - tx2) / dx;
float ty1 = p1.ty * th;
float ty3 = p3.ty * th;
float ty4 = ty1 + ((ty3 - ty1) * tf);
float ty2 = p2.ty * th;
dty = (ty4 - ty2) / dx;
float sw1 = p1.invZ;
float sw3 = p3.invZ;
float sw4 = sw1 + ((sw3 - sw1) * tf);
float sw2 = p2.invZ;
dsw = (sw4 - sw2) / dx;
float tx1 = sw1 * p1.u * tw;
float tx3 = sw3 * p3.u * tw;
float tx4 = tx1 + ((tx3 - tx1) * tf);
float tx2 = sw2 * p2.u * tw;
dtx = (tx4 - tx2) / dx;
float ty1 = sw1 * p1.v * th;
float ty3 = sw3 * p3.v * th;
float ty4 = ty1 + ((ty3 - ty1) * tf);
float ty2 = sw2 * p2.v * th;
dty = (ty4 - ty2) / dx;
if (dx < 0)
{
int temp = x2;
x2 = x4;
x4 = temp;
(x4, x2) = (x2, x4);
z2 = z4;
tx2 = tx4;
ty2 = ty4;
@@ -336,11 +319,8 @@ namespace Warp3D
if (y2 > height)
y2 = height;
offset = y1 * width;
for (y = y1; y < y2; y++)
{
renderLine();
}
renderLines(y1 * width, y2 * width);
}
dy = y3 - y2;
@@ -379,194 +359,288 @@ namespace Warp3D
if (y3 > height)
y3 = height;
offset = y2 * width;
for (y = y2; y < y3; y++)
{
renderLine();
}
}
}
private void renderLine()
{
xL = xBase >> 16;
xR = xMax >> 16;
z = zBase;
nx = nxBase;
ny = nyBase;
tx = txBase;
ty = tyBase;
sw = swBase;
if (xL < 0)
{
z -= xL * dz;
nx -= xL * dnx;
ny -= xL * dny;
tx -= xL * dtx;
ty -= xL * dty;
sw -= xL * dsw;
xL = 0;
}
if (xR > width)
xR = width;
if (mode == F)
renderLineF();
else
{
switch(shademode)
{
case P:
renderLineP();
break;
case E:
renderLineE();
break;
case T:
renderLineT();
break;
case P | E:
renderLinePE();
break;
case P | T:
renderLinePT();
break;
case P | E | T:
renderLinePET();
break;
}
renderLines(y2 * width, y3 * width);
}
offset += width;
xBase += dxL;
xMax += dxR;
zBase += dzBase;
nxBase += dnxBase;
nyBase += dnyBase;
txBase += dtxBase;
tyBase += dtyBase;
swBase += dswBase;
}
// Fast scanline rendering
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
private unsafe void renderLineF()
{
int bkgrd;
int c;
int pos;
fixed (int* sp = screen.pixels, zB = zBuffer)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void renderLines(int offsetStart, int offsetEnd)
{
for (int x = xL; x < xR; x++)
ref int rpixels = ref MemoryMarshal.GetArrayDataReference(screen.pixels);
ref int rzbuf = ref MemoryMarshal.GetArrayDataReference(zBuffer);
ref int rdifuse = ref MemoryMarshal.GetArrayDataReference(diffuse);
ref int rspecular = ref MemoryMarshal.GetArrayDataReference(specular);
ref int rtpixels = ref MemoryMarshal.GetArrayDataReference(tpixels);
for (offset = offsetStart; offset < offsetEnd; offset += width)
{
pos = x + offset;
if (z < zBuffer[pos])
xL = xBase >> 16;
xR = xMax >> 16;
z = zBase;
nx = nxBase;
ny = nyBase;
tx = txBase;
ty = tyBase;
sw = swBase;
if (xL < 0)
{
bkgrd = sp[pos];
c = warp_Color.overSolid(bkgrd, currentColor);
sp[pos] = c;
zB[pos] = z;
z -= xL * dz;
nx -= xL * dnx;
ny -= xL * dny;
tx -= xL * dtx;
ty -= xL * dty;
sw -= xL * dsw;
xL = 0;
}
z += dz;
}
}
}
if (xR > width)
xR = width;
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
private unsafe void renderLineP()
{
int bkgrd;
int c;
int s;
int lutID;
int pos;
fixed (int* sp = screen.pixels, zB = zBuffer, df = diffuse, spc = specular)
{
for (int x = xL; x < xR; x++)
{
pos = x + offset;
if (z < zB[pos])
int posEnd = xR + offset;
switch (mode)
{
lutID = ((nx >> 16) & 255) + (((ny >> 16) & 255) << 8);
bkgrd = sp[pos];
c = warp_Color.multiply(color, df[lutID]);
s = spc[lutID];
s = warp_Color.scale(s, reflectivity);
c = warp_Color.overSolid(bkgrd, c);
c = warp_Color.add(c, s);
sp[pos] = c;
zB[pos] = z;
}
z += dz;
nx += dnx;
ny += dny;
case F:
{
//renderLineF;
for (int pos = xL + offset; pos < posEnd; pos++)
{
if (z < Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)))
{
Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)) = z;
int bkgrd = Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos));
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos)) = warp_Color.overSolid(bkgrd, currentColor);
}
z += dz;
}
break;
}
case F | OPAQUE:
{
//renderLineFO
for (int pos = xL + offset; pos < posEnd; pos++)
{
if (z < Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)))
{
Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)) = z;
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos)) = currentColor;
}
z += dz;
}
break;
}
case P:
//renderLineP();
for (int pos = xL + offset; pos < posEnd; pos++)
{
if (z < Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)))
{
Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)) = z;
int lutID = ((nx >> 16) & 255) + (((ny >> 16) & 255) << 8);
int c = warp_Color.multiply(color, Unsafe.As<int, int>(ref Unsafe.Add(ref rdifuse, lutID)));
int s = warp_Color.scale(Unsafe.As<int, int>(ref Unsafe.Add(ref rspecular, lutID)), reflectivity);
int bkgrd = Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos));
c = warp_Color.overSolid(bkgrd, c);
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos)) = warp_Color.add(c, s);
}
z += dz;
nx += dnx;
ny += dny;
}
break;
case P | OPAQUE:
//renderLinePO();
for (int pos = xL + offset; pos < posEnd; pos++)
{
if (z < Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)))
{
Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)) = z;
int lutID = ((nx >> 16) & 255) + (((ny >> 16) & 255) << 8);
int c = warp_Color.multiply(color, Unsafe.As<int, int>(ref Unsafe.Add(ref rdifuse, lutID)));
int s = warp_Color.scale(Unsafe.As<int, int>(ref Unsafe.Add(ref rspecular, lutID)), reflectivity);
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos)) = warp_Color.add(c, s);
}
z += dz;
nx += dnx;
ny += dny;
}
break;
case E:
//renderLineE();
ref int renvmap = ref MemoryMarshal.GetArrayDataReference(envmap);
for (int pos = xL + offset; pos < posEnd; pos++)
{
if (z < Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)))
{
Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)) = z;
int lutID = ((nx >> 16) & 255) + (((ny >> 16) & 255) << 8);
int s = Unsafe.As<int, int>(ref Unsafe.Add(ref rspecular, lutID));
s = warp_Color.add(s, Unsafe.As<int, int>(ref Unsafe.Add(ref renvmap, lutID)));
s = warp_Color.scale(s, reflectivity);
int bkgrd = Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos));
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos)) = warp_Color.overSolid(bkgrd, s);
}
z += dz;
nx += dnx;
ny += dny;
}
break;
case E | OPAQUE:
//renderLineEO();
renvmap = ref MemoryMarshal.GetArrayDataReference(envmap);
for (int pos = xL + offset; pos < posEnd; pos++)
{
if (z < Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)))
{
Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)) = z;
int lutID = ((nx >> 16) & 255) + (((ny >> 16) & 255) << 8);
int s = Unsafe.As<int, int>(ref Unsafe.Add(ref rspecular, lutID));
s = warp_Color.add(s, Unsafe.As<int, int>(ref Unsafe.Add(ref renvmap, lutID)));
s = warp_Color.scale(s, reflectivity);
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos)) = warp_Color.scale(s, reflectivity);
}
z += dz;
nx += dnx;
ny += dny;
}
break;
case T:
//renderLineT();
for (int pos = xL + offset; pos < posEnd; pos++)
{
if (z < Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)))
{
Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)) = z;
int tpindx = (((int)(tx / sw)) & tw) + ((((int)(ty / sw)) & th) << tbitW);
int c = Unsafe.As<int, int>(ref Unsafe.Add(ref rtpixels, tpindx));
c = warp_Color.multiply(color, c);
int bkgrd = Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos));
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos)) = warp_Color.overSolid(bkgrd, c);
}
z += dz;
tx += dtx;
ty += dty;
sw += dsw;
}
break;
case T | OPAQUE:
//renderLineTO();
for (int pos = xL + offset; pos < posEnd; pos++)
{
if (z < Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)))
{
Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)) = z;
int tpindx = (((int)(tx / sw)) & tw) + ((((int)(ty / sw)) & th) << tbitW);
int c = Unsafe.As<int, int>(ref Unsafe.Add(ref rtpixels, tpindx));
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos)) = warp_Color.multiply(color, c);
}
z += dz;
tx += dtx;
ty += dty;
sw += dsw;
}
break;
case P | E:
renderLinePE();
break;
case P | E | OPAQUE:
renderLinePEO();
break;
case P | T:
//renderLinePT();
for (int pos = xL + offset; pos < posEnd; pos++)
{
if (z < Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)))
{
Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)) = z;
int tpindx = (((int)(tx / sw)) & tw) + ((((int)(ty / sw)) & th) << tbitW);
int c = Unsafe.As<int, int>(ref Unsafe.Add(ref rtpixels, tpindx));
c = warp_Color.multiply(color, c);
int lutID = ((nx >> 16) & 255) + (((ny >> 16) & 255) << 8);
c = warp_Color.multiply(c, Unsafe.As<int, int>(ref Unsafe.Add(ref rdifuse, lutID)));
int s = warp_Color.scale(Unsafe.As<int, int>(ref Unsafe.Add(ref rspecular, lutID)), reflectivity);
int bkgrd = Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos));
c = warp_Color.overSolid(bkgrd, c);
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos)) = warp_Color.add(c, s);
}
z += dz;
nx += dnx;
ny += dny;
tx += dtx;
ty += dty;
sw += dsw;
}
break;
case P | T | OPAQUE:
//renderLinePTO();
for (int pos = xL + offset; pos < posEnd; pos++)
{
if (z < Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)))
{
Unsafe.As<int, int>(ref Unsafe.Add(ref rzbuf, pos)) = z;
int tpindx = (((int)(tx / sw)) & tw) + ((((int)(ty / sw)) & th) << tbitW);
int c = Unsafe.As<int, int>(ref Unsafe.Add(ref rtpixels, tpindx));
c = warp_Color.multiply(color, c);
int lutID = ((nx >> 16) & 255) + (((ny >> 16) & 255) << 8);
c = warp_Color.multiply(c, Unsafe.As<int, int>(ref Unsafe.Add(ref rdifuse, lutID)));
int s = warp_Color.scale(Unsafe.As<int, int>(ref Unsafe.Add(ref rspecular, lutID)), reflectivity);
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixels, pos)) = warp_Color.add(c, s);
}
z += dz;
nx += dnx;
ny += dny;
tx += dtx;
ty += dty;
sw += dsw;
}
break;
case P | E | T:
renderLinePET();
break;
case P | E | T | OPAQUE:
renderLinePETO();
break;
default:
return;
};
xBase += dxL;
xMax += dxR;
zBase += dzBase;
nxBase += dnxBase;
nyBase += dnyBase;
txBase += dtxBase;
tyBase += dtyBase;
swBase += dswBase;
}
}
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
private unsafe void renderLineE()
{
int bkgrd;
int s;
int lutID;
int pos;
fixed (int* sp = screen.pixels, zB = zBuffer, spc = specular, env = envmap)
{
for (int x = xL; x < xR; x++)
{
pos = x + offset;
if (z < zB[pos])
{
lutID = ((nx >> 16) & 255) + (((ny >> 16) & 255) << 8);
bkgrd = sp[pos];
s = warp_Color.add(spc[lutID], env[lutID]);
s = warp_Color.scale(s, reflectivity);
sp[pos] = warp_Color.overSolid(bkgrd, s);;
zB[pos] = z;
}
z += dz;
nx += dnx;
ny += dny;
}
}
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
private unsafe void renderLineT()
{
int bkgrd;
int c;
int pos;
fixed (int* sp = screen.pixels, zB = zBuffer, tp = tpixels)
{
for (int x = xL; x < xR; x++)
{
pos = x + offset;
if (z < zB[pos])
{
bkgrd = sp[pos];
c = tp[(((int)(tx / sw)) & tw) + ((((int)(ty / sw)) & th) << tbitW)];
c = warp_Color.multiply(color, c);
c = warp_Color.overSolid(bkgrd, c);
sp[pos] = c;
zB[pos] = z;
}
z += dz;
tx += dtx;
ty += dty;
sw += dsw;
}
}
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe void renderLinePE()
{
int bkgrd;
@@ -589,8 +663,7 @@ namespace Warp3D
s = warp_Color.scale(s, reflectivity);
c = warp_Color.multiply(color, df[lutID]);
c = warp_Color.overSolid(bkgrd, c);
c = warp_Color.add(c, s);
sp[pos] = c;
sp[pos] = warp_Color.add(c, s);
zB[pos] = z;
}
z += dz;
@@ -600,16 +673,15 @@ namespace Warp3D
}
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
private unsafe void renderLinePT()
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe void renderLinePEO()
{
int bkgrd;
int c;
int s;
int lutID;
int pos;
fixed (int* sp = screen.pixels, zB = zBuffer, df = diffuse, spc = specular, tp = tpixels)
fixed (int* sp = screen.pixels, zB = zBuffer, df = diffuse, spc = specular, env = envmap)
{
for (int x = xL; x < xR; x++)
{
@@ -618,17 +690,40 @@ namespace Warp3D
{
lutID = ((nx >> 16) & 255) + (((ny >> 16) & 255) << 8);
bkgrd = sp[pos];
s = warp_Color.scale(spc[lutID], reflectivity);
c = tp[(((int)(tx / sw)) & tw) + ((((int)(ty / sw)) & th) << tbitW)];
s = warp_Color.add(spc[lutID], env[lutID]);
s = warp_Color.scale(s, reflectivity);
c = warp_Color.multiply(color, df[lutID]);
sp[pos] = warp_Color.add(c, s);
zB[pos] = z;
}
z += dz;
nx += dnx;
ny += dny;
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe void renderLinePET()
{
fixed (int* sp = screen.pixels, zB = zBuffer, df = diffuse, spc = specular, tp = tpixels, env = envmap)
{
for (int x = xL; x < xR; x++)
{
int pos = x + offset;
if (z < zB[pos])
{
int lutID = ((nx >> 16) & 255) + (((ny >> 16) & 255) << 8);
int bkgrd = sp[pos];
int s = warp_Color.add(spc[lutID], env[lutID]);
s = warp_Color.scale(s, reflectivity);
int c = tp[(((int)(tx / sw)) & tw) + ((((int)(ty / sw)) & th) << tbitW)];
c = warp_Color.multiply(color, c);
c = warp_Color.multiply(c, df[lutID]);
c = warp_Color.overSolid(bkgrd, c);
c = warp_Color.add(c, s);
sp[pos] = c;
sp[pos] = warp_Color.add(c, s);
zB[pos] = z;
}
z += dz;
nx += dnx;
ny += dny;
@@ -638,34 +733,23 @@ namespace Warp3D
}
}
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
private unsafe void renderLinePET()
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe void renderLinePETO()
{
int bkgrd;
int c;
int s;
int lutID;
int pos;
fixed (int* sp = screen.pixels, zB = zBuffer, df = diffuse, spc = specular, tp = tpixels, env = envmap)
{
for (int x = xL; x < xR; x++)
{
pos = x + offset;
int pos = x + offset;
if (z < zB[pos])
{
lutID = ((nx >> 16) & 255) + (((ny >> 16) & 255) << 8);
bkgrd = sp[pos];
s = warp_Color.add(spc[lutID], env[lutID]);
int lutID = ((nx >> 16) & 255) + (((ny >> 16) & 255) << 8);
int s = warp_Color.add(spc[lutID], env[lutID]);
s = warp_Color.scale(s, reflectivity);
c = tp[(((int)(tx / sw)) & tw) + ((((int)(ty / sw)) & th) << tbitW)];
int c = tp[(((int)(tx / sw)) & tw) + ((((int)(ty / sw)) & th) << tbitW)];
c = warp_Color.multiply(color, c);
c = warp_Color.multiply(c, df[lutID]);
c = warp_Color.overSolid(bkgrd, c);
c = warp_Color.add(c, s);
sp[pos] = c;
sp[pos] = warp_Color.add(c, s);
zB[pos] = z;
}
z += dz;
@@ -692,8 +776,8 @@ namespace Warp3D
if ((a.clipcode & b.clipcode) != 0)
return;
dx = (int)Math.Abs(a.x - b.x);
dy = (int)Math.Abs(a.y - b.y);
dx = (int)MathF.Abs(a.x - b.x);
dy = (int)MathF.Abs(a.y - b.y);
dz = 0;
fixed (int* sp = screen.pixels, zB = zBuffer)
+46 -146
View File
@@ -1,24 +1,22 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_RenderPipeline.
/// </summary>
public class warp_RenderPipeline: IDisposable
public class warp_RenderPipeline
{
public warp_Screen screen;
warp_Scene scene;
readonly warp_Scene scene;
public warp_Lightmap lightmap;
public bool useId = false;
warp_Rasterizer rasterizer;
ArrayList transparentQueue = new ArrayList(16384);
int zFar = int.MaxValue;
public int[] zBuffer;
@@ -34,7 +32,7 @@ namespace Warp3D
public void buildLightMap()
{
if(lightmap == null)
if (lightmap == null)
{
lightmap = new warp_Lightmap(scene);
}
@@ -51,9 +49,8 @@ namespace Warp3D
rasterizer.rebuildReferences(this);
warp_Math.clearBuffer(zBuffer, zFar);
//System.Array.Copy(screen.zBuffer,0,zBuffer,0,zBuffer.Length);
if(scene.environment.background != null)
if (scene.environment.background is not null)
{
screen.drawBackground(scene.environment.background, 0, 0, screen.width, screen.height);
}
@@ -64,17 +61,17 @@ namespace Warp3D
cam.setScreensize(screen.width, screen.height);
scene.prepareForRendering();
emptyQueues();
// Project
warp_Matrix m = warp_Matrix.multiply(cam.getMatrix(), scene.matrix);
warp_Matrix nm = warp_Matrix.multiply(cam.getNormalMatrix(), scene.normalmatrix);
warp_Matrix vertexProjection, normalProjection;
warp_Matrix vertexProjection = new warp_Matrix();
warp_Matrix normalProjection = new warp_Matrix();
warp_Object obj;
warp_Triangle t;
warp_Vertex v;
warp_Material objmaterial;
const double log2inv = 1.4426950408889634073599246810019;
int w = screen.width;
int h = screen.height;
int minx;
@@ -82,55 +79,53 @@ namespace Warp3D
int maxx;
int maxy;
for(int id = 0 ; id < scene.objects; ++id)
List<warp_Triangle> transparentQueue = new List<warp_Triangle>(4 * scene.wobject.Length);
for (int id = 0; id < scene.wobject.Length; ++id)
{
obj = scene.wobject[id];
if (!obj.visible)
continue;
objmaterial = obj.material;
if(objmaterial == null)
if (objmaterial is null)
continue;
if(!obj.visible)
continue;
if(objmaterial.opaque && objmaterial.reflectivity == 0)
if (objmaterial.opaque && objmaterial.reflectivity == 0)
continue;
vertexProjection = obj.matrix.getClone();
normalProjection = obj.normalmatrix.getClone();
vertexProjection.transform(m);
normalProjection.transform(nm);
vertexProjection.SetFromtransform(obj.matrix, m);
normalProjection.SetFromtransform(obj.normalmatrix, nm);
minx = int.MaxValue;
miny = int.MaxValue;
maxx = int.MinValue;
maxy = int.MinValue;
for(int i = 0; i < obj.vertices; ++i)
for (int i = 0; i < obj.vertexData.Count; ++i)
{
v = obj.fastvertex[i];
v = obj.vertexData[i];
v.project(vertexProjection, normalProjection, cam);
v.clipFrustrum(w, h);
if(minx > v.x)
if (minx > v.x)
minx = v.x;
if(maxx < v.x)
if (maxx < v.x)
maxx = v.x;
if(miny > v.y)
if (miny > v.y)
miny = v.y;
if(maxy < v.y)
if (maxy < v.y)
maxy = v.y;
}
maxx -= minx;
maxy -= miny;
if(maxy > maxx)
maxx = maxy + 1;
else
maxx++;
maxx = Math.Abs(maxx - minx);
maxy = Math.Abs(maxy - miny);
if (maxy > maxx)
maxx = maxy;
obj.projectedmaxMips = (int)Math.Ceiling((Math.Log(maxx) * log2inv));
obj.cacheMaterialData();
obj.projectedmaxMips = System.Numerics.BitOperations.Log2((uint)maxx + 1);
if (objmaterial.opaque)
{
rasterizer.loadFastMaterial(obj);
for (int i = 0; i < obj.triangles; ++i)
rasterizer.loadMaterial(obj);
for (int i = 0; i < obj.triangleData.Count; ++i)
{
t = obj.fasttriangle[i];
t = obj.triangleData[i];
t.project(normalProjection);
if (t.clipFrustrum(w, h))
rasterizer.render(t);
@@ -138,9 +133,9 @@ namespace Warp3D
}
else
{
for (int i = 0; i < obj.triangles; ++i)
for (int i = 0; i < obj.triangleData.Count; ++i)
{
t = obj.fasttriangle[i];
t = obj.triangleData[i];
t.project(normalProjection);
if (t.clipFrustrum(w, h))
transparentQueue.Add(t);
@@ -149,122 +144,27 @@ namespace Warp3D
}
//screen.lockImage();
warp_Triangle[] tri;
obj = null;
tri = getTransparentQueue();
if(tri != null)
if (transparentQueue.Count > 0)
{
transparentQueue.Clear();
for (int i = 0; i < tri.GetLength(0); i++)
transparentQueue.Sort(CompareTrisDistance);
for (int i = 0; i < transparentQueue.Count; i++)
{
if(obj != tri[i].parent)
if (obj != transparentQueue[i].parent)
{
obj = tri[i].parent;
rasterizer.loadFastMaterial(obj);
obj = transparentQueue[i].parent;
rasterizer.loadMaterial(obj);
}
rasterizer.render(tri[i]);
rasterizer.render(transparentQueue[i]);
}
}
//screen.unlockImage();
}
private void performResizing()
{
//screen.resize(requestedWidth, requestedHeight);
zBuffer = new int[screen.width * screen.height];
}
// Triangle sorting
private void emptyQueues()
{
transparentQueue.Clear();
}
private warp_Triangle[] getTransparentQueue()
{
if(transparentQueue.Count == 0)
return null;
IComparer comp = new tridistZDescCompare();
transparentQueue.Sort(comp);
warp_Triangle[] tri = new warp_Triangle[transparentQueue.Count];
int id = 0;
for(int i = 0; i < transparentQueue.Count; ++i)
tri[id++] = (warp_Triangle)transparentQueue[i];
//return sortTriangles(tri, 0, tri.GetLength(0) - 1);
return tri;
}
private warp_Triangle[] sortTriangles(warp_Triangle[] tri, int L, int R)
{
//FIX: Added Index bounds checking. (Was causing random exceptions) - Created by: X
if(L < 0)
L = 0;
if(L > tri.GetLength(0))
L = tri.GetLength(0);
if(R < 0)
R = 0;
if(R > tri.GetLength(0))
R = tri.GetLength(0);
// - Created by: X
float m = (tri[L].distZ + tri[R].distZ) / 2;
int i = L;
int j = R;
warp_Triangle temp;
do
{
while(tri[i].distZ > m)
i++;
while(tri[j].distZ < m)
j--;
if(i <= j)
{
temp = tri[i];
tri[i] = tri[j];
tri[j] = temp;
i++;
j--;
}
}
while(j >= i);
if(L < j)
sortTriangles(tri, L, j);
if(R > i)
sortTriangles(tri, i, R);
return tri;
}
public void Dispose()
{
if(screen != null)
screen.Dispose();
screen = null;
zBuffer = null;
rasterizer.clean();
rasterizer = null;
transparentQueue.Clear();
transparentQueue = null;
}
}
public class tridistZDescCompare : IComparer
{
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
int IComparer.Compare(object x, object y)
{
float a = ((warp_Triangle)x).distZ;
float b = ((warp_Triangle)y).distZ;
if( a == b )
return 0;
return a < b ? 1 : -1;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
int CompareTrisDistance(warp_Triangle x, warp_Triangle y)
{
return y.minDistZ.CompareTo(x.minDistZ);
}
}
}
}
+54 -92
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Timers;
@@ -10,33 +11,30 @@ namespace Warp3D
/// </summary>
public class warp_Scene : warp_CoreObject
{
public static String version = "1.0.0";
public static String release = "0010";
public static string version = "1.0.1";
public static string release = "0010";
public warp_RenderPipeline renderPipeline;
public int width, height;
public warp_Environment environment = new warp_Environment();
public warp_Environment environment = new();
public warp_Camera defaultCamera = warp_Camera.FRONT();
public warp_Object[] wobject;
public warp_Light[] light;
public int objects = 0;
public int lights = 0;
private bool objectsNeedRebuild = true;
private bool lightsNeedRebuild = true;
protected bool preparedForRendering = false;
public warp_Vector normalizedOffset = new warp_Vector(0f, 0f, 0f);
public warp_Vector normalizedOffset = new(0f, 0f, 0f);
public float normalizedScale = 1f;
public Hashtable objectData = new Hashtable();
public Hashtable lightData = new Hashtable();
public Hashtable materialData = new Hashtable();
public Hashtable cameraData = new Hashtable();
public Dictionary<string, warp_Object> objectData = new();
public Dictionary<string, warp_Light> lightData = new();
public Dictionary<string, warp_Material> materialData = new();
public Dictionary<string, warp_Camera> cameraData = new();
public warp_Scene()
{
@@ -52,16 +50,13 @@ namespace Warp3D
public void destroy()
{
objects = objectData.Count;
foreach (warp_Object o in objectData.Values)
o.destroy();
objectData.Clear();
lightData.Clear();
materialData.Clear();
cameraData.Clear();
if (renderPipeline != null)
renderPipeline.Dispose();
objectData = null;
lightData = null;
materialData = null;
cameraData = null;
renderPipeline = null;
environment = null;
defaultCamera = null;
@@ -70,8 +65,7 @@ namespace Warp3D
public void removeAllObjects()
{
objectData = new Hashtable();
objectData = new Dictionary<string, warp_Object>();
objectsNeedRebuild = true;
rebuild();
}
@@ -82,54 +76,53 @@ namespace Warp3D
{
objectsNeedRebuild = false;
objects = objectData.Count;
wobject = new warp_Object[objects];
IDictionaryEnumerator enumerator = objectData.GetEnumerator();
wobject = new warp_Object[objectData.Count];
for (int i = 0; i < objects; ++i)
int i = 0;
foreach (warp_Object o in objectData.Values)
{
enumerator.MoveNext();
wobject[i] = (warp_Object)enumerator.Value;
wobject[i] = o;
wobject[i].id = i;
wobject[i].rebuild();
i++;
}
}
if (lightsNeedRebuild)
{
lightsNeedRebuild = false;
lights = lightData.Count;
light = new warp_Light[lights];
IDictionaryEnumerator enumerator = lightData.GetEnumerator();
for (int i = lights - 1; i >= 0; i--)
{
enumerator.MoveNext();
light[i] = (warp_Light)enumerator.Value;
}
light = new warp_Light[lightData.Count];
lightData.Values.CopyTo(light, 0);
}
}
public warp_Object sceneobject(String key)
public warp_Object sceneobject(string key)
{
return (warp_Object)objectData[key];
if (objectData.TryGetValue(key, out warp_Object obj))
return obj;
return null;
}
public bool TryGetSceneObject(string key, out warp_Object obj)
{
return objectData.TryGetValue(key, out obj);
}
public warp_Material material(String key)
public bool TryGetMaterial(string key, out warp_Material material)
{
return (warp_Material)materialData[key];
return materialData.TryGetValue(key, out material);
}
public warp_Camera camera(String key)
public warp_Camera camera(string key)
{
return (warp_Camera)cameraData[key];
if (cameraData.TryGetValue(key, out warp_Camera camera))
return camera;
return null;
}
public void addObject(String key, warp_Object obj)
public void addObject(string key, warp_Object obj)
{
obj.name = key;
objectData.Add(key, obj);
objectData[key] = obj;
obj.parent = this;
objectsNeedRebuild = true;
preparedForRendering = false;
@@ -142,19 +135,19 @@ namespace Warp3D
preparedForRendering = false;
}
public void addMaterial(String key, warp_Material m)
public void addMaterial(string key, warp_Material m)
{
materialData.Add(key, m);
materialData[key] = m;
}
public void removeMaterial(String key)
public void removeMaterial(string key)
{
materialData.Remove(key);
}
public void addCamera(String key, warp_Camera c)
{
cameraData.Add(key, c);
cameraData[key] = c;
}
public void removeCamera(String key)
@@ -162,9 +155,9 @@ namespace Warp3D
cameraData.Remove(key);
}
public void addLight(String key, warp_Light l)
public void addLight(string key, warp_Light l)
{
lightData.Add(key, l);
lightData[key] = l;
lightsNeedRebuild = true;
}
@@ -213,14 +206,16 @@ namespace Warp3D
public int countVertices()
{
int counter = 0;
for (int i = 0; i < objects; i++) counter += wobject[i].vertices;
for (int i = 0; i < wobject.Length; i++)
counter += wobject[i].vertexData.Count;
return counter;
}
public int countTriangles()
{
int counter = 0;
for (int i = 0; i < objects; i++) counter += wobject[i].triangles;
for (int i = 0; i < wobject.Length; i++)
counter += wobject[i].triangleData.Count;
return counter;
}
@@ -229,46 +224,30 @@ namespace Warp3D
objectsNeedRebuild = true;
rebuild();
warp_Vector min, max, tempmax, tempmin;
if (objects == 0)
{
if (wobject.Length == 0)
return;
}
matrix = new warp_Matrix();
normalmatrix = new warp_Matrix();
max = wobject[0].maximum();
min = wobject[0].maximum();
for (int i = 0; i < objects; i++)
warp_Vector min = wobject[0].fastMin;
warp_Vector max = wobject[0].fastMax;
for (int i = 0; i < wobject.Length; i++)
{
tempmax = wobject[i].maximum();
tempmin = wobject[i].maximum();
warp_Vector tempmin = wobject[i].fastMin;
warp_Vector tempmax = wobject[i].fastMax;
if (tempmax.x > max.x)
{
max.x = tempmax.x;
}
if (tempmax.y > max.y)
{
max.y = tempmax.y;
}
if (tempmax.z > max.z)
{
max.z = tempmax.z;
}
if (tempmin.x < min.x)
{
min.x = tempmin.x;
}
if (tempmin.y < min.y)
{
min.y = tempmin.y;
}
if (tempmin.z < min.z)
{
min.z = tempmin.z;
}
}
float xdist = max.x - min.x;
float ydist = max.y - min.y;
@@ -289,7 +268,7 @@ namespace Warp3D
public float EstimateBoxProjectedArea(warp_Vector pos, warp_Vector size, warp_Matrix rotation)
{
warp_Matrix om = new warp_Matrix();
warp_Matrix om = new();
om.scale(size.x, size.y, size.z);
om.transform(rotation);
@@ -316,14 +295,12 @@ namespace Warp3D
warp_Matrix m = warp_Matrix.multiply(defaultCamera.getMatrix(), matrix);
om.transform(m);
float zmin;
side = new warp_Vector(-1f, -1f, -1f);
v = side.transform(om);
xmin = v.x;
xmax = xmin;
ymin = v.y;
ymax = ymin;
zmin = v.z;
side.x = 1f;
v = side.transform(om);
@@ -335,8 +312,6 @@ namespace Warp3D
ymin = v.y;
else if (ymax < v.y)
ymax = v.y;
if (zmin > v.z)
zmin = v.z;
side.x = -1f;
side.y = 1f;
@@ -349,8 +324,6 @@ namespace Warp3D
ymin = v.y;
else if (ymax < v.y)
ymax = v.y;
if (zmin > v.z)
zmin = v.z;
side.x = 1f;
v = side.transform(om);
@@ -362,8 +335,6 @@ namespace Warp3D
ymin = v.y;
else if (ymax < v.y)
ymax = v.y;
if (zmin > v.z)
zmin = v.z;
side.x = -1f;
side.y = -1f;
@@ -377,8 +348,6 @@ namespace Warp3D
ymin = v.y;
else if (ymax < v.y)
ymax = v.y;
if (zmin > v.z)
zmin = v.z;
side.x = 1f;
v = side.transform(om);
@@ -390,8 +359,6 @@ namespace Warp3D
ymin = v.y;
else if (ymax < v.y)
ymax = v.y;
if (zmin > v.z)
zmin = v.z;
side.x = -1f;
side.y = 1f;
@@ -404,8 +371,6 @@ namespace Warp3D
ymin = v.y;
else if (ymax < v.y)
ymax = v.y;
if (zmin > v.z)
zmin = v.z;
side.x = 1f;
v = side.transform(om);
@@ -417,9 +382,6 @@ namespace Warp3D
ymin = v.y;
else if (ymax < v.y)
ymax = v.y;
if (zmin > v.z)
zmin = v.z;
xmax -= xmin;
ymax -= ymin;
+12 -24
View File
@@ -2,20 +2,18 @@ using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using static System.Net.Mime.MediaTypeNames;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_Screen.
/// </summary>
unsafe public class warp_Screen : IDisposable
unsafe public class warp_Screen
{
public int width;
public int height;
Bitmap image = null;
public int[] pixels;
private GCHandle handle;
public warp_Screen(int w, int h)
{
@@ -23,11 +21,6 @@ namespace Warp3D
height = h;
pixels = new int[w * h];
handle = GCHandle.Alloc(pixels, GCHandleType.Pinned);
IntPtr pointer = Marshal.UnsafeAddrOfPinnedArrayElement(pixels, 0);
image = new Bitmap(w, h, w * 4, PixelFormat.Format32bppPArgb, pointer);
}
public void clear(int c)
@@ -47,12 +40,18 @@ namespace Warp3D
public Bitmap getImage()
{
return new Bitmap(image);
GCHandle handle = GCHandle.Alloc(pixels, GCHandleType.Pinned);
IntPtr pointer = Marshal.UnsafeAddrOfPinnedArrayElement(pixels, 0);
Bitmap image = new Bitmap(width, height, width * 4, PixelFormat.Format32bppPArgb, pointer);
Bitmap ret = new Bitmap(image); //duhhhh
image.Dispose();
handle.Free();
return ret;
}
private unsafe void draw(int width, int height, warp_Texture texture, int posx, int posy, int xsize, int ysize)
{
if (texture == null)
if (texture is null)
{
return;
}
@@ -74,7 +73,7 @@ namespace Warp3D
xBase = warp_Math.crop(xBase, 0, width);
yBase = warp_Math.crop(yBase, 0, height);
fixed(int* px = pixels, txp = texture.pixel)
fixed (int* px = pixels, txp = texture.pixel)
{
ty = tyBase;
for (int j = yBase; j < yend; j++)
@@ -99,7 +98,7 @@ namespace Warp3D
private void add(int width, int height, warp_Texture texture, int posx, int posy, int xsize, int ysize)
{
if (texture == null)
if (texture is null)
{
return;
}
@@ -138,16 +137,5 @@ namespace Warp3D
}
}
}
public void Dispose()
{
if (image != null)
{
handle.Free();
image.Dispose();
image = null;
pixels = null;
}
}
}
}
+110 -132
View File
@@ -1,7 +1,11 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.Net;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Xml.Linq;
namespace Warp3D
{
@@ -16,7 +20,7 @@ namespace Warp3D
public int bitWidth;
public int bitHeight;
public int[] pixel;
public String path = null;
public string path = null;
public int averageColor;
public bool hasAlpha;
public bool opaque;
@@ -38,59 +42,66 @@ namespace Warp3D
cls();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Texture(int w, int h, int[] data)
{
height = h;
width = w;
pixel = new int[width * height];
System.Array.Copy(data, pixel, pixel.Length);
Array.Copy(data, pixel, pixel.Length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Texture(Bitmap map, int maxBitSize = -1)
{
loadTexture(map, maxBitSize);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Texture(string path, int maxBitSize = -1)
{
using(Bitmap map = new Bitmap(path, false))
loadTexture(map, maxBitSize);
using Bitmap map = new(path, false);
loadTexture(map, maxBitSize);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void resize()
{
double log2inv = 1 / Math.Log(2);
int w = (int)Math.Pow(2, bitWidth = (int)Math.Ceiling(MathF.Log2(width)));
int h = (int)Math.Pow(2, bitHeight = (int)Math.Ceiling(MathF.Log2(height)));
int w = (int)Math.Pow(2, bitWidth = (int)Math.Ceiling((Math.Log(width) * log2inv)));
int h = (int)Math.Pow(2, bitHeight = (int)Math.Ceiling((Math.Log(height) * log2inv)));
if(!(w == width && h == height))
if (w != width || h != height)
resize(w, h);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void resize(int w, int h)
{
setSize(w, h);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void cls()
{
warp_Math.clearBuffer(pixel, 0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Texture toAverage()
{
for(int i = width * height - 1; i >= 0; i--)
pixel[i] = warp_Color.getAverage(pixel[i]);
ref int rpixel = ref MemoryMarshal.GetArrayDataReference(pixel);
for (int i = 0; i < pixel.Length; i++)
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixel, i)) = warp_Color.getAverage(Unsafe.As<int, int>(ref Unsafe.Add(ref rpixel, i)));
return this;
}
public warp_Texture toGray()
{
for(int i = width * height - 1; i >= 0; i--)
pixel[i] = warp_Color.getGray(pixel[i]);
ref int rpixel = ref MemoryMarshal.GetArrayDataReference(pixel);
for (int i = 0; i < pixel.Length; i++)
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixel, i)) = warp_Color.getGray(Unsafe.As<int, int>(ref Unsafe.Add(ref rpixel, i)));
return this;
}
@@ -98,10 +109,11 @@ namespace Warp3D
public warp_Texture valToGray()
{
int intensity;
for(int i = width * height - 1; i >= 0; i--)
ref int rpixel = ref MemoryMarshal.GetArrayDataReference(pixel);
for (int i = 0; i < pixel.Length; i++)
{
intensity = warp_Math.crop(pixel[i], 0, 255);
pixel[i] = warp_Color.getColor(intensity, intensity, intensity);
intensity = warp_Math.crop(Unsafe.As<int, int>(ref Unsafe.Add(ref rpixel, i)), 0, 255);
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixel, i)) = warp_Color.getColor(intensity, intensity, intensity);
}
return this;
@@ -110,8 +122,10 @@ namespace Warp3D
public warp_Texture colorize(int[] pal)
{
int range = pal.GetLength(0) - 1;
for(int i = width * height - 1; i >= 0; i--)
pixel[i] = pal[warp_Math.crop(pixel[i], 0, range)];
ref int rpixel = ref MemoryMarshal.GetArrayDataReference(pixel);
for (int i = 0; i < pixel.Length; i++)
Unsafe.As<int, int>(ref Unsafe.Add(ref rpixel, i)) =
pal[warp_Math.crop(Unsafe.As<int, int>(ref Unsafe.Add(ref rpixel, i)), 0, range)];
return this;
}
@@ -126,30 +140,23 @@ namespace Warp3D
height = map.Height;
PixelFormat format = pmap.PixelFormat;
PixelFormat targetformat;
switch(format)
PixelFormat targetformat = format switch
{
case PixelFormat.Format16bppArgb1555:
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
case PixelFormat.Format64bppArgb:
case PixelFormat.Format64bppPArgb:
targetformat = PixelFormat.Format32bppArgb;
break;
default:
targetformat = PixelFormat.Format24bppRgb;
break;
}
PixelFormat.Format16bppArgb1555 => PixelFormat.Format32bppArgb,
PixelFormat.Format32bppArgb => PixelFormat.Format32bppArgb,
PixelFormat.Format32bppPArgb => PixelFormat.Format32bppArgb,
PixelFormat.Format64bppArgb => PixelFormat.Format32bppArgb,
PixelFormat.Format64bppPArgb => PixelFormat.Format32bppArgb,
_ => PixelFormat.Format24bppRgb
};
// make sure sizes are power of 2
const double log2inv = 1.4426950408889634073599246810019;
bitWidth = (int)Math.Ceiling((Math.Log(width) * log2inv));
bitHeight = (int)Math.Ceiling((Math.Log(height) * log2inv));
// make sure sizes are power of 2
bitWidth = (int)MathF.Ceiling(MathF.Log2(width));
bitHeight = (int)MathF.Ceiling(MathF.Log2(height));
if(maxBitSize > 3)
if (maxBitSize > 3)
{
if(bitWidth > bitHeight)
if (bitWidth > bitHeight)
{
if (bitWidth > maxBitSize)
{
@@ -173,10 +180,10 @@ namespace Warp3D
}
}
int w = (int)Math.Pow(2, bitWidth);
int h = (int)Math.Pow(2, bitHeight);
int w = (int)MathF.Pow(2, bitWidth);
int h = (int)MathF.Pow(2, bitHeight);
if(width != w || height != h || format != targetformat)
if (width != w || height != h || format != targetformat)
{
map = ResizeBitmap(pmap, w, h, targetformat);
width = w;
@@ -193,7 +200,7 @@ namespace Warp3D
byte green;
byte red;
byte alpha;
pixel = new int[width * height];
hasAlpha = targetformat == PixelFormat.Format32bppArgb;
@@ -202,26 +209,26 @@ namespace Warp3D
unsafe
{
byte* p = (byte*)bmData.Scan0;
fixed(int* px = pixel)
fixed (int* px = pixel)
{
int nPixel = 0;
if(hasAlpha)
if (hasAlpha)
{
int nOffset = bmData.Stride - width * 4;
for(int i = 0; i < height; i++)
for (int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
for (int j = 0; j < width; j++)
{
blue = *(p++);
avgB += blue;
avgB += blue;
green = *(p++);
avgG += green;
avgG += green;
red = *(p++);
avgR += red;
alpha = *(p++);
avgA += alpha;
if(opaque && alpha != 0xff)
if (opaque && alpha != 0xff)
opaque = false;
px[nPixel++] = alpha << 24 | red << 16 | green << 8 | blue;
}
@@ -231,9 +238,9 @@ namespace Warp3D
else
{
int nOffset = bmData.Stride - width * 3;
for(int i = 0; i < height; i++)
for (int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
for (int j = 0; j < width; j++)
{
blue = *(p++);
avgB += blue;
@@ -251,7 +258,7 @@ namespace Warp3D
}
map.UnlockBits(bmData);
if(disposemap)
if (disposemap)
map.Dispose();
ulong np = (ulong)(width * height);
@@ -259,16 +266,16 @@ namespace Warp3D
blue = (byte)(avgB / np);
green = (byte)(avgG / np);
red = (byte)(avgR / np);
if(hasAlpha)
if (hasAlpha)
{
alpha= (byte)(avgA / np);
alpha = (byte)(avgA / np);
averageColor = alpha << 24 | red << 16 | green << 8 | blue;
}
else
averageColor = ALPHA | red << 16 | green << 8 | blue;
maxmips = bitHeight;
if(maxmips > bitWidth)
if (maxmips > bitWidth)
maxmips = bitWidth;
maxmips -= 3; // less 1x1 2x2 and max
@@ -285,51 +292,33 @@ namespace Warp3D
mipsBitHeight = new int[maxmips + 1];
mipstw = new int[maxmips + 1];
mipsth = new int[maxmips + 1];
int w = width;
int h = height;
int bw = bitWidth;
int bh = bitHeight;
int[] src;
int[] dst = null;
for(int n = maxmips; n >= 0; --n)
int[] dst = mips[maxmips + 1];
for (int n = maxmips; n >= 0; --n)
{
src = mips[n + 1];
if(w > 1)
{
w >>= 1;
--bw;
if(h > 1)
{
h >>= 1;
--bh;
dst = dec2XY(src, w, h);
}
else
dst = dec2X(src, w, h);
}
else
{
if(h > 1)
{
h >>= 1;
--bh;
dst = dec2Y(src, w, h);
}
}
src = dst;
w >>= 1;
h >>= 1;
dst = dec2XY(src, w, h);
mips[n] = dst;
mipsBitWidth[n] = bw;
mipsBitHeight[n] = bh;
mipsBitWidth[n] = --bw;
mipsBitHeight[n] = --bh;
mipstw[n] = w;
mipsth[n] = h;
}
hasmips = true;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe int[] dec2XY(int[] src, int w, int h)
{
/*
int[] dst = new int[w * h];
int sw = 2 * w;
int stot = 2 * h * sw;
@@ -341,9 +330,9 @@ namespace Warp3D
int dx = 0;
fixed (int* s = src, d = dst)
{
for (int sx = 0 ; sx < stot; sx += sw, sxl2 += sw)
for (int sx = 0; sx < stot; sx += sw, sxl2 += sw)
{
for(int i = 0; i < w ; i++, sx += 2, sxl2 += 2)
for (int i = 0; i < w; i++, sx += 2, sxl2 += 2)
{
c1 = s[sx];
c2 = s[sx + 1];
@@ -354,48 +343,37 @@ namespace Warp3D
}
}
return dst;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
private int[] dec2X(int[] src, int w, int h)
{
int dstsize = w * h;
int[] dst = new int[dstsize];
int c1;
int c2;
int sx = 0;
for(int dx = 0 ; dx < dstsize; ++dx)
{
c1 = src[sx];
c2 = src[sx + 1];
dst[dx] = warp_Color.avg2c(c1, c2);
sx += 2;
}
return dst;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
private unsafe int[] dec2Y(int[] src, int w, int h)
{
*/
int[] dst = new int[w * h];
int stot = 2 * h * w;
int c1;
int c2;
int sxl2 = w;
int dx = 0;
fixed (int* s = src, d = dst)
int sw = 8 * w; // 4 bytes * 2 * w
fixed (int* si = src, di = dst)
{
for (int sx = 0 ; sx < stot; sx += w, sxl2 += w)
byte* d = (byte*)di;
byte* s = (byte*)si;
byte* s2 = s + sw;
for (int y = 0; y < h; y++)
{
for(int i = 0; i < w ; i++, ++sx, ++sxl2)
for (int x = 0; x < w; x++)
{
c1 = s[sx];
c2 = s[sxl2];
d[dx++] = warp_Color.avg2c(c1, c2);
int t = s[0] + s[4] + s2[0] + s2[4] + 2;
d[0] = (byte)(t >> 2);
t = s[1] + s[5] + s2[1] + s2[5] + 2;
d[1] = (byte)(t >> 2);
t = s[2] + s[6] + s2[2] + s2[6] + 2;
d[2] = (byte)(t >> 2);
t = s[3] + s[7] + s2[3] + s2[7] + 2;
d[3] = (byte)(t >> 2);
d += 4;
s += 8;
s2 += 8;
}
s += sw;
s2 += sw;
}
}
return dst;
@@ -405,16 +383,16 @@ namespace Warp3D
{
int offset = w * h;
int offset2;
if(w * h != 0)
if (w * h != 0)
{
int[] newpixels = new int[w * h];
fixed(int* np = newpixels, p = pixel)
fixed (int* np = newpixels, p = pixel)
{
for(int j = h - 1; j >= 0; j--)
for (int j = h - 1; j >= 0; j--)
{
offset -= w;
offset2 = (j * height / h) * width;
for(int i = w - 1; i >= 0; i--)
for (int i = w - 1; i >= 0; i--)
np[i + offset] = p[(i * width / w) + offset2];
}
}
@@ -424,7 +402,7 @@ namespace Warp3D
}
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool inrange(int a, int b, int c)
{
return (a >= b) & (a < c);
@@ -432,16 +410,16 @@ namespace Warp3D
public warp_Texture getClone()
{
warp_Texture t = new warp_Texture(width, height);
warp_Texture t = new(width, height);
warp_Math.copyBuffer(pixel, t.pixel);
return t;
}
public static Bitmap ResizeBitmap(Image image, int width, int height, PixelFormat format)
{
Bitmap result = new Bitmap(width, height, format);
Bitmap result = new(width, height, format);
using (ImageAttributes atrib = new ImageAttributes())
using (ImageAttributes atrib = new())
using (Graphics graphics = Graphics.FromImage(result))
{
atrib.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY);
@@ -451,7 +429,7 @@ namespace Warp3D
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None;
graphics.DrawImage(image,new Rectangle(0,0, result.Width, result.Height),
graphics.DrawImage(image, new Rectangle(0, 0, result.Width, result.Height),
0, 0, image.Width, image.Height, GraphicsUnit.Pixel, atrib);
}
+201 -201
View File
@@ -2,231 +2,231 @@ using System;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_TextureFactory.
/// </summary>
public class warp_TextureFactory
{
public static float pi = 3.1415926535f;
public static float deg2rad = pi / 180;
private static float[,] noiseBuffer;
private static bool noiseBufferInitialized = false;
public static int ALPHA = unchecked((int)0xFF000000); // alpha mask
/// <summary>
/// Summary description for warp_TextureFactory.
/// </summary>
public class warp_TextureFactory
{
public static float pi = 3.1415926535f;
public static float deg2rad = pi / 180;
private static float[,] noiseBuffer;
private static bool noiseBufferInitialized = false;
public static int ALPHA = unchecked((int)0xFF000000); // alpha mask
private warp_TextureFactory()
{
}
private warp_TextureFactory()
{
}
public static warp_Texture SKY(int w, int h, float density)
{
int[] colors = new int[2];
colors[0] = 0x003399;
colors[1] = 0xFFFFFF;
return PERLIN(w, h, 0.5f, 2.8f * density, 8, 1024).colorize(warp_Color.makeGradient(colors, 1024));
}
public static warp_Texture SKY(int w, int h, float density)
{
int[] colors = new int[2];
colors[0] = 0x003399;
colors[1] = 0xFFFFFF;
return PERLIN(w, h, 0.5f, 2.8f * density, 8, 1024).colorize(warp_Color.makeGradient(colors, 1024));
}
public static warp_Texture MARBLE(int w, int h, float density)
{
int[] colors = new int[3];
colors[0] = 0x111111;
colors[1] = 0x696070;
colors[2] = 0xFFFFFF;
return WAVE(w, h, 0.5f, 0.64f * density, 6, 1024).colorize(warp_Color.makeGradient(colors, 1024));
}
public static warp_Texture MARBLE(int w, int h, float density)
{
int[] colors = new int[3];
colors[0] = 0x111111;
colors[1] = 0x696070;
colors[2] = 0xFFFFFF;
return WAVE(w, h, 0.5f, 0.64f * density, 6, 1024).colorize(warp_Color.makeGradient(colors, 1024));
}
public static warp_Texture WOOD(int w, int h, float density)
{
int[] colors = new int[3];
colors[0] = 0x332211;
colors[1] = 0x523121;
colors[2] = 0x996633;
public static warp_Texture WOOD(int w, int h, float density)
{
int[] colors = new int[3];
colors[0] = 0x332211;
colors[1] = 0x523121;
colors[2] = 0x996633;
return GRAIN(w, h, 0.5f, 3f * density, 3, 8, 1024).colorize(warp_Color.makeGradient(colors, 1024));
}
return GRAIN(w, h, 0.5f, 3f * density, 3, 8, 1024).colorize(warp_Color.makeGradient(colors, 1024));
}
public static warp_Texture PERLIN(int w, int h, float persistency,
float density, int samples, int scale)
{
initNoiseBuffer();
warp_Texture t = new warp_Texture(w, h);
int pos = 0;
float wavelength = (float) ( (w > h) ? w : h) / density;
public static warp_Texture PERLIN(int w, int h, float persistency,
float density, int samples, int scale)
{
initNoiseBuffer();
warp_Texture t = new(w, h);
int pos = 0;
float wavelength = (float)((w > h) ? w : h) / density;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
t.pixel[pos++] = (int) ( (float) scale *
perlin2d(x, y, wavelength, persistency,
samples));
}
}
return t;
}
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
t.pixel[pos++] = (int)((float)scale *
perlin2d(x, y, wavelength, persistency,
samples));
}
}
return t;
}
public static warp_Texture WAVE(int w, int h, float persistency,
float density, int samples, int scale)
{
initNoiseBuffer();
warp_Texture t = new warp_Texture(w, h);
int pos = 0;
float wavelength = (float) ( (w > h) ? w : h) / density;
public static warp_Texture WAVE(int w, int h, float persistency,
float density, int samples, int scale)
{
initNoiseBuffer();
warp_Texture t = new(w, h);
int pos = 0;
float wavelength = (float)((w > h) ? w : h) / density;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
t.pixel[pos++] = (int) ( (double) scale *
(Math.Sin(32 *
perlin2d(x, y, wavelength,
persistency, samples)) * 0.5 + 0.5));
}
}
return t;
}
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
t.pixel[pos++] = (int)(scale *
(MathF.Sin(32f *
perlin2d(x, y, wavelength,
persistency, samples)) * 0.5f + 0.5f));
}
}
return t;
}
public static warp_Texture GRAIN(int w, int h, float persistency,
float density, int samples, int levels,
int scale)
// TIP: For wooden textures
{
initNoiseBuffer();
warp_Texture t = new warp_Texture(w, h);
int pos = 0;
float wavelength = (float) ( (w > h) ? w : h) / density;
float perlin;
public static warp_Texture GRAIN(int w, int h, float persistency,
float density, int samples, int levels,
int scale)
// TIP: For wooden textures
{
initNoiseBuffer();
warp_Texture t = new(w, h);
int pos = 0;
float wavelength = (float)((w > h) ? w : h) / density;
float perlin;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
perlin = (float) levels *
perlin2d(x, y, wavelength, persistency, samples);
t.pixel[pos++] = (int) ( (float) scale *
(perlin - (float) (int) perlin));
}
}
return t;
}
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
perlin = (float)levels *
perlin2d(x, y, wavelength, persistency, samples);
t.pixel[pos++] = (int)((float)scale *
(perlin - (float)(int)perlin));
}
}
return t;
}
// Perlin noise functions
// Perlin noise functions
private static float perlin2d(float x, float y, float wavelength,
float persistence, int samples)
{
float sum = 0;
float freq = 1f / wavelength;
float amp = persistence;
float range = 0;
private static float perlin2d(float x, float y, float wavelength,
float persistence, int samples)
{
float sum = 0;
float freq = 1f / wavelength;
float amp = persistence;
float range = 0;
for (int i = 0; i < samples; i++)
{
sum += amp * interpolatedNoise(x * freq, y * freq, i);
range += amp;
amp *= persistence;
freq *= 2;
}
return warp_Math.crop(sum / persistence * 0.5f + 0.5f, 0, 1);
}
for (int i = 0; i < samples; i++)
{
sum += amp * interpolatedNoise(x * freq, y * freq, i);
range += amp;
amp *= persistence;
freq *= 2;
}
return warp_Math.crop(sum / persistence * 0.5f + 0.5f, 0, 1);
}
// Helper methods
// Helper methods
private static float interpolatedNoise(float x, float y, int octave)
{
int intx = (int) x;
int inty = (int) y;
float fracx = x - (float) intx;
float fracy = y - (float) inty;
private static float interpolatedNoise(float x, float y, int octave)
{
int intx = (int)x;
int inty = (int)y;
float fracx = x - (float)intx;
float fracy = y - (float)inty;
float i1 = warp_Math.interpolate(noise(intx, inty, octave),
noise(intx + 1, inty, octave), fracx);
float i2 = warp_Math.interpolate(noise(intx, inty + 1, octave),
noise(intx + 1, inty + 1, octave),
fracx);
float i1 = warp_Math.interpolate(noise(intx, inty, octave),
noise(intx + 1, inty, octave), fracx);
float i2 = warp_Math.interpolate(noise(intx, inty + 1, octave),
noise(intx + 1, inty + 1, octave),
fracx);
return warp_Math.interpolate(i1, i2, fracy);
}
return warp_Math.interpolate(i1, i2, fracy);
}
private static float smoothNoise(int x, int y, int o)
{
return (noise(x - 1, y - 1, o) + noise(x + 1, y - 1, o) +
noise(x - 1, y + 1, o) + noise(x + 1, y + 1, o)) / 16
+
(noise(x - 1, y, o) + noise(x + 1, y, o) + noise(x, y - 1, o) +
noise(x, y + 1, o)) / 8
+ noise(x, y, o) / 4;
}
private static float smoothNoise(int x, int y, int o)
{
return (noise(x - 1, y - 1, o) + noise(x + 1, y - 1, o) +
noise(x - 1, y + 1, o) + noise(x + 1, y + 1, o)) / 16
+
(noise(x - 1, y, o) + noise(x + 1, y, o) + noise(x, y - 1, o) +
noise(x, y + 1, o)) / 8
+ noise(x, y, o) / 4;
}
private static float noise(int x, int y, int octave)
{
return noiseBuffer[octave & 3, (x + y * 57) & 8191];
}
private static float noise(int x, int y, int octave)
{
return noiseBuffer[octave & 3, (x + y * 57) & 8191];
}
private static float noise(int seed, int octave)
{
int id = octave & 3;
int n = (seed << 13) ^ seed;
private static float noise(int seed, int octave)
{
int id = octave & 3;
int n = (seed << 13) ^ seed;
if (id == 0)
{
return (float) (1f -
( (n * (n * n * 15731 + 789221) + 1376312589) &
0x7FFFFFFF) *
0.000000000931322574615478515625f);
}
if (id == 1)
{
return (float) (1f -
( (n * (n * n * 12497 + 604727) + 1345679039) &
0x7FFFFFFF) *
0.000000000931322574615478515625f);
}
if (id == 2)
{
return (float) (1f -
( (n * (n * n * 19087 + 659047) + 1345679627) &
0x7FFFFFFF) *
0.000000000931322574615478515625f);
}
return (float) (1f -
( (n * (n * n * 16267 + 694541) + 1345679501) &
0x7FFFFFFF) *
0.000000000931322574615478515625f);
}
if (id == 0)
{
return (float)(1f -
((n * (n * n * 15731 + 789221) + 1376312589) &
0x7FFFFFFF) *
0.000000000931322574615478515625f);
}
if (id == 1)
{
return (float)(1f -
((n * (n * n * 12497 + 604727) + 1345679039) &
0x7FFFFFFF) *
0.000000000931322574615478515625f);
}
if (id == 2)
{
return (float)(1f -
((n * (n * n * 19087 + 659047) + 1345679627) &
0x7FFFFFFF) *
0.000000000931322574615478515625f);
}
return (float)(1f -
((n * (n * n * 16267 + 694541) + 1345679501) &
0x7FFFFFFF) *
0.000000000931322574615478515625f);
}
private static void initNoiseBuffer()
{
if (noiseBufferInitialized)
{
return;
}
private static void initNoiseBuffer()
{
if (noiseBufferInitialized)
{
return;
}
noiseBuffer = new float[4,8192];
for (int octave = 0; octave < 4; octave++)
{
for (int i = 0; i < 8192; i++)
{
noiseBuffer[octave,i] = noise(i, octave);
}
}
noiseBufferInitialized = true;
}
public static warp_Texture CHECKERBOARD(int w, int h, int cellbits, int oddColor, int evenColor)
{
warp_Texture t = new warp_Texture(w, h);
noiseBuffer = new float[4, 8192];
for (int octave = 0; octave < 4; octave++)
{
for (int i = 0; i < 8192; i++)
{
noiseBuffer[octave, i] = noise(i, octave);
}
}
noiseBufferInitialized = true;
}
int pos = 0;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
int c = ( ( (x >> cellbits) + (y >> cellbits)) & 1) == 0 ? evenColor : oddColor;
t.pixel[pos++] = c;
}
}
public static warp_Texture CHECKERBOARD(int w, int h, int cellbits, int oddColor, int evenColor)
{
warp_Texture t = new(w, h);
return t;
}
}
int pos = 0;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
int c = (((x >> cellbits) + (y >> cellbits)) & 1) == 0 ? evenColor : oddColor;
t.pixel[pos++] = c;
}
}
return t;
}
}
}
@@ -2,40 +2,40 @@ using System;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_TextureProjector.
/// </summary>
public class warp_TextureProjector
{
public static void projectFrontal(warp_Object obj)
{
obj.rebuild();
warp_Vector min = obj.minimum();
warp_Vector max = obj.maximum();
float du = 1 / (max.x - min.x);
float dv = 1 / (max.y - min.y);
for (int i = 0; i < obj.vertices; i++)
{
obj.fastvertex[i].u = (obj.fastvertex[i].pos.x - min.x) * du;
obj.fastvertex[i].v = 1 - (obj.fastvertex[i].pos.y - min.y) * dv;
}
}
/// <summary>
/// Summary description for warp_TextureProjector.
/// </summary>
public class warp_TextureProjector
{
public static void projectFrontal(warp_Object obj)
{
obj.rebuild();
warp_Vector min = obj.fastMin;
warp_Vector max = obj.fastMax;
float du = 1 / (max.x - min.x);
float dv = 1 / (max.y - min.y);
public static void projectTop(warp_Object obj)
{
obj.rebuild();
warp_Vector min = obj.minimum();
warp_Vector max = obj.maximum();
float du = 1 / (max.x - min.x);
float dv = 1 / (max.z - min.z);
for (int i = 0; i < obj.vertices; i++)
{
obj.fastvertex[i].u = (obj.fastvertex[i].pos.x - min.x) * du;
obj.fastvertex[i].v = (obj.fastvertex[i].pos.z - min.z) * dv;
}
}
for (int i = 0; i < obj.vertexData.Count; i++)
{
obj.vertexData[i].u = (obj.vertexData[i].pos.x - min.x) * du;
obj.vertexData[i].v = 1 - (obj.vertexData[i].pos.y - min.y) * dv;
}
}
public static void projectTop(warp_Object obj)
{
obj.rebuild();
warp_Vector min = obj.fastMin;
warp_Vector max = obj.fastMax;
float du = 1 / (max.x - min.x);
float dv = 1 / (max.z - min.z);
for (int i = 0; i < obj.vertexData.Count; i++)
{
obj.vertexData[i].u = (obj.vertexData[i].pos.x - min.x) * du;
obj.vertexData[i].v = (obj.vertexData[i].pos.z - min.z) * dv;
}
}
/*
public static void projectCylindric(warp_Object obj)
{
obj.rebuild();
@@ -48,6 +48,22 @@ namespace Warp3D
obj.fastvertex[i].u = obj.fastvertex[i].pos.theta / (2 * 3.14159265f);
obj.fastvertex[i].v = (obj.fastvertex[i].pos.z - min.z) * dz;
}
}
}
}
*/
public static void projectCylindric(warp_Object obj)
{
obj.rebuild();
const float inv2p = 0.5f / MathF.PI;
warp_Vector min = obj.fastMin;
warp_Vector max = obj.fastMax;
float dz = 1 / (max.z - min.z);
for (int i = 0; i < obj.vertexData.Count; i++)
{
float theta = MathF.Atan2(obj.vertexData[i].pos.x, obj.vertexData[i].pos.y);
obj.vertexData[i].u = theta * inv2p;
obj.vertexData[i].v = (obj.vertexData[i].pos.z - min.z) * dz;
}
}
}
}
+27 -27
View File
@@ -2,32 +2,32 @@ using System;
namespace Warp3D
{
/// <summary>
/// Summary description for warp_TextureSettings.
/// </summary>
///
public class warp_TextureSettings
{
public warp_Texture texture;
public int width;
public int height;
public int type;
public float persistency;
public float density;
public int samples;
public int numColors;
public int[] colors;
/// <summary>
/// Summary description for warp_TextureSettings.
/// </summary>
///
public class warp_TextureSettings
{
public warp_Texture texture;
public int width;
public int height;
public int type;
public float persistency;
public float density;
public int samples;
public int numColors;
public int[] colors;
public warp_TextureSettings(warp_Texture tex, int w, int h, int t, float p, float d, int s, int[] c)
{
texture=tex;
width=w;
height=h;
type=t;
persistency=p;
density=d;
samples=s;
colors=c;
}
}
public warp_TextureSettings(warp_Texture tex, int w, int h, int t, float p, float d, int s, int[] c)
{
texture = tex;
width = w;
height = h;
type = t;
persistency = p;
density = d;
samples = s;
colors = c;
}
}
}
+21 -16
View File
@@ -1,4 +1,5 @@
using System;
using System.Runtime.CompilerServices;
namespace Warp3D
{
@@ -7,17 +8,16 @@ namespace Warp3D
/// </summary>
public class warp_Triangle
{
public const float oneThird = 1.0f / 3f;
public warp_Object parent; // the object which obtains this triangle
public warp_Vertex p1; // first vertex
public warp_Vertex p2; // second vertex
public warp_Vertex p3; // third vertex
public warp_Vector n; // Normal vector of flat triangle
public warp_Vector rawNorm; // Normal h vector of flat triangle
public warp_Vector n2; // Projected Normal vector
private warp_Vector triangleCenter = new warp_Vector();
public float distZ = 0;
public int minDistZ = 0;
public int id = 0;
@@ -39,36 +39,41 @@ namespace Warp3D
public void project(warp_Matrix normalProjection)
{
n2 = n.transform(normalProjection);
distZ = getDistZ();
minDistZ = getMinDistZ();
}
public void regenerateNormal()
{
rawNorm = warp_Vector.vectorProduct(p1.pos, p2.pos, p3.pos);
n = rawNorm.normalize();
warp_Vector tmpa = warp_Vector.sub(ref p2.pos, ref p1.pos);
warp_Vector tmpb = warp_Vector.sub(ref p3.pos, ref p1.pos);
n = warp_Vector.vectorProduct(ref tmpa, ref tmpb);
n.normalize();
}
public warp_Vertex getMedium()
{
float cx = (p1.pos.x + p2.pos.x + p3.pos.x) / 3;
float cy = (p1.pos.y + p2.pos.y + p3.pos.y) / 3;
float cz = (p1.pos.z + p2.pos.z + p3.pos.z) / 3;
float cu = (p1.u + p2.u + p3.u) / 3;
float cv = (p1.v + p2.v + p3.v) / 3;
float cx = (p1.pos.x + p2.pos.x + p3.pos.x) * oneThird;
float cy = (p1.pos.y + p2.pos.y + p3.pos.y) * oneThird;
float cz = (p1.pos.z + p2.pos.z + p3.pos.z) * oneThird;
float cu = (p1.u + p2.u + p3.u) * oneThird;
float cv = (p1.v + p2.v + p3.v) * oneThird;
return new warp_Vertex(cx, cy, cz, cu, cv);
}
public warp_Vector getCenter()
{
float cx = (p1.pos.x + p2.pos.x + p3.pos.x) / 3;
float cy = (p1.pos.y + p2.pos.y + p3.pos.y) / 3;
float cz = (p1.pos.z + p2.pos.z + p3.pos.z) / 3;
float cx = (p1.pos.x + p2.pos.x + p3.pos.x) * oneThird;
float cy = (p1.pos.y + p2.pos.y + p3.pos.y) * oneThird;
float cz = (p1.pos.z + p2.pos.z + p3.pos.z) * oneThird;
return new warp_Vector(cx, cy, cz);
}
public float getDistZ()
public int getMinDistZ()
{
return p1.z + p2.z + p3.z;
int m = p1.z;
if (m > p2.z)
m = p2.z;
return m > p3.z ? p3.z : m;
}
public bool degenerated()
+64 -93
View File
@@ -1,14 +1,13 @@
using System;
using System.Runtime.CompilerServices;
namespace Warp3D
{
public class warp_Vector
public struct warp_Vector
{
public float x = 0; //Cartesian (default)
public float y = 0; //Cartesian (default)
public float z = 0; //Cartesian (default),Cylindric
public float r = 0; //Cylindric
public float theta = 0; //Cylindric
public float x = 0;
public float y = 0;
public float z = 0;
public warp_Vector()
{
@@ -20,20 +19,31 @@ namespace Warp3D
y = ypos;
z = zpos;
}
public warp_Vector normalize()
public static warp_Vector FromXYZ(float xpos, float zpos, float ypos)
{
return new warp_Vector
{
x = xpos,
y = ypos,
z = zpos
};
}
public void normalize()
// Normalizes the vector
{
float dist = length();
if(dist == 0)
return this;
float invdist = 1 / dist;
x *= invdist;
y *= invdist;
z *= invdist;
return this;
float dist = lengthSquare();
if (dist > 1e-6f)
{
float invdist = 1f / MathF.Sqrt(dist);
x *= invdist;
y *= invdist;
z *= invdist;
}
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Vector reverse()
// Reverses the vector
{
@@ -43,21 +53,33 @@ namespace Warp3D
return this;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float length()
// Lenght of this vector
{
return (float)Math.Sqrt(x * x + y * y + z * z);
return MathF.Sqrt(x * x + y * y + z * z);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float lengthSquare()
{
return (x * x + y * y + z * z);
}
public warp_Vector transform(warp_Matrix m)
// Modifies the vector by matrix m
{
float newx = x * m.m00 + y * m.m01 + z * m.m02 + m.m03;
float newy = x * m.m10 + y * m.m11 + z * m.m12 + m.m13;
float newz = x * m.m20 + y * m.m21 + z * m.m22 + m.m23;
return new warp_Vector(
x * m.m00 + y * m.m01 + z * m.m02 + m.m03,
x * m.m10 + y * m.m11 + z * m.m12 + m.m13,
x * m.m20 + y * m.m21 + z * m.m22 + m.m23
);
}
return new warp_Vector(newx, newy, newz);
public void transformToXY(warp_Matrix m, out float nx, out float ny)
// Modifies the vector by matrix m
{
nx = x * m.m00 + y * m.m01 + z * m.m02 + m.m03;
ny = x * m.m10 + y * m.m11 + z * m.m12 + m.m13;
}
public warp_Vector pointtransform(warp_Matrix m)
@@ -66,8 +88,8 @@ namespace Warp3D
float newx = x * m.m00 + y * m.m01 + z * m.m02 + m.m03;
float newy = x * m.m10 + y * m.m11 + z * m.m12 + m.m13;
float newz = x * m.m20 + y * m.m21 + z * m.m22 + m.m23;
float w = x * m.m30 + y * m.m31 + z * m.m32 + m.m33;
if(w != 1.0f && w != 0f)
float w = x * m.m30 + y * m.m31 + z * m.m32 + m.m33;
if (w != 1.0f && w != 0f)
{
w = 1.0f / w;
newx *= w;
@@ -78,109 +100,58 @@ namespace Warp3D
return new warp_Vector(newx, newy, newz);
}
public void buildCylindric()
// Builds the cylindric coordinates out of the given cartesian coordinates
{
r = (float)Math.Sqrt(x * x + y * y);
theta = (float)Math.Atan2(x, y);
}
public void buildCartesian()
// Builds the cartesian coordinates out of the given cylindric coordinates
{
x = r * warp_Math.cos(theta);
y = r * warp_Math.sin(theta);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static warp_Vector getNormal(warp_Vector a, warp_Vector b)
// returns the normal vector of the plane defined by the two vectors
{
return vectorProduct(a, b).normalize();
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static warp_Vector getNormal(warp_Vector a, warp_Vector b, warp_Vector c)
// returns the normal vector of the plane defined by the two vectors
{
return vectorProduct(a, b, c).normalize();
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static warp_Vector vectorProduct(warp_Vector a, warp_Vector b)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static warp_Vector vectorProduct(ref warp_Vector a, ref warp_Vector b)
// returns a x b
{
return new warp_Vector(a.y * b.z - b.y * a.z, a.z * b.x - b.z * a.x, a.x * b.y - b.x * a.y);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static warp_Vector vectorProduct(warp_Vector a, warp_Vector b, warp_Vector c)
// returns (b-a) x (c-a)
{
return vectorProduct(sub(b, a), sub(c, a));
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static float vectorsCos(warp_Vector a, warp_Vector b)
// returns the angle between 2 vectors
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float vectorsCos(ref warp_Vector a, ref warp_Vector b)
{
a.normalize();
b.normalize();
return (a.x * b.x + a.y * b.y + a.z * b.z);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static float Dot(warp_Vector a, warp_Vector b)
// returns the angle between 2 vectors
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Dot(ref warp_Vector a, ref warp_Vector b)
{
return (a.x * b.x + a.y * b.y + a.z * b.z);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static warp_Vector add(warp_Vector a, warp_Vector b)
// adds 2 vectors
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static warp_Vector add(ref warp_Vector a, ref warp_Vector b)
{
return new warp_Vector(a.x + b.x, a.y + b.y, a.z + b.z);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static warp_Vector sub(warp_Vector a, warp_Vector b)
// substracts 2 vectors
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static warp_Vector sub(ref warp_Vector a, ref warp_Vector b)
{
return new warp_Vector(a.x - b.x, a.y - b.y, a.z - b.z);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static warp_Vector scale(float f, warp_Vector a)
// substracts 2 vectors
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static warp_Vector scale(float f, ref warp_Vector a)
{
return new warp_Vector(f * a.x, f * a.y, f * a.z);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float len(warp_Vector a)
// length of vector
{
return (float)Math.Sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
return MathF.Sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
}
/*
public static warp_Vector random(float fact)
// returns a random vector
{
return new warp_Vector(fact*warp_Math.random(),fact*warp_Math.random(),fact*warp_Math.random());
}
public String toString()
{
return new String ("<vector x="+x+" y="+y+" z="+z+">\r\n");
}
*/
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Vector getClone()
{
return new warp_Vector(x, y, z);
}
public static warp_Vector Zero = new();
}
}
+66 -74
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Warp3D
{
@@ -9,70 +10,64 @@ namespace Warp3D
/// </summary>
public class warp_Vertex
{
public warp_Object parent;
public warp_Object parent = null;
public warp_Vector pos = new warp_Vector(); //(x,y,z) Coordinate of vertex
public warp_Vector n = new warp_Vector(); //Normal Vector at vertex
public float u = 0; // Texture x-coordinate (relative)
public float v = 0; // Texture y-coordinate (relative)
public warp_Vector pos2; //Transformed vertex coordinate
public warp_Vector n2; //Transformed normal vector (camera space)
public int x; //Projected x coordinate
public int y; //Projected y coordinate
public int z; //Projected z coordinate for z-Buffer
public float tx = 0; // Texture x-coordinate (relative)
public float ty = 0; // Texture y-coordinate (relative)
public int nx = 0; // Normal x-coordinate for envmapping
public int ny = 0; // Normal y-coordinate for envmapping
public float invZ = 1.0f;
public bool visible = true; //visibility tag for clipping
public int clipcode = 0;
public warp_Vector pos; //(x,y,z) Coordinate of vertex
public warp_Vector n; //Normal at vertex
public float u; // Texture x-coordinate (relative)
public float v; // Texture y-coordinate (relative)
public int id; // Vertex index
//private Vector neighbor=new Vector(); //Neighbor triangles of vertex
private List<warp_Triangle> neighbor = new List<warp_Triangle>();
// projected data cache
public int x; //x coordinate
public int y; //y coordinate
public int z; //z coordinate for z-Buffer
public int nx; // Normal x-coordinate for envmapping
public int ny; // Normal y-coordinate for envmapping
public float invZ;
public int clipcode;
private readonly List<warp_Triangle> neighbor = new();
public warp_Vertex()
{
pos = new warp_Vector(0f, 0f, 0f);
pos = new(0f, 0f, 0f);
}
public warp_Vertex(float xpos, float ypos, float zpos)
{
pos = new warp_Vector(xpos, ypos, zpos);
pos = new(xpos, ypos, zpos);
}
public warp_Vertex(float xpos, float ypos, float zpos, float u, float v)
{
pos = new warp_Vector(xpos, ypos, zpos);
pos = new(xpos, ypos, zpos);
this.u = u;
this.v = v;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Vertex(warp_Vector ppos)
{
pos = ppos.getClone();
pos = ppos;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Vertex(warp_Vector ppos, float u, float v)
{
pos = ppos.getClone();
pos = ppos;
this.u = u;
this.v = v;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Vertex(warp_Vector ppos, warp_Vector norm, float u, float v)
{
pos = ppos.getClone();
n = norm.getClone();
pos = ppos;
n = norm;
this.u = u;
this.v = v;
}
@@ -80,66 +75,62 @@ namespace Warp3D
public void project(warp_Matrix vertexProjection, warp_Matrix normalProjection, warp_Camera camera)
// Projects this vertex into camera space
{
pos2 = pos.transform(vertexProjection);
n2 = n.transform(normalProjection);
if(pos2.z < 0.001f && pos2.z > -0.0001f)
warp_Vector pos2 = pos.transform(vertexProjection);
if (pos2.z < 0.001f && pos2.z > -0.0001f)
pos2.z = 0.001f;
if(camera.isOrthographic)
if (camera.isOrthographic)
{
x = (int)pos2.x;
y = (int)pos2.y;
invZ = -1.0f;
tx = -u;
ty = -v;
}
else
{
invZ = 1.0f / pos2.z;
x = (int)(pos2.x * invZ + camera.halfscreenwidth);
y = (int)(pos2.y * invZ + camera.halfscreenheight);
invZ = - invZ;
tx = u * invZ;
ty = v * invZ;
invZ = -invZ;
}
z = (int)(65536f * pos2.z);
nx = ((int)(n2.x * 127 + 127)) << 16;
ny = ((int)(n2.y * 127 + 127)) << 16;
n.transformToXY(normalProjection, out float nxf, out float nyf);
nx = ((int)(nxf * 127 + 127)) << 16;
ny = ((int)(nyf * 127 + 127)) << 16;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setUV(float u, float v)
{
this.u = u;
this.v = v;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void clipFrustrum(int w, int h)
{
// View plane clipping
clipcode = 0;
if(x < 0)
if (x < 0)
clipcode |= 1;
else if(x >= w)
else if (x >= w)
clipcode |= 2;
if(y < 0)
if (y < 0)
clipcode |= 4;
else if(y >= h)
else if (y >= h)
clipcode |= 8;
if(pos2.z < 0)
if (z < 0)
clipcode |= 16;
visible = (clipcode == 0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void registerNeighbor(warp_Triangle triangle)
{
if(!neighbor.Contains(triangle))
if (!neighbor.Contains(triangle))
neighbor.Add(triangle);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void resetNeighbors()
{
neighbor.Clear();
@@ -150,16 +141,15 @@ namespace Warp3D
float nx = 0;
float ny = 0;
float nz = 0;
for(int i = 0; i < neighbor.Count; ++i)
for (int i = 0; i < neighbor.Count; ++i)
{
warp_Triangle tri = neighbor[i];
warp_Vector wn = tri.rawNorm;
nx += wn.x;
ny += wn.y;
nz += wn.z;
nx += neighbor[i].n.x;
ny += neighbor[i].n.y;
nz += neighbor[i].n.z;
}
n = new warp_Vector(nx, ny, nz).normalize();
n = new warp_Vector(nx, ny, nz);
n.normalize();
}
/*
@@ -183,42 +173,44 @@ namespace Warp3D
n=new warp_Vector(nx,ny,nz).normalize();
}
*/
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void scaleTextureCoordinates(float fx, float fy)
{
u *= fx;
v *= fy;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void moveTextureCoordinates(float fx, float fy)
{
u += fx;
v += fy;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public warp_Vertex getClone()
{
warp_Vertex newVertex = new warp_Vertex();
newVertex.pos = pos.getClone();
newVertex.n = n.getClone();
newVertex.u = u;
newVertex.v = v;
warp_Vertex newVertex = new()
{
pos = pos,
n = n,
u = u,
v = v
};
return newVertex;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool equals(warp_Vertex v)
{
return ((pos.x == v.pos.x) && (pos.y == v.pos.y) && (pos.z == v.pos.z));
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool equals(warp_Vertex v, float tolerance)
{
return Math.Abs(warp_Vector.sub(pos, v.pos).length()) < tolerance;
return warp_Vector.sub(ref pos, ref v.pos).lengthSquare() < tolerance * tolerance;
}
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
using System.Runtime.InteropServices;
using System.Reflection;
[assembly: AssemblyVersion("1.10.0.2")]
[assembly: AssemblyVersion("1.10.0.4")]
[assembly: AssemblyTitle("XmlRpc Opensim")]
[assembly: AssemblyCompany("Ronin Consulting Inc, OpenSimulator")]
[assembly: AssemblyDescription("XML RPC client and server")]
+1 -2
View File
@@ -40,8 +40,7 @@ namespace Nwc.XmlRpc
///<param name="level">The <c>LogLevel</c> of your message.</param>
static public void WriteEntry(String message,LogLevel level)
{
if(Delegate != null)
Delegate(message,level);
Delegate?.Invoke(message, level);
}
}
}
+33 -24
View File
@@ -16,9 +16,9 @@ namespace Nwc.XmlRpc
private String _filePathFile = null;
private String _filePathDir = null;
private String __filePath;
private TcpClient _client;
private StreamReader _input;
private StreamWriter _output;
private readonly TcpClient _client;
private readonly StreamReader _input;
private readonly StreamWriter _output;
private Hashtable _headers;
/// <summary>A constructor which accepts the TcpClient.</summary>
@@ -107,16 +107,16 @@ namespace Nwc.XmlRpc
{
get
{
if(_filePathFile != null)
if(_filePathFile is not null)
return _filePathFile;
int i = FilePath.LastIndexOf("/");
int i = FilePath.LastIndexOf('/');
if(i == -1)
return "";
i++;
_filePathFile = FilePath.Substring(i,FilePath.Length - i);
_filePathFile = FilePath[i..];
return _filePathFile;
}
}
@@ -126,16 +126,15 @@ namespace Nwc.XmlRpc
{
get
{
if(_filePathDir != null)
if(_filePathDir is not null)
return _filePathDir;
int i = FilePath.LastIndexOf("/");
int i = FilePath.LastIndexOf('/');
if(i == -1)
return "";
i++;
_filePathDir = FilePath.Substring(0,i);
_filePathDir = FilePath[..i];
return _filePathDir;
}
}
@@ -143,28 +142,38 @@ namespace Nwc.XmlRpc
private void GetRequestMethod()
{
string req = _input.ReadLine();
if(req == null)
if(req is null)
throw new ApplicationException("Void request.");
var sreq = req.AsSpan();
if(0 == String.Compare("GET ",req.Substring(0,4),true))
if(sreq.StartsWith("GET "))
{
_httpMethod = "GET";
else if(0 == String.Compare("POST ",req.Substring(0,5),true))
sreq = sreq[5..];
}
else if(sreq.StartsWith("POST "))
{
_httpMethod = "POST";
sreq = sreq[6..];
}
else
throw new InvalidOperationException("Unrecognized method in query: " + req);
req = req.TrimEnd();
int idx = req.IndexOf(' ') + 1;
if(idx >= req.Length)
sreq = sreq.TrimEnd();
if(sreq.Length == 0)
throw new ApplicationException("What do you want?");
string page_protocol = req.Substring(idx);
int idx2 = page_protocol.IndexOf(' ');
int idx2 = sreq.IndexOf(' ');
if(idx2 == -1)
idx2 = page_protocol.Length;
_filePath = page_protocol.Substring(0,idx2).Trim();
_protocol = page_protocol.Substring(idx2).Trim();
{
_filePath = sreq.ToString();
_protocol = string.Empty;
}
else
{
_filePath = sreq[..idx2].Trim().ToString();
_protocol = sreq[idx2..].Trim().ToString();
}
}
private void GetRequestHeaders()
@@ -188,8 +197,8 @@ namespace Nwc.XmlRpc
continue;
}
String key = line.Substring(0,idx);
String value = line.Substring(idx + 1);
String key = line[..idx];
String value = line[(idx + 1)..];
try
{
+5 -3
View File
@@ -43,9 +43,11 @@ namespace Nwc.XmlRpc
ArrayList reqArray = new ArrayList();
foreach(XmlRpcRequest request in Requests)
{
Hashtable requestEntry = new Hashtable();
requestEntry.Add(XmlRpcXmlTokens.METHOD_NAME,request.MethodName);
requestEntry.Add(XmlRpcXmlTokens.PARAMS,request.Params);
Hashtable requestEntry = new Hashtable
{
{ XmlRpcXmlTokens.METHOD_NAME, request.MethodName },
{ XmlRpcXmlTokens.PARAMS, request.Params }
};
reqArray.Add(requestEntry);
}
_params.Add(reqArray);
+10 -30
View File
@@ -21,7 +21,7 @@ namespace Nwc.XmlRpc
/// but is designed to be subclassed.</remarks>
public class XmlRpcDeserializer:XmlRpcXmlTokens
{
private static DateTimeFormatInfo _dateFormat = new DateTimeFormatInfo();
private readonly static DateTimeFormatInfo _dateFormat = new();
private object _container;
private Stack _containerStack;
@@ -58,7 +58,7 @@ namespace Nwc.XmlRpc
switch(reader.NodeType)
{
case XmlNodeType.Element:
if(Logger.Delegate != null)
if(Logger.Delegate is not null)
Logger.WriteEntry("START " + reader.Name,LogLevel.Information);
switch(reader.Name)
{
@@ -77,13 +77,13 @@ namespace Nwc.XmlRpc
}
break;
case XmlNodeType.EndElement:
if(Logger.Delegate != null)
if(Logger.Delegate is not null)
Logger.WriteEntry("END " + reader.Name,LogLevel.Information);
switch(reader.Name)
{
case BASE64:
if(string.IsNullOrEmpty(_text))
_value = new byte[0];
_value = Array.Empty<byte>();
else
_value = Convert.FromBase64String(_text);
break;
@@ -105,25 +105,19 @@ namespace Nwc.XmlRpc
_value = Int32.Parse(_text);
break;
case DATETIME:
#if __MONO__
_value = DateParse(_text);
#else
_value = DateTime.ParseExact(_text,"F",_dateFormat);
#endif
break;
case NAME:
_name = _text;
break;
case VALUE:
if(_value == null)
_value = _text; // some kits don't use <string> tag, they just do <value>
if((_container != null) && (_container is IList)) // in an array? If so add value to it.
((IList)_container).Add(_value);
_value ??= _text; // some kits don't use <string> tag, they just do <value>
if(_container is IList cnt) // in an array? If so add value to it.
cnt.Add(_value);
break;
case MEMBER:
if((_container != null) && (_container is IDictionary)) // in an struct? If so add value to it.
((IDictionary)_container).Add(_name,_value);
if(_container is IDictionary icnt) // in an struct? If so add value to it.
icnt.Add(_name,_value);
break;
case ARRAY:
case STRUCT:
@@ -133,7 +127,7 @@ namespace Nwc.XmlRpc
}
break;
case XmlNodeType.Text:
if(Logger.Delegate != null)
if(Logger.Delegate is not null)
Logger.WriteEntry("Text " + reader.Value,LogLevel.Information);
_text = reader.Value;
break;
@@ -179,20 +173,6 @@ namespace Nwc.XmlRpc
_container = null;
_containerStack = new Stack();
}
#if __MONO__
private DateTime DateParse(String str)
{
int year = Int32.Parse(str.Substring(0,4));
int month = Int32.Parse(str.Substring(4,2));
int day = Int32.Parse(str.Substring(6,2));
int hour = Int32.Parse(str.Substring(9,2));
int min = Int32.Parse(str.Substring(12,2));
int sec = Int32.Parse(str.Substring(15,2));
return new DateTime(year,month,day,hour,min,sec);
}
#endif
}
}
+2 -2
View File
@@ -7,7 +7,7 @@ namespace Nwc.XmlRpc
/// include a message so this adds the code needed by XML-RPC.</remarks>
public class XmlRpcException:Exception
{
private int _code;
private readonly int _code;
/// <summary>Instantiate an <c>XmlRpcException</c> with a code and message.</summary>
/// <param name="code"><c>Int</c> faultCode associated with this exception.</param>
@@ -38,7 +38,7 @@ namespace Nwc.XmlRpc
/// <summary>Format the message to include the code.</summary>
override public String ToString()
{
return "Code: " + FaultCode + " Message: " + base.ToString();
return $"Code: {FaultCode} Message: {base.ToString()}";
}
}
}
@@ -35,7 +35,7 @@ namespace Nwc.XmlRpc
Type type = obj.GetType();
MethodInfo method = type.GetMethod(methodName);
if(method == null)
if(method is null)
throw new MissingMethodException("Method " + methodName + " not found.");
if(!IsExposed(type))
+79 -9
View File
@@ -5,6 +5,10 @@ using System.Xml;
using System.Net;
using System.Net.Security;
using System.Text;
using System.Net.Http;
using System.Threading;
using System.Linq;
using System.Threading.Tasks;
namespace Nwc.XmlRpc
{
@@ -12,9 +16,9 @@ namespace Nwc.XmlRpc
public class XmlRpcRequest
{
private string m_methodName = null;
private Encoding m_encoding = new UTF8Encoding();
private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer();
private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer();
private readonly Encoding m_encoding = new UTF8Encoding();
private readonly XmlRpcRequestSerializer _serializer = new();
private readonly XmlRpcResponseDeserializer _deserializer = new();
/// <summary><c>ArrayList</c> containing the parameters.</summary>
protected IList _params = null;
@@ -67,12 +71,12 @@ namespace Nwc.XmlRpc
{
get
{
int index = MethodName.IndexOf(".");
int index = MethodName.IndexOf('.');
if (index == -1)
return MethodName;
return MethodName.Substring(0, index);
return MethodName[..index];
}
}
@@ -81,12 +85,12 @@ namespace Nwc.XmlRpc
{
get
{
int index = MethodName.IndexOf(".");
int index = MethodName.IndexOf('.');
if (index == -1)
return MethodName;
return MethodName.Substring(index + 1, MethodName.Length - index - 1);
return MethodName.Substring(index + 1);
}
}
@@ -94,6 +98,16 @@ namespace Nwc.XmlRpc
/// <param name="url"><c>String</c> The url of the XML-RPC server.</param>
/// <returns><c>Object</c> The value returned from the method invocation on the server.</returns>
/// <exception cref="XmlRpcException">If an exception generated on the server side.</exception>
public object Invoke(string url, HttpClient client)
{
XmlRpcResponse res = Send(url, client);
if (res.IsFault)
throw new XmlRpcException(res.FaultCode, res.FaultString);
return res.Value;
}
public object Invoke(string url, RemoteCertificateValidationCallback certCallBack = null)
{
XmlRpcResponse res = Send(url, 100000, certCallBack);
@@ -121,7 +135,7 @@ namespace Nwc.XmlRpc
request.ServerCertificateValidationCallback = certCallBack;
using (Stream stream = request.GetRequestStream())
using (XmlTextWriter xml = new XmlTextWriter(stream, m_encoding))
using (XmlTextWriter xml = new(stream, m_encoding))
{
_serializer.Serialize(xml, this);
xml.Flush();
@@ -129,11 +143,67 @@ namespace Nwc.XmlRpc
XmlRpcResponse resp;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (StreamReader input = new StreamReader(response.GetResponseStream()))
using (StreamReader input = new(response.GetResponseStream()))
resp = (XmlRpcResponse)_deserializer.Deserialize(input);
return resp;
}
public XmlRpcResponse Send(string url, HttpClient client)
{
HttpResponseMessage responseMessage = null;
HttpRequestMessage request = null;
try
{
request = new(HttpMethod.Post, url);
request.Headers.ExpectContinue = false;
request.Headers.TransferEncodingChunked = false;
//if (keepalive)
{
request.Headers.TryAddWithoutValidation("Keep-Alive", "timeout=30, max=10");
request.Headers.TryAddWithoutValidation("Connection", "Keep-Alive");
}
//else
// request.Headers.TryAddWithoutValidation("Connection", "close");
byte[] outbuf;
using (MemoryStream outbufms = new())
using (XmlTextWriter xml = new(outbufms, m_encoding))
{
_serializer.Serialize(xml, this);
xml.Flush();
outbuf = outbufms.ToArray();
}
request.Content = new ByteArrayContent(outbuf);
request.Content.Headers.TryAddWithoutValidation("Content-Type", "text/xml");
request.Content.Headers.TryAddWithoutValidation("Content-Length", outbuf.Length.ToString());
responseMessage = client.Send(request, HttpCompletionOption.ResponseHeadersRead);
responseMessage.EnsureSuccessStatusCode();
XmlRpcResponse resp;
using (StreamReader input = new(responseMessage.Content.ReadAsStream()))
resp = (XmlRpcResponse)_deserializer.Deserialize(input);
return resp;
}
catch (WebException ex) when (ex.Status is WebExceptionStatus.Timeout)
{
throw new HttpRequestException("request timeout");
}
//catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException)
catch (TaskCanceledException)
{
throw new HttpRequestException("request timeout");
}
finally
{
request?.Dispose();
responseMessage?.Dispose();
}
}
/// <summary>Produce <c>String</c> representation of the object.</summary>
/// <returns><c>String</c> representation of the object.</returns>
override public string ToString()
@@ -14,9 +14,7 @@ namespace Nwc.XmlRpc
{
get
{
if(_singleton == null)
_singleton = new XmlRpcRequestDeserializer();
_singleton ??= new XmlRpcRequestDeserializer();
return _singleton;
}
}
@@ -26,10 +24,10 @@ namespace Nwc.XmlRpc
/// <returns><c>XmlRpcRequest</c> object resulting from the parse.</returns>
override public Object Deserialize(TextReader xmlData)
{
using(XmlTextReader reader = new XmlTextReader(xmlData))
using(XmlTextReader reader = new(xmlData))
{
reader.DtdProcessing = DtdProcessing.Ignore;
XmlRpcRequest request = new XmlRpcRequest(reader.Encoding);
XmlRpcRequest request = new(reader.Encoding);
bool done = false;
lock(this)
@@ -16,9 +16,7 @@ namespace Nwc.XmlRpc
{
get
{
if(_singleton == null)
_singleton = new XmlRpcRequestSerializer();
_singleton ??= new XmlRpcRequestSerializer();
return _singleton;
}
}
+8 -8
View File
@@ -12,9 +12,9 @@ namespace Nwc.XmlRpc
/// side dialog. Namely they manage an inbound deserializer and an outbound serializer. </remarks>
public class XmlRpcResponder
{
private XmlRpcRequestDeserializer _deserializer = new XmlRpcRequestDeserializer();
private XmlRpcResponseSerializer _serializer = new XmlRpcResponseSerializer();
private XmlRpcServer _server;
private readonly XmlRpcRequestDeserializer _deserializer = new();
private readonly XmlRpcResponseSerializer _serializer = new();
private readonly XmlRpcServer _server;
private TcpClient _client;
private SimpleHttpRequest _httpReq;
@@ -58,7 +58,7 @@ namespace Nwc.XmlRpc
public void Respond(SimpleHttpRequest httpReq)
{
XmlRpcRequest xmlRpcReq = (XmlRpcRequest)_deserializer.Deserialize(httpReq.Input);
XmlRpcResponse xmlRpcResp = new XmlRpcResponse();
XmlRpcResponse xmlRpcResp = new();
try
{
@@ -74,12 +74,12 @@ namespace Nwc.XmlRpc
XmlRpcErrorCodes.APPLICATION_ERROR_MSG + ": " + e2.Message);
}
if(Logger.Delegate != null)
if(Logger.Delegate is not null)
Logger.WriteEntry(xmlRpcResp.ToString(),LogLevel.Information);
XmlRpcServer.HttpHeader(httpReq.Protocol,"text/xml",0," 200 OK",httpReq.Output);
httpReq.Output.Flush();
using(XmlTextWriter xml = new XmlTextWriter(httpReq.Output))
using(XmlTextWriter xml = new(httpReq.Output))
{
_serializer.Serialize(xml, xmlRpcResp);
xml.Flush();
@@ -90,13 +90,13 @@ namespace Nwc.XmlRpc
///<summary>Close all contained resources, both the HttpReq and client.</summary>
public void Close()
{
if(_httpReq != null)
if(_httpReq is not null)
{
_httpReq.Close();
_httpReq = null;
}
if(_client != null)
if(_client is not null)
{
_client.Close();
_client = null;
+5 -3
View File
@@ -69,9 +69,11 @@ namespace Nwc.XmlRpc
/// <param name="message"><c>String</c> the faultString value.</param>
public void SetFault(int code,String message)
{
Hashtable fault = new Hashtable();
fault.Add("faultCode",code);
fault.Add("faultString",message);
Hashtable fault = new()
{
{ "faultCode", code },
{ "faultString", message }
};
Value = fault;
IsFault = true;
}
@@ -18,9 +18,7 @@ namespace Nwc.XmlRpc
{
get
{
if(_singleton == null)
_singleton = new XmlRpcResponseDeserializer();
_singleton ??= new XmlRpcResponseDeserializer();
return _singleton;
}
}
@@ -30,10 +28,10 @@ namespace Nwc.XmlRpc
/// <returns><c>XmlRpcResponse</c> object resulting from the parse.</returns>
override public Object Deserialize(TextReader xmlData)
{
using(XmlTextReader reader = new XmlTextReader(xmlData))
using(XmlTextReader reader = new(xmlData))
{
reader.DtdProcessing = DtdProcessing.Ignore;
XmlRpcResponse response = new XmlRpcResponse();
XmlRpcResponse response = new();
bool done = false;
lock(this)
@@ -16,9 +16,7 @@ namespace Nwc.XmlRpc
{
get
{
if(_singleton == null)
_singleton = new XmlRpcResponseSerializer();
_singleton ??= new XmlRpcResponseSerializer();
return _singleton;
}
}
+19 -25
View File
@@ -13,7 +13,7 @@ namespace Nwc.XmlRpc
/// <seealso cref="XmlRpcXmlTokens"/>
public class XmlRpcSerializer : XmlRpcXmlTokens
{
private Encoding m_encoding = new UTF8Encoding();
private readonly Encoding m_encoding = new UTF8Encoding();
/// <summary>Serialize the <c>XmlRpcRequest</c> to the output stream.</summary>
/// <param name="output">An <c>XmlTextWriter</c> stream to write data to.</param>
/// <param name="obj">An <c>Object</c> to serialize.</param>
@@ -30,17 +30,13 @@ namespace Nwc.XmlRpc
/// <seealso cref="XmlRpcRequest"/>
public String Serialize(Object obj)
{
using (MemoryStream ms = new MemoryStream(1024))
{
using (XmlTextWriter xml = new XmlTextWriter(ms, m_encoding))
{
xml.Formatting = Formatting.Indented;
xml.Indentation = 4;
Serialize(xml, obj);
xml.Flush();
return m_encoding.GetString(ms.ToArray());
}
}
using MemoryStream ms = new(1024);
using XmlTextWriter xml = new(ms, m_encoding);
xml.Formatting = Formatting.Indented;
xml.Indentation = 4;
Serialize(xml, obj);
xml.Flush();
return m_encoding.GetString(ms.ToArray());
}
/// <remarks>Serialize the object to the output stream.</remarks>
@@ -48,12 +44,11 @@ namespace Nwc.XmlRpc
/// <param name="obj">An <c>Object</c> to serialize.</param>
public void SerializeObject(XmlTextWriter output, Object obj)
{
if (obj == null)
if (obj is null)
return;
if (obj is byte[])
if (obj is byte[] ba)
{
byte[] ba = (byte[])obj;
output.WriteStartElement(BASE64);
output.WriteBase64(ba, 0, ba.Length);
output.WriteEndElement();
@@ -66,25 +61,25 @@ namespace Nwc.XmlRpc
{
output.WriteElementString(INT, obj.ToString());
}
else if (obj is DateTime)
else if (obj is DateTime dt)
{
output.WriteElementString(DATETIME, ((DateTime)obj).ToString(ISO_DATETIME));
output.WriteElementString(DATETIME, dt.ToString(ISO_DATETIME));
}
else if (obj is Double)
else if (obj is Double dbl)
{
output.WriteElementString(DOUBLE, ((Double)obj).ToString(CultureInfo.InvariantCulture));
output.WriteElementString(DOUBLE, dbl.ToString(CultureInfo.InvariantCulture));
}
else if (obj is Boolean)
else if (obj is Boolean bl)
{
output.WriteElementString(BOOLEAN, ((((Boolean)obj) == true) ? "1" : "0"));
output.WriteElementString(BOOLEAN, bl == true ? "1" : "0");
}
else if (obj is IList)
else if (obj is IList lst)
{
output.WriteStartElement(ARRAY);
output.WriteStartElement(DATA);
if (((ArrayList)obj).Count > 0)
{
foreach (Object member in ((IList)obj))
foreach (Object member in lst)
{
output.WriteStartElement(VALUE);
SerializeObject(output, member);
@@ -94,9 +89,8 @@ namespace Nwc.XmlRpc
output.WriteEndElement();
output.WriteEndElement();
}
else if (obj is IDictionary)
else if (obj is IDictionary h)
{
IDictionary h = (IDictionary)obj;
output.WriteStartElement(STRUCT);
foreach (String key in h.Keys)
{
+247 -244
View File
@@ -1,251 +1,254 @@
namespace Nwc.XmlRpc
{
using System;
using System.Collections;
using System.Reflection;
using System;
using System.Collections;
using System.Reflection;
/// <summary> XML-RPC System object implementation of extended specifications.</summary>
[XmlRpcExposed]
public class XmlRpcSystemObject
{
private XmlRpcServer _server;
static private IDictionary _methodHelp = new Hashtable();
/// <summary> XML-RPC System object implementation of extended specifications.</summary>
[XmlRpcExposed]
public class XmlRpcSystemObject
{
private readonly XmlRpcServer _server;
static private readonly IDictionary _methodHelp = new Hashtable();
/// <summary>Static <c>IDictionary</c> to hold mappings of method name to associated documentation String</summary>
static public IDictionary MethodHelp
{
get { return _methodHelp; }
}
/// <summary>Constructor.</summary>
/// <param name="server"><c>XmlRpcServer</c> server to be the system object for.</param>
public XmlRpcSystemObject(XmlRpcServer server)
{
_server = server;
server.Add("system", this);
_methodHelp.Add(this.GetType().FullName + ".methodHelp", "Return a string description.");
}
/// <summary>Invoke a method on a given object.</summary>
/// <remarks>Using reflection, and respecting the <c>XmlRpcExposed</c> attribute,
/// invoke the <paramref>methodName</paramref> method on the <paramref>target</paramref>
/// instance with the <paramref>parameters</paramref> provided. All this packages other <c>Invoke</c> methods
/// end up calling this.</remarks>
/// <returns><c>Object</c> the value the invoked method returns.</returns>
/// <exception cref="XmlRpcException">If method does not exist, is not exposed, parameters invalid, or invocation
/// results in an exception. Note, the <c>XmlRpcException.Code</c> will indicate cause.</exception>
static public Object Invoke(Object target, String methodName, IList parameters)
{
if (target is null)
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": Invalid target object.");
Type type = target.GetType();
MethodInfo method = type.GetMethod(methodName);
try
{
if (!XmlRpcExposedAttribute.ExposedMethod(target, methodName))
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": Method " + methodName + " is not exposed.");
}
catch (MissingMethodException me)
{
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": " + me.Message);
}
Object[] args = new Object[parameters.Count];
int index = 0;
foreach (Object arg in parameters)
{
args[index] = arg;
index++;
}
try
{
Object retValue = method.Invoke(target, args);
if (retValue is null)
throw new XmlRpcException(XmlRpcErrorCodes.APPLICATION_ERROR,
XmlRpcErrorCodes.APPLICATION_ERROR_MSG + ": Method returned NULL.");
return retValue;
}
catch (XmlRpcException e)
{
throw e;
}
catch (ArgumentException ae)
{
Logger.WriteEntry(XmlRpcErrorCodes.SERVER_ERROR_PARAMS_MSG + ": " + ae.Message,
LogLevel.Information);
String call = methodName + "( ";
foreach (Object o in args)
{
call += o.GetType().Name;
call += " ";
}
call += ")";
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_PARAMS,
XmlRpcErrorCodes.SERVER_ERROR_PARAMS_MSG + ": Arguement type mismatch invoking " + call);
}
catch (TargetParameterCountException tpce)
{
Logger.WriteEntry(XmlRpcErrorCodes.SERVER_ERROR_PARAMS_MSG + ": " + tpce.Message,
LogLevel.Information);
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_PARAMS,
XmlRpcErrorCodes.SERVER_ERROR_PARAMS_MSG + ": Arguement count mismatch invoking " + methodName);
}
catch (TargetInvocationException tie)
{
throw new XmlRpcException(XmlRpcErrorCodes.APPLICATION_ERROR,
XmlRpcErrorCodes.APPLICATION_ERROR_MSG + " Invoked method " + methodName + ": " + tie.Message);
}
}
/// <summary>List methods available on all handlers of this server.</summary>
/// <returns><c>IList</c> An array of <c>Strings</c>, each <c>String</c> will have form "object.method".</returns>
[XmlRpcExposed]
public IList listMethods()
{
IList methods = new ArrayList();
Boolean considerExposure;
foreach (DictionaryEntry handlerEntry in _server)
{
considerExposure = XmlRpcExposedAttribute.IsExposed(handlerEntry.Value.GetType());
foreach (MemberInfo mi in handlerEntry.Value.GetType().GetMembers())
{
if (mi.MemberType != MemberTypes.Method)
continue;
if (!((MethodInfo)mi).IsPublic)
continue;
if (considerExposure && !XmlRpcExposedAttribute.IsExposed(mi))
continue;
methods.Add(handlerEntry.Key + "." + mi.Name);
}
}
return methods;
}
/// <summary>Given a method name return the possible signatures for it.</summary>
/// <param name="name"><c>String</c> The object.method name to look up.</param>
/// <returns><c>IList</c> Of arrays of signatures.</returns>
[XmlRpcExposed]
public IList methodSignature(String name)
{
IList signatures = new ArrayList();
int index = name.IndexOf('.');
if (index < 0)
return signatures;
String oName = name[..index];
Object obj = _server[oName];
if (obj is null)
return signatures;
MemberInfo[] mi = obj.GetType().GetMember(name[(index + 1)..]);
if (mi is null || mi.Length != 1) // for now we want a single signature
return signatures;
MethodInfo method;
try
{
method = (MethodInfo)mi[0];
}
catch (Exception e)
{
Logger.WriteEntry("Attempted methodSignature call on " + mi[0] + " caused: " + e,
LogLevel.Information);
return signatures;
}
if (!method.IsPublic)
return signatures;
IList signature = new ArrayList
{
method.ReturnType.Name
};
foreach (ParameterInfo param in method.GetParameters())
{
signature.Add(param.ParameterType.Name);
}
signatures.Add(signature);
return signatures;
}
/// <summary>Help for given method signature. Not implemented yet.</summary>
/// <param name="name"><c>String</c> The object.method name to look up.</param>
/// <returns><c>String</c> help text. Rich HTML text.</returns>
[XmlRpcExposed]
public String methodHelp(String name)
{
String help = null;
try
{
help = (String)_methodHelp[_server.MethodName(name)];
}
catch (XmlRpcException e)
{
throw e;
}
catch (Exception) { /* ignored */ };
help ??= "No help available for: " + name;
return help;
}
/// <summary>Boxcarring support method.</summary>
/// <param name="calls"><c>IList</c> of calls</param>
/// <returns><c>ArrayList</c> of results/faults.</returns>
[XmlRpcExposed]
public IList multiCall(IList calls)
{
IList responses = new ArrayList();
XmlRpcResponse fault = new();
foreach (IDictionary call in calls)
{
try
{
XmlRpcRequest req = new((String)call[XmlRpcXmlTokens.METHOD_NAME], (ArrayList)call[XmlRpcXmlTokens.PARAMS]);
Object results = _server.Invoke(req);
IList response = new ArrayList
{
results
};
responses.Add(response);
}
catch (XmlRpcException e)
{
fault.SetFault(e.FaultCode, e.FaultString);
responses.Add(fault.Value);
}
catch (Exception e2)
{
fault.SetFault(XmlRpcErrorCodes.APPLICATION_ERROR,
XmlRpcErrorCodes.APPLICATION_ERROR_MSG + ": " + e2.Message);
responses.Add(fault.Value);
}
}
return responses;
}
/// <summary>Static <c>IDictionary</c> to hold mappings of method name to associated documentation String</summary>
static public IDictionary MethodHelp {
get { return _methodHelp; }
}
/// <summary>Constructor.</summary>
/// <param name="server"><c>XmlRpcServer</c> server to be the system object for.</param>
public XmlRpcSystemObject(XmlRpcServer server)
{
_server = server;
server.Add("system",this);
_methodHelp.Add(this.GetType().FullName + ".methodHelp", "Return a string description.");
}
/// <summary>Invoke a method on a given object.</summary>
/// <remarks>Using reflection, and respecting the <c>XmlRpcExposed</c> attribute,
/// invoke the <paramref>methodName</paramref> method on the <paramref>target</paramref>
/// instance with the <paramref>parameters</paramref> provided. All this packages other <c>Invoke</c> methods
/// end up calling this.</remarks>
/// <returns><c>Object</c> the value the invoked method returns.</returns>
/// <exception cref="XmlRpcException">If method does not exist, is not exposed, parameters invalid, or invocation
/// results in an exception. Note, the <c>XmlRpcException.Code</c> will indicate cause.</exception>
static public Object Invoke(Object target, String methodName, IList parameters)
{
if (target == null)
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": Invalid target object.");
Type type = target.GetType();
MethodInfo method = type.GetMethod(methodName);
try
{
if (!XmlRpcExposedAttribute.ExposedMethod(target,methodName))
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": Method " + methodName + " is not exposed.");
}
catch (MissingMethodException me)
{
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": " + me.Message);
}
Object[] args = new Object[parameters.Count];
int index = 0;
foreach (Object arg in parameters)
{
args[index] = arg;
index++;
}
try
{
Object retValue = method.Invoke(target, args);
if (retValue == null)
throw new XmlRpcException(XmlRpcErrorCodes.APPLICATION_ERROR,
XmlRpcErrorCodes.APPLICATION_ERROR_MSG + ": Method returned NULL.");
return retValue;
}
catch (XmlRpcException e)
{
throw e;
}
catch (ArgumentException ae)
{
Logger.WriteEntry(XmlRpcErrorCodes.SERVER_ERROR_PARAMS_MSG + ": " + ae.Message,
LogLevel.Information);
String call = methodName + "( ";
foreach (Object o in args)
{
call += o.GetType().Name;
call += " ";
}
call += ")";
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_PARAMS,
XmlRpcErrorCodes.SERVER_ERROR_PARAMS_MSG + ": Arguement type mismatch invoking " + call);
}
catch (TargetParameterCountException tpce)
{
Logger.WriteEntry(XmlRpcErrorCodes.SERVER_ERROR_PARAMS_MSG + ": " + tpce.Message,
LogLevel.Information);
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_PARAMS,
XmlRpcErrorCodes.SERVER_ERROR_PARAMS_MSG + ": Arguement count mismatch invoking " + methodName);
}
catch (TargetInvocationException tie)
{
throw new XmlRpcException(XmlRpcErrorCodes.APPLICATION_ERROR,
XmlRpcErrorCodes.APPLICATION_ERROR_MSG + " Invoked method " + methodName + ": " + tie.Message);
}
}
/// <summary>List methods available on all handlers of this server.</summary>
/// <returns><c>IList</c> An array of <c>Strings</c>, each <c>String</c> will have form "object.method".</returns>
[XmlRpcExposed]
public IList listMethods()
{
IList methods = new ArrayList();
Boolean considerExposure;
foreach (DictionaryEntry handlerEntry in _server)
{
considerExposure = XmlRpcExposedAttribute.IsExposed(handlerEntry.Value.GetType());
foreach (MemberInfo mi in handlerEntry.Value.GetType().GetMembers())
{
if (mi.MemberType != MemberTypes.Method)
continue;
if(!((MethodInfo)mi).IsPublic)
continue;
if (considerExposure && !XmlRpcExposedAttribute.IsExposed(mi))
continue;
methods.Add(handlerEntry.Key + "." + mi.Name);
}
}
return methods;
}
/// <summary>Given a method name return the possible signatures for it.</summary>
/// <param name="name"><c>String</c> The object.method name to look up.</param>
/// <returns><c>IList</c> Of arrays of signatures.</returns>
[XmlRpcExposed]
public IList methodSignature(String name)
{
IList signatures = new ArrayList();
int index = name.IndexOf('.');
if (index < 0)
return signatures;
String oName = name.Substring(0,index);
Object obj = _server[oName];
if (obj == null)
return signatures;
MemberInfo[] mi = obj.GetType().GetMember(name.Substring(index + 1));
if (mi == null || mi.Length != 1) // for now we want a single signature
return signatures;
MethodInfo method;
try
{
method = (MethodInfo)mi[0];
}
catch (Exception e)
{
Logger.WriteEntry("Attempted methodSignature call on " + mi[0] + " caused: " + e,
LogLevel.Information);
return signatures;
}
if (!method.IsPublic)
return signatures;
IList signature = new ArrayList();
signature.Add(method.ReturnType.Name);
foreach (ParameterInfo param in method.GetParameters())
{
signature.Add(param.ParameterType.Name);
}
signatures.Add(signature);
return signatures;
}
/// <summary>Help for given method signature. Not implemented yet.</summary>
/// <param name="name"><c>String</c> The object.method name to look up.</param>
/// <returns><c>String</c> help text. Rich HTML text.</returns>
[XmlRpcExposed]
public String methodHelp(String name)
{
String help = null;
try
{
help = (String)_methodHelp[_server.MethodName(name)];
}
catch (XmlRpcException e)
{
throw e;
}
catch (Exception) { /* ignored */ };
if (help == null)
help = "No help available for: " + name;
return help;
}
/// <summary>Boxcarring support method.</summary>
/// <param name="calls"><c>IList</c> of calls</param>
/// <returns><c>ArrayList</c> of results/faults.</returns>
[XmlRpcExposed]
public IList multiCall(IList calls)
{
IList responses = new ArrayList();
XmlRpcResponse fault = new XmlRpcResponse();
foreach (IDictionary call in calls)
{
try
{
XmlRpcRequest req = new XmlRpcRequest((String)call[XmlRpcXmlTokens.METHOD_NAME],
(ArrayList)call[XmlRpcXmlTokens.PARAMS]);
Object results = _server.Invoke(req);
IList response = new ArrayList();
response.Add(results);
responses.Add(response);
}
catch (XmlRpcException e)
{
fault.SetFault(e.FaultCode, e.FaultString);
responses.Add(fault.Value);
}
catch (Exception e2)
{
fault.SetFault(XmlRpcErrorCodes.APPLICATION_ERROR,
XmlRpcErrorCodes.APPLICATION_ERROR_MSG + ": " + e2.Message);
responses.Add(fault.Value);
}
}
return responses;
}
}
}
+8 -62
View File
@@ -1,71 +1,17 @@
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{678DEE13-A366-4130-9BCA-46F695640AD5}</ProjectGuid>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Library</OutputType>
<NoStandardLibraries>false</NoStandardLibraries>
<AssemblyName>XMLRPC</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>
</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<TieredCompilationQuickJit>false</TieredCompilationQuickJit>
<Optimize>True</Optimize>
</PropertyGroup>
<PropertyGroup>
<RootNamespace>xmlrpc</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Logger.cs" />
<Compile Include="SimpleHttpRequest.cs" />
<Compile Include="XmlRpcBoxcarRequest.cs" />
<Compile Include="XmlRpcClientProxy.cs" />
<Compile Include="XmlRpcDeserializer.cs" />
<Compile Include="XmlRpcErrorCodes.cs" />
<Compile Include="XmlRpcException.cs" />
<Compile Include="XmlRpcExposedAttribute.cs" />
<Compile Include="XmlRpcRequest.cs" />
<Compile Include="XmlRpcRequestDeserializer.cs" />
<Compile Include="XmlRpcRequestSerializer.cs" />
<Compile Include="XmlRpcResponder.cs" />
<Compile Include="XmlRpcResponse.cs" />
<Compile Include="XmlRpcResponseDeserializer.cs" />
<Compile Include="XmlRpcResponseSerializer.cs" />
<Compile Include="XmlRpcSerializer.cs" />
<Compile Include="XmlRpcServer.cs" />
<Compile Include="XmlRpcSystemObject.cs" />
<Compile Include="XmlRpcXmlTokens.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSHARP.Targets" />
<ProjectExtensions>
<VisualStudio AllowExistingFolder="true" />
</ProjectExtensions>
</Project>