mirror of
git://opensimulator.org/git/opensim-libs
synced 2026-08-14 00:58:00 +00:00
update warp3d and xmlrpc
This commit is contained in:
@@ -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.
+400
-575
File diff suppressed because it is too large
Load Diff
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,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")]
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user