Skip to content

Commit

Permalink
add mouse picking for selecting objects in 3d world (#45)
Browse files Browse the repository at this point in the history
* sync to latest version of ace physics

* add mouse picking for selecting objects in 3d world

* fix unicode char

* fix picking raw gfxobjs

* improved dungeon picking from out of bounds camera location

* update version info

* .
  • Loading branch information
gmriggs authored Jan 25, 2022
1 parent 45eaaab commit 486e59c
Show file tree
Hide file tree
Showing 26 changed files with 735 additions and 70 deletions.
3 changes: 3 additions & 0 deletions ACViewer/ACViewer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
<Compile Include="Entity\TMTerrainDesc.cs" />
<Compile Include="Enum\DatType.cs" />
<Compile Include="Enum\Facing.cs" />
<Compile Include="Enum\PickType.cs" />
<Compile Include="Enum\ModelType.cs" />
<Compile Include="Enum\ProfilerSection.cs" />
<Compile Include="Enum\ViewMode.cs" />
Expand Down Expand Up @@ -243,6 +244,7 @@
<Compile Include="Model\LandVertex.cs" />
<Compile Include="Model\Mesh.cs" />
<Compile Include="Model\ParticleDeclaration.cs" />
<Compile Include="Model\PickResult.cs" />
<Compile Include="Model\VertexInstanceEnv.cs" />
<Compile Include="Model\VertexPositionNormalTextures.cs" />
<Compile Include="ParticleViewer.cs" />
Expand Down Expand Up @@ -271,6 +273,7 @@
<Compile Include="Physics\Common\TextureMergeInfo.cs" />
<Compile Include="Physics\Common\TMTerrainDesc.cs" />
<Compile Include="Physics\Managers\ServerObjectManager.cs" />
<Compile Include="Picker.cs" />
<Compile Include="Render\Buffer.cs" />
<Compile Include="Render\ParticleBatch.cs" />
<Compile Include="Render\ParticleBatchDraw.cs" />
Expand Down
34 changes: 33 additions & 1 deletion ACViewer/Content/texture.fx
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ float4 ParticleInstanceTransPS(ParticleVertexShaderOutput input) : COLOR

// only output semi-transparent pixels
// also discard inactive particles
clip(color.a < 1.0f && color.a >= 0.03125f && input.OpacityActive.y > 0 ? 1 : -1);
clip(color.a < 1.0f && input.OpacityActive.y > 0 ? 1 : -1);

return color;
}
Expand All @@ -831,3 +831,35 @@ technique ParticleInstance
PixelShader = compile ps_4_0 ParticleInstanceTransPS();
}
}

//------- Technique: Picker --------

VertexPositionColor PickerVS(float4 inPos : SV_POSITION, float4 inColor : COLOR)
{
VertexPositionColor output = (VertexPositionColor)0;

output.Position = mul(mul(inPos, xView), xProjection);
output.Color = inColor;

return output;
}

PixelShaderOutput PickerPS(VertexPositionColor input)
{
PixelShaderOutput output = (PixelShaderOutput)0;

output.Color = input.Color;

return output;
}

technique Picker
{
pass Pass0
{
ZEnable = false;

VertexShader = compile vs_4_0 ColoredNoShadingVS();
PixelShader = compile ps_4_0 ColoredNoShadingPS();
}
}
Binary file modified ACViewer/Content/texture.mgfxo
Binary file not shown.
21 changes: 19 additions & 2 deletions ACViewer/Entity/LightInfo.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace ACViewer.Entity
using System.Collections.Generic;

namespace ACViewer.Entity
{
public class LightInfo
{
Expand All @@ -9,9 +11,24 @@ public LightInfo(ACE.DatLoader.Entity.LightInfo lightInfo)
_lightInfo = lightInfo;
}

public List<TreeNode> BuildTree()
{
var viewerSpaceLocation = new TreeNode($"Viewer space location: {_lightInfo.ViewerSpaceLocation}");

var color = new TreeNode($"Color: {Color.ToRGBA(_lightInfo.Color)}");

var intensity = new TreeNode($"Intensity: {_lightInfo.Intensity}");

var falloff = new TreeNode($"Falloff: {_lightInfo.Falloff}");

var coneAngle = new TreeNode($"ConeAngle: {_lightInfo.ConeAngle}");

return new List<TreeNode>() { viewerSpaceLocation, color, intensity, falloff, coneAngle };
}

public override string ToString()
{
return $"Viewer space location: {_lightInfo.ViewerSpaceLocation}, Color: {_lightInfo.Color}, Intensity: {_lightInfo.Intensity}, Falloff: {_lightInfo.Falloff}, ConeAngle: {_lightInfo.ConeAngle}";
return $"Viewer space location: {_lightInfo.ViewerSpaceLocation}, Color: {Color.ToRGBA(_lightInfo.Color)}, Intensity: {_lightInfo.Intensity}, Falloff: {_lightInfo.Falloff}, ConeAngle: {_lightInfo.ConeAngle}";
}
}
}
10 changes: 10 additions & 0 deletions ACViewer/Enum/PickType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace ACViewer.Enum
{
public enum PickType
{
Undef,
LandCell,
EnvCell,
GfxObj,
}
}
7 changes: 6 additions & 1 deletion ACViewer/FileTypes/Setup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,16 @@ public TreeNode BuildTree()
if (_setup.Lights.Count > 0)
{
var lights = new TreeNode("Lights:");

foreach (var kvp in _setup.Lights)
{
var light = new TreeNode($"{kvp.Key}: {new LightInfo(kvp.Value)}");
var light = new TreeNode($"{kvp.Key}");

light.Items = new LightInfo(kvp.Value).BuildTree();

lights.Items.Add(light);
}

treeView.Items.Add(lights);
}

Expand Down
18 changes: 18 additions & 0 deletions ACViewer/Model/PickResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using ACE.Server.Physics;
using ACE.Server.Physics.Common;

using ACViewer.Enum;

namespace ACViewer.Model
{
public class PickResult
{
public PickType Type { get; set; }
public ObjCell ObjCell { get; set; }
public PhysicsObj PhysicsObj { get; set; }
public int PartIdx { get; set; }
public ushort PolyIdx { get; set; }

public ACE.Server.Physics.Polygon HitPoly { get; set; } // only needed for ObjCell single poly mode
}
}
13 changes: 10 additions & 3 deletions ACViewer/Model/Setup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ public Setup(uint setupID)
if (!_setup.PlacementFrames.TryGetValue((int)Placement.Resting, out var placementFrames))
_setup.PlacementFrames.TryGetValue((int)Placement.Default, out placementFrames);

foreach (var placementFrame in placementFrames.AnimFrame.Frames)
PlacementFrames.Add(placementFrame.ToXna());
if (placementFrames != null)
{
foreach (var placementFrame in placementFrames.AnimFrame.Frames)
PlacementFrames.Add(placementFrame.ToXna());
}

BuildBoundingBox();
}
Expand Down Expand Up @@ -126,7 +129,11 @@ public List<Vector3> GetVertices()
continue;

var part = Parts[i];
var placementFrame = PlacementFrames[i];

var placementFrame = Matrix.Identity;

if (i < PlacementFrames.Count)
placementFrame = PlacementFrames[i];

var partVerts = part.VertexArray.Select(v => v.Position).ToList();

Expand Down
18 changes: 17 additions & 1 deletion ACViewer/Physics/BSP/BSPLeaf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Numerics;
using ACE.Server.Physics.Animation;

using ACViewer;

namespace ACE.Server.Physics.BSP
{
public class BSPLeaf: BSPNode, IEquatable<BSPLeaf>
Expand Down Expand Up @@ -72,7 +74,12 @@ public override bool sphere_intersects_poly(Sphere checkPos, Vector3 movement, r
foreach (var polygon in Polygons)
{
if (polygon.pos_hits_sphere(checkPos, movement, ref contactPoint, ref hitPoly))
{
if (PhysicsObj.IsPicking)
Picker.PickResult.HitPoly = hitPoly;

return true;
}
}
return false;
}
Expand All @@ -84,9 +91,15 @@ public override bool sphere_intersects_solid(Sphere checkPos, bool checkCenter)
if (!Sphere.Intersects(checkPos)) return false;

foreach (var polygon in Polygons)
{
if (polygon.hits_sphere(checkPos))
return true;
{
if (PhysicsObj.IsPicking)
Picker.PickResult.HitPoly = polygon;

return true;
}
}
return false;
}

Expand All @@ -104,6 +117,9 @@ public override bool sphere_intersects_solid_poly(Sphere checkPos, float radius,
{
if (polygon.hits_sphere(checkPos))
{
if (PhysicsObj.IsPicking)
Picker.PickResult.HitPoly = hitPoly;

hitPoly = polygon;
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion ACViewer/Physics/Common/BuildingObj.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public TransitionState find_building_collisions(Transition transition)
return TransitionState.OK;

transition.SpherePath.BuildingCheck = true;
var transitionState = PartArray.Parts[0].FindObjCollisions(transition);
var transitionState = PartArray.Parts[0].FindObjCollisions(transition, 0);
transition.SpherePath.BuildingCheck = false;

if (transitionState != TransitionState.OK && !transition.ObjectInfo.State.HasFlag(ObjectInfoState.Contact))
Expand Down
12 changes: 12 additions & 0 deletions ACViewer/Physics/Common/EnvCell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
using ACE.Server.Physics.Collision;
using ACE.Server.Physics.Extensions;

using ACViewer;
using ACViewer.Enum;

namespace ACE.Server.Physics.Common
{
public class EnvCell: ObjCell, IEquatable<EnvCell>
Expand Down Expand Up @@ -99,7 +102,16 @@ public override TransitionState FindEnvCollisions(Transition transition)
transitState = CellStructure.PhysicsBSP.find_collisions(transition, 1.0f);

if (transitState != TransitionState.OK && !transition.ObjectInfo.State.HasFlag(ObjectInfoState.Contact))
{
transition.CollisionInfo.CollidedWithEnvironment = true;

if (PhysicsObj.IsPicking)
{
// HitPoly set in BSPLeaf
Picker.PickResult.Type = PickType.EnvCell;
Picker.PickResult.ObjCell = this;
}
}
}
return transitState;
}
Expand Down
18 changes: 18 additions & 0 deletions ACViewer/Physics/Common/GfxObj.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,24 @@ public TransitionState FindObjCollisions(Transition transition, float scaleZ)
return TransitionState.OK;
}

public TransitionState FindObjCollisions_Draw(Transition transition, float scaleZ)
{
var path = transition.SpherePath;

// get overall drawing sphere from root node if needed
var drawingSphere = DrawingSphere ?? DrawingBSP.RootNode.Sphere;

foreach (var localSpaceSphere in path.LocalSpaceSphere)
{
var offset = drawingSphere.Center - localSpaceSphere.Center;
var radsum = drawingSphere.Radius + localSpaceSphere.Radius;

if (offset.LengthSquared() - radsum * radsum < PhysicsGlobals.EPSILON)
return TransitionState.Collided;
}
return TransitionState.OK;
}

public void Init()
{
GfxBoundBox = new BBox();
Expand Down
13 changes: 12 additions & 1 deletion ACViewer/Physics/Common/LandCell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
using ACE.Server.Physics.Animation;
using ACE.Server.Physics.Collision;

using ACViewer;
using ACViewer.Enum;

namespace ACE.Server.Physics.Common
{
public class LandCell: SortCell
Expand Down Expand Up @@ -62,7 +65,15 @@ public override TransitionState FindEnvCollisions(Transition transition)
var checkPos = new Sphere(path.GlobalSphere[0]);
checkPos.Center -= LandDefs.GetBlockOffset(path.CheckPos.ObjCellID, ID);

return objInfo.ValidateWalkable(checkPos, walkable.Plane, WaterType != LandDefs.WaterType.NotWater, waterDepth, transition, ID);
var result = objInfo.ValidateWalkable(checkPos, walkable.Plane, WaterType != LandDefs.WaterType.NotWater, waterDepth, transition, ID);

if (result != TransitionState.OK && PhysicsObj.IsPicking)
{
Picker.PickResult.Type = PickType.LandCell;
Picker.PickResult.ObjCell = this;
Picker.PickResult.HitPoly = walkable;
}
return result;
}

public new static LandCell Get(uint cellID)
Expand Down
4 changes: 0 additions & 4 deletions ACViewer/Physics/Common/ObjCell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,10 @@
using ACE.Server.Physics.Combat;
using ACE.Server.Physics.Managers;

using log4net;

namespace ACE.Server.Physics.Common
{
public class ObjCell: PartCell, IEquatable<ObjCell>
{
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

public uint ID;
public LandDefs.WaterType WaterType;
public Position Pos;
Expand Down
14 changes: 14 additions & 0 deletions ACViewer/Physics/Common/Position.cs
Original file line number Diff line number Diff line change
Expand Up @@ -298,5 +298,19 @@ public string ShortLoc()
{
return $"0x{ObjCellID:X8} [{Frame.Origin.X} {Frame.Origin.Y} {Frame.Origin.Z}]";
}

public void Reframe(uint landblock)
{
var lbx = landblock >> 24;
var lby = landblock >> 16 & 0xFF;

var dx = (int)LandblockX - lbx;
var dy = (int)LandblockY - lby;

Frame.Origin.X += dx * 192;
Frame.Origin.Y += dy * 192;

ObjCellID = landblock & 0xFFFF0000;
}
}
}
6 changes: 3 additions & 3 deletions ACViewer/Physics/Common/WeenieObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public bool InqRunRate(ref float rate)
uint runSkill = 0;
/*if (WorldObject is Creature creature)
runSkill = creature.GetCreatureSkill(Skill.Run).Current;*/
if (WorldObject.IsCreature)
if (WorldObject?.IsCreature ?? false)
runSkill = WorldObject.RunSkill;

//rate = (float)MovementSystem.GetRunRate(0.0f, 300, 1.0f);
Expand Down Expand Up @@ -162,13 +162,13 @@ public bool IsPKLite()
public bool IsPlayer()
{
//return WorldObject is Player;
return WorldObject.IsPlayer;
return WorldObject?.IsPlayer ?? false;
}

public bool IsCreature()
{
//return WorldObject is Creature;
return WorldObject.IsCreature;
return WorldObject?.IsCreature ?? false;
}

public bool IsStorage()
Expand Down
Loading

0 comments on commit 486e59c

Please sign in to comment.