Skip to content

Commit

Permalink
added Placeholder gizmo for nonmeshed Translokator Instances
Browse files Browse the repository at this point in the history
  • Loading branch information
Kozmeker committed Nov 25, 2024
1 parent 8f27ec4 commit 1fdff45
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 13 deletions.
49 changes: 37 additions & 12 deletions Mafia2Libs/Forms/MapEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1104,11 +1104,15 @@ private void BuildRenderObjects()

if (groupRef != null && hasMesh)
{
for (int i = 0; i < groupRef.Children.Count; i++)
for (int i = 0; i < groupRef.Children.Count; i++)//i dont think this for cycle is needed really if done right
{
InstanceTranslokatorPart(assets, groupRef.Children[i], Matrix4x4.Identity, instance);
}
}
else
{
Graphics.InstanceGizmo.InstanceTranslokator(instance);
}

TreeNode instanceNode = new TreeNode(obj.Name + " " + x);
instanceNode.Tag = instance;
Expand Down Expand Up @@ -1431,6 +1435,10 @@ private void ApplyEntryChanges(object sender, EventArgs e)
Graphics.UpdateInstanceBuffers(modelsToUpdate);
}
}
else
{
Graphics.InstanceGizmo.UpdateInstanceBuffer(instance, Graphics.GetId3D11Device());
}
}
}
}
Expand Down Expand Up @@ -1598,7 +1606,7 @@ private void Pick(int sx, int sy)
{
dSceneTree.SelectedNode = nodes[0];

if (dSceneTree.SelectedNode.Tag is FrameObjectBase obj)//dostat se na instance, ne na ref frame, od toho je jump, když na nějakej instance šáhnu, abych v tree viděl jakej to přesně je
if (dSceneTree.SelectedNode.Tag is FrameObjectBase obj)
{
int Parent1Index = obj.ParentIndex1.Index;
int Parent2Index = obj.ParentIndex2.Index;
Expand Down Expand Up @@ -1838,6 +1846,10 @@ private void OnPropertyValueChanged(object s, PropertyValueChangedEventArgs e)
Graphics.UpdateInstanceBuffers(modelsToUpdate);
}
}
else
{
Graphics.InstanceGizmo.UpdateInstanceBuffer(instance, Graphics.GetId3D11Device());
}
}

pGrid.Refresh();
Expand Down Expand Up @@ -2671,24 +2683,24 @@ private void TranslokatorNewInstance(TreeNode parentObj, Instance old)

Object parent = parentObj.Tag as Object;
FrameObjectBase frameref = SceneData.FrameResource.GetObjectByHash<FrameObjectBase>(parent.Name.Hash);
if (frameref != null && frameref.HasMeshObject())//todo nonframerefs solution once they are managed
if (frameref != null && frameref.HasMeshObject())
{
for (int i = 0; i < frameref.Children.Count; i++)
{
InstanceTranslokatorPart(Graphics.Assets, frameref.Children[i], Matrix4x4.Identity, newInstance,true);
}
}
else
{
Graphics.InstanceGizmo.InstanceTranslokator(newInstance,Graphics.GetId3D11Device());
}

dSceneTree.AddToTree(newInstanceNode,parentObj);
}

private void UpdateInstanceVisualisation(TreeNode instanceNode, Object trObject, bool visibility)
{
FrameObjectBase groupRef = SceneData.FrameResource.GetObjectByHash<FrameObjectBase>(trObject.Name.Hash);
if (groupRef == null)//todo: once placeholder is implemented, reword this to work with it
{
return;
}

Instance instance = instanceNode.Tag as Instance;
if (visibility)
Expand All @@ -2700,10 +2712,21 @@ private void UpdateInstanceVisualisation(TreeNode instanceNode, Object trObject,
InstanceTranslokatorPart(Graphics.Assets, groupRef.Children[i], Matrix4x4.Identity, instance,true);
}
}
else
{
Graphics.InstanceGizmo.InstanceTranslokator(instance,Graphics.GetId3D11Device());
}
}
else
{
Graphics.DeleteInstance(groupRef,instance.RefID);
if (groupRef != null && groupRef.HasMeshObject())
{
Graphics.DeleteInstance(groupRef,instance.RefID);
}
else
{
Graphics.DeleteInstance(instance.RefID);
}
}

}
Expand Down Expand Up @@ -2757,12 +2780,14 @@ private void DeleteTRInstance(TreeNode instanceNode)
Instance instance = instanceNode.Tag as Instance;
FrameObjectBase groupRef = SceneData.FrameResource.GetObjectByHash<FrameObjectBase>((instanceNode.Parent.Tag as Object).Name.Hash);
dSceneTree.RemoveNode(instanceNode);
if (groupRef == null)//todo: once placeholder is implemented, reword this to work with it
if (groupRef != null)
{
return;
Graphics.DeleteInstance(groupRef, instance.RefID);
}
else
{
Graphics.DeleteInstance(instance.RefID);
}

Graphics.DeleteInstance(groupRef, instance.RefID);
}

private void DeleteTRObject(TreeNode objectNode)
Expand Down
6 changes: 6 additions & 0 deletions Mafia2Libs/MafiaToolkit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@
<ItemGroup>
<None Remove="Localisations\ar_AR.xml" />
<None Remove="Rendering\Graphics\RenderTypes\Instances\**" />
<None Update="Resources\Translokator.m2t">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Resources\Translokator_Texture.dds">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<RuntimeHostConfigurationOption Include="SubdirectoriesToProbe" Value="\\libs\\" />
Expand Down
114 changes: 114 additions & 0 deletions Mafia2Libs/Rendering/Core/InstanceGizmo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using Rendering.Graphics;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using ResourceTypes.Translokator;
using Utils.Logging;
using Utils.VorticeUtils;
using Vortice.Direct3D;
using Vortice.Direct3D11;
using Vortice.Mathematics;

namespace Rendering.Core
{
public class InstanceGizmo
{

// Variable for rendering
public RenderModel InstanceModel;

public InstanceGizmo(RenderModel InModel)
{
InstanceModel = InModel;
}

public void InitBuffers(ID3D11Device d3d, ID3D11DeviceContext d3dContext)
{
InstanceModel.InitBuffers(d3d, d3dContext);//texture should be loaded either differently or rendersingleton should precache it
InstanceModel.AOTexture = LoadTexture(d3d, d3dContext);
}

public ID3D11ShaderResourceView LoadTexture(ID3D11Device d3d, ID3D11DeviceContext d3dContext)
{
try
{
ID3D11Resource ddsResource;
ID3D11ShaderResourceView _temp;
DDSTextureLoader.DDS_ALPHA_MODE mode;
DDSTextureLoader.CreateDDSTextureFromFile(d3d, d3dContext, "Resources/Translokator_Texture.dds", out ddsResource, out _temp, 4096, out mode);
return _temp;
}
catch
{
Log.WriteLine(string.Format("Failed to load file: {0}", "Resources/Translokator_Texture.dds"), LoggingTypes.FATAL, LogCategoryTypes.IO);
return null;
}
}

public void UpdateInstanceBuffer(Instance instance, ID3D11Device d3d)
{
Matrix4x4 newtransform = MatrixUtils.SetMatrix(instance.Quaternion, new Vector3(0.015f,0.015f,0.015f), instance.Position);

if (!InstanceModel.InstanceTransforms.ContainsKey(instance.RefID))
{
InstanceModel.InstanceTransforms.Add(instance.RefID, Matrix4x4.Transpose(newtransform));
}
else
{
InstanceModel.InstanceTransforms[instance.RefID] = Matrix4x4.Transpose(newtransform);
}

InstanceModel.ReloadInstanceBuffer(d3d);
}

public void UpdateBuffers(ID3D11Device d3d, ID3D11DeviceContext d3dContext)
{
InstanceModel.UpdateBuffers(d3d, d3dContext);
}

public void Render(ID3D11Device d3d, ID3D11DeviceContext d3dContext, Camera camera)//render only instances
{
if (InstanceModel.InstanceTransforms.Count > 0)
{
VertexBufferView VertexBufferView = new VertexBufferView(InstanceModel.GetVB(), Unsafe.SizeOf<VertexLayouts.NormalLayout.Vertex>(), 0);//polish so getib/vb doesnt have to be used
d3dContext.IASetVertexBuffers(0, VertexBufferView);
d3dContext.IASetIndexBuffer(InstanceModel.GetIB(), Vortice.DXGI.Format.R32_UInt, 0);
d3dContext.IASetPrimitiveTopology(PrimitiveTopology.TriangleList);
d3dContext.PSSetShaderResource(2, InstanceModel.AOTexture);

InstanceModel.RenderInstances(d3dContext, camera, d3d);
}
}

public void InstanceTranslokator(Instance instance,ID3D11Device device = null)
{
Matrix4x4 newtransform = new Matrix4x4();

newtransform = MatrixUtils.SetMatrix(instance.Quaternion, new Vector3(0.015f,0.015f,0.015f), instance.Position);//fbx to m2t enlarged the mesh so, beware gltf

if (!InstanceModel.InstanceTransforms.ContainsKey(instance.RefID))
{
InstanceModel.InstanceTransforms.Add(instance.RefID, Matrix4x4.Transpose(newtransform));
if (device!=null)
{
InstanceModel.ReloadInstanceBuffer(device);
}
}
}

public void Select(int InstanceId)
{
InstanceModel.SelectInstance(InstanceId);
}

public void Unselect()
{
InstanceModel.UnselectInstance();
}

public void Shutdown()
{
InstanceModel.Shutdown();
}
}
}
56 changes: 56 additions & 0 deletions Mafia2Libs/Rendering/Graphics/GraphicsClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class GraphicsClass
private RenderModel sky;
private RenderModel clouds;
private GizmoTool TranslationGizmo;
public InstanceGizmo InstanceGizmo;

private DirectX11Class D3D;

Expand Down Expand Up @@ -119,6 +120,13 @@ public bool PreInit(IntPtr WindowHandle)
clouds.ConvertMTKToRenderModel(structure);
clouds.InitBuffers(D3D.Device, D3D.DeviceContext);
clouds.DoRender = false;

RenderModel instancePlaceholder = new RenderModel();
structure = new M2TStructure();
structure.ReadFromM2T("Resources/Translokator.m2t");
instancePlaceholder.ConvertMTKToRenderModel(structure);
instancePlaceholder.InitBuffers(D3D.Device,D3D.DeviceContext);
InstanceGizmo = new InstanceGizmo(instancePlaceholder);
}

selectionBox.SetColour(System.Drawing.Color.Red);
Expand All @@ -140,6 +148,14 @@ public bool InitScene(int width, int height)
sky.InitBuffers(D3D.Device, D3D.DeviceContext);
sky.DoRender = WorldSettings.RenderSky;
clouds.InitBuffers(D3D.Device, D3D.DeviceContext);
InstanceGizmo.InitBuffers(D3D.Device, D3D.DeviceContext);
var task = InstanceGizmo.InstanceModel.GetBVHBuildingTask(); // Maybe this function should be added to the IRenderer class instead? probably

if (task != null)
{
BVHBuildingTasks.Add(task);
}

Input = new InputClass();
Input.Init();
return true;
Expand Down Expand Up @@ -283,6 +299,31 @@ public PickOutParams Pick(int sx, int sy, int Width, int Height)

index++;
}

foreach (var transform in InstanceGizmo.InstanceModel.InstanceTransforms)
{
var transposed = Matrix4x4.Transpose(transform.Value);

Matrix4x4 tvWM = Matrix4x4.Identity;
Matrix4x4.Invert(transposed, out tvWM);
var localInstanceRay = new Ray(
Vector3Utils.TransformCoordinate(ray.Position, tvWM),
Vector3.TransformNormal(ray.Direction, tvWM)
);

if (localInstanceRay.Intersects(InstanceGizmo.InstanceModel.BoundingBox) == 0.0f) continue;

var bvhInstanceIntersect = InstanceGizmo.InstanceModel.BVH.Intersect(localInstanceRay);

if (bvhInstanceIntersect.distance < lowest)
{
lowest = bvhInstanceIntersect.distance;
lowestRefID = -2;
lowestInstanceID = transform.Key;
WorldPosIntersect = bvhInstanceIntersect.pos;
}
}


PickOutParams OutputParams = new PickOutParams();
OutputParams.LowestRefID = lowestRefID;
Expand Down Expand Up @@ -398,6 +439,9 @@ public bool Render()
sky.DoRender = WorldSettings.RenderSky;
sky.UpdateBuffers(D3D.Device, D3D.DeviceContext);
sky.Render(D3D.Device, D3D.DeviceContext, Camera);
InstanceGizmo.UpdateBuffers(D3D.Device, D3D.DeviceContext);
InstanceGizmo.Render(D3D.Device, D3D.DeviceContext, Camera);


D3D.EndScene();
return true;
Expand Down Expand Up @@ -462,6 +506,7 @@ public void SelectEntry(int id)
}
selectedInstances.Clear();
}
InstanceGizmo.Unselect();

TranslationGizmo.OnSelectEntry(NewObject.Transform, true);
NewObject.Select();
Expand Down Expand Up @@ -489,6 +534,7 @@ public void SelectInstance(int instanceId)
}
selectedInstances.Clear();
}
InstanceGizmo.Unselect();

selectedInstances = new Dictionary<int, int>();

Expand All @@ -507,6 +553,11 @@ public void SelectInstance(int instanceId)
RenderModel model = Assets[selectedInstances.First().Key] as RenderModel;
TranslationGizmo.OnSelectEntry(Matrix4x4.Transpose(model.InstanceTransforms[selectedInstances.First().Value]) , true);
}
else
{
InstanceGizmo.Select(instanceId);
TranslationGizmo.OnSelectEntry(Matrix4x4.Transpose(InstanceGizmo.InstanceModel.InstanceTransforms[instanceId]) , true);
}
}

public IRenderer GetAsset(int RefID)
Expand Down Expand Up @@ -610,6 +661,7 @@ public void Shutdown()
D3D?.Shutdown();
D3D = null;
selectedInstances = null;
InstanceGizmo.Shutdown();
}


Expand Down Expand Up @@ -668,5 +720,9 @@ public void DeleteInstance(FrameObjectBase frame,int InstanceRefID)
}
}
}
public void DeleteInstance(int InstanceRefID)
{
InstanceGizmo.InstanceModel.RemoveInstance(InstanceRefID,D3D.Device);
}
}
}
11 changes: 10 additions & 1 deletion Mafia2Libs/Rendering/Graphics/RenderTypes/RenderModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ public override void Render(ID3D11Device device, ID3D11DeviceContext deviceConte

private float colorTransitionTime = 0.0f; // timer for distinguishing translokators

private void RenderInstances(ID3D11DeviceContext deviceContext, Camera camera, ID3D11Device device)
public void RenderInstances(ID3D11DeviceContext deviceContext, Camera camera, ID3D11Device device)
{
deviceContext.VSSetShaderResource(0, instanceBufferView);

Expand Down Expand Up @@ -544,5 +544,14 @@ public void RemoveInstance(int instanceRefId,ID3D11Device d3d)
ReloadInstanceBuffer(d3d);
}
}

public ID3D11Buffer GetVB()
{
return vertexBuffer;
}
public ID3D11Buffer GetIB()
{
return indexBuffer;
}
}
}
Binary file added Mafia2Libs/Resources/Translokator.m2t
Binary file not shown.
Binary file added Mafia2Libs/Resources/Translokator_Texture.dds
Binary file not shown.

0 comments on commit 1fdff45

Please sign in to comment.