# Question
Title: How to implement translation, scale, rotation gizmos for manipulating 3D object's transforms?
I am in the process of developing a basic 3D editor. It uses OpenGL for rendering a 3D world. Right now my scene is just a few boxes of different sizes and I am at the stage where I want to be able to select each box and then move/scale/rotate it to achieve any transform I want.

How can I solve the problem of implementing both the rendering of these tool's gizmos(or handles, or how people usually call them), and also picking them on each axis to perform the change in the transform with my mouse? For clarity:

My research so far suggested the cleanest approach is to have an axis aligned bounding box per arrow in the gizmo and another one per square (the ones that move the object in a plane rather than a single axis) and then cast a ray from the mouse position and see what it collides with. But this is still a bit too abstract for me, I would appreciate further guidance in how this algorithm would go (pseudocode is more than enough)

# Answer
> 9 votes
At some point in my time at e-on I have maintained the gizmos of Vue product line.
I can tell you, it will take you multiple days, full time.
Unless you find some library or super clever way, the classic way is to get the coordinate of the mouse in the window when you click, if its a relative coordinate to the viewport, you can simply divide x and y by width and height, you get a vector (float 2d) in \[0,1\] range. subtract (0.5,0.5) to it to get into \[-0.5, 0.5\] range for both x and y.
Then, you make a ray from this coordinate by using the x and y simply as the ray x and y, and you set z to the focal distance. sometimes aspect ratio is a pain in the ass in this operation. A bit of fiddling and trial error will get you fixed.
Then, you need to check intersection with your gizmos elements, either you have a mesh that you generated, or modeled in blender or other DCC, or mesh parts that can articulate between each other... Just use those mesh part as a ray/triangle intersection query.
Or if you have it, ray/cylinder, ray/sphere according to your gizmo looks and parts.
**You need to have intersection routines that are capable to apply a transformation matrix on the primitive they collide**. Extremely important because your gizmo will translate with the object it serves to move, it will rotate, and it will scale with the inverse of the distance to the camera, so that it keeps a fixed projected size on screen.
Then you have the interaction part, the easiest is the take the delta of the point when the mouse was first "mouse down" event, and the current "Mouse move" position, in pure 2D, and use this delta as the current axis movement in world space, multiplied by some `k` that you decide empirically. According to your internal units versus pixel versus current scale of zoom etc..
The final step is simply to apply the gizmo's matrix to the manipulated object, so that it follows it.

I tell you it is quite a journey in hell to implement, and if you're doing it in your free time excpect more than one week. Multiple weeks if you're completely discovering the field. More than one month if your week-ends are busy with other activities :)

I suggest you download Embree 2.0 from intel to do the ray/triangle intersection query for you, so you don't have to worry about coding that. Or you could mercilessely copy/paste and adapt code from blender... I think they moved to Apache license ? Should be possible legally.

# Answer
> 0 votes
For manipulator-translator I use follow algorithm:

1) When mouse down, we need check if ray intersects arrow. For example we consider X arrow. We construct Ray in world space (based on camera frustum and mouse position). We build a plane in which the x axis lies: its normal is equal V cross X cross V, where V - vector from center to camera, X - represents x axis. Then we intersect the ray with the plane and therefore we find the intersection point in world coordinates. Then we project the x axis segment and the resulting point back onto the screen, find the distance between the projected segment and the projected point on the screen. if it is less than a few pixels, the mouse intresects the axis. Also we calculate world space delta vector between selection’s center and our intersection.

This procedure we do for 3 axis, so we find distances to all axis. Find the minimum distance. so we found with which axis the mouse is intersects.

2) When mouse move. we know by what axis the object moves (from 1). we find the world space intersection of the ray with the plane (as in 1). additionally we project the intersection point on the line the object moves along. final manipulator position = intersection + delta.

---
Tags: opengl, 3d
---


title: Lock Z axis from the gyroscope rotation

text:
# Question
Title: Lock Z axis from the gyroscope rotation
Here's the code I use.

```
public class CameraGyro : MonoBehaviour {

private float initialX;
private float initialY;
private float initialZ;

// Use this for initialization
void Start () {
    Input.gyro.enabled = true;

    initialX = Input.gyro.rotationRateUnbiased.x;
    initialY = Input.gyro.rotationRateUnbiased.y;
}

// Update is called once per frame
void Update () {

    transform.Rotate (initialX - Input.gyro.rotationRateUnbiased.x, initialY - Input.gyro.rotationRateUnbiased.y, 0f);
}

}

```

The thing is when I rotate the phone, the Z axis seems to change even if I've set it to 0f in the code above. Is there a way to really lock this position to 0?

# Answer
I go into some detail about this phenomenon in this Q&A:

I'm rotating an object on two axes, so why does it keep twisting around the third axis?

The root issue here is that the idea that rotation is naturally/objectively separable into 3 independent components (the way we can do with translation) is a misconception.

Euler angles / Tait-Bryan angles lure us into this belief because they look a lot like a translation vector, but it's easy to show that it's false. Consider the angle triplets (180, 180, 0) and (0, 0, 180): both represent the same orientation, one purely with "x & y" rotations, the other with "purely z" rotation. Or here's another example with compounding rotations in sequence:

So, zeroing-out the z component of an angular triplet isn't enough to guarantee you don't get roll.

What to do instead depends on the exact behaviour you want. You could try for instance track a pitch & yaw value independently, and apply the total all at once rather than incrementally compounding rotations:

```
// in Start(), initialize your x & y angles to match the camera's initial orientation.
pitch = transform.eulerAngles.x;
yaw = transform.eulerAngles.y;

// In Update, accumulate rotational change in these axes:
pitch += input.gyro.rotationRateUnbiased.x * Mathf.RadToDeg() * Time.deltaTime;
yaw += input.gyro.rotationRateUnbiased.y * Mathf.RadToDeg() * Time.deltaTime;
// Apply the result all at once:
transform.eulerAngles = new Vector3(pitch, yaw, 0);

```

Or you could try rotating the forward / look vector, then construct a "roll-free" orientation that looks in that direction:

```
Vector3 angularDelta = input.gyro.rotationRateUnbiased * Time.deltaTime;
Vector3 newForward = transform.forward + Vector3.Cross(transform.forward, angularDelta);
transform.rotation = Quaternion.LookRotation(newForward);

```
> 1 votes

# Answer
Try locking the z axis using "Rotation Constraints": https://docs.unity3d.com/Manual/class-RotationConstraint.html
> 0 votes

---
Tags: c#, unity
---


# Question
Title: How do I create an empty Prefab with Unity 2018.3?
I was using Unity 2018.1.(something), where I could simply create an empty Prefab object, then drag a Game Object to the Prefab from the Hierarchy to fill it. When I updated to Unity 2018.3.0f2, I don't see any more empty Prefab object in the create menu, all I get is Prefab Variant (which is disabled).

I read the Unity Blog talking about new prefab workflows, and I could not find any changes in how Prefabs are created.

# Answer
> 6 votes
You can still do it the other way around, which is: GameObject -\> Create Empty. That will create an empty GameObject in your scene. You can then drag it into your Project View that will create a prefab in your project. The "Prefab Variant" selection only works when you have a prefab selected in your Project View.

---
Tags: unity
---


title: 3D Texture Only interpolates on Y-Axis

text:
# Question
Title: 3D Texture Only interpolates on Y-Axis
I'm having trouble wrapping my brain around what actually is the issue here, but the sampler I'm using in my volume renderer is only interpolating the 3D texture along the Y axis.

I roughly followed (and borrowed a lot of code from) this tutorial, but I'm using SlimDX and WPF: http://graphicsrunner.blogspot.com/2009/01/volume-rendering-101.html

Here's an example, showing voxel artifacts on the X and Z axes, which are evidently not being interpolated, or being done incorrectly:

It's somewhat hard to tell, but the Y-axis samples are seemingly being interpolated correctly:

Disabling interpolation in the sampler causes artifacts to appear on the Y-axis, as shown below. So I at least know it's partially working.

I tried writing a manual trilinear interpolation routine, but I get the same results with built-in sampling and my own code.

To get a better idea of what might be the problem, I tried coloring pixels based on the fraction of the coordinate in grid space, to see why the linear interpolation wasn't working. The Y-axis should have 30 white-\> black fades, because the radar dataset I'm volume rendering has 30 vertical layers. It did:

Using the same approach on the Z-axis, I get nonsense:

My best guess is that I'm somehow initializing the 3D texture incorrectly, causing the shader to act unexpectedly.

Here's relevant code, starting at ingestion of data:

```
// Read data file and get physical sizes
Data = new GURUGridFile(@"E:\GURU2 Test Data\GoshenDual\Finished\30_DOW7_(X)_20090605_220006.ggf");
double DataX = Data.CellSize[0] * Data.Dimensions[0];
double DataY = Data.CellSize[1] * Data.Dimensions[1];
double DataZ = Data.CellSize[2] * Data.Dimensions[2];
double MaxSize = Math.Max(DataX, Math.Max(DataY, DataZ));

// Send geometry sizes to the renderer
DataX /= MaxSize;
DataY /= MaxSize;
DataZ /= MaxSize;
Renderer.XSize = (float)DataX;
Renderer.YSize = (float)DataY;
Renderer.ZSize = (float)DataZ;

// Grab data and read into a 3D array
int ProductCode = Data.LayerProducts[0].ToList().IndexOf("A_DZ");
float[,,] RadarData = new float[Data.Dimensions[0], Data.Dimensions[1], Data.Dimensions[2]];
for (int x = 0; x < Data.Dimensions[0]; x++)
    for (int y = 0; y < Data.Dimensions[1]; y++)
        for (int z = 0; z < Data.Dimensions[2]; z++)
            RadarData[x, y, z] = Data.Data[z][ProductCode][x, y];

// Calculate and assign the step size for raycasting
// Z and Y axes are flipped here to come in line with D3D coordinates
int DataSize = Math.Max(RadarData.GetLength(0), Math.Max(RadarData.GetLength(1), RadarData.GetLength(2)));
int mWidth = RadarData.GetLength(0);
int mHeight = RadarData.GetLength(2);
int mDepth = RadarData.GetLength(1);
float mStepScale = 1.0F;
float maxSize = (float)Math.Max(mWidth, Math.Max(mHeight, mDepth));
SlimDX.Vector3 stepSize = new SlimDX.Vector3(   1.0f / (mWidth * (maxSize / mWidth)),
                                                1.0f / (mHeight * (maxSize / mHeight)),
                                                1.0f / (mDepth * (maxSize / mDepth)));

// Make render engine
VolumeRenderer = new VolumeRenderEngine(false, Renderer.device);
VolumeRenderer.Data = VolumeRenderTest.Rendering.TextureObject3D.FromData(RadarData);
VolumeRenderer.StepSize = stepSize * mStepScale;
VolumeRenderer.Iterations = (int)(maxSize * (1.0f / mStepScale) * 2.0F);

Renderer.Initialize();
SetupSlimDX();

this.VolumeRenderer.DataWidth = Data.Dimensions[0];
this.VolumeRenderer.DataHeight = Data.Dimensions[2];
this.VolumeRenderer.DataDepth = Data.Dimensions[1];

```

Here's my code to generate the 3D texture, wrapped in a helper class to make working with it more convenient. This is where I think my problem is, maybe?

```
public static TextureObject3D FromData(float[,,] Data)
{
    Texture3DDescription texDesc = new Texture3DDescription()
    {
        BindFlags = SlimDX.Direct3D11.BindFlags.ShaderResource,
        CpuAccessFlags = SlimDX.Direct3D11.CpuAccessFlags.None,
        Format = SlimDX.DXGI.Format.R32_Float,
        MipLevels = 1,
        OptionFlags = SlimDX.Direct3D11.ResourceOptionFlags.None,
        Usage = SlimDX.Direct3D11.ResourceUsage.Default,
        Width = Data.GetLength(0),
        Height = Data.GetLength(2),
        Depth = Data.GetLength(1)
    };

    // Flatten data
    int i = 0;
    float[] FlatData = new float[Data.GetLength(0) * Data.GetLength(1) * Data.GetLength(2)];
    for (int y = 0; y < Data.GetLength(1); y++)
        for (int z = 0; z < Data.GetLength(2); z++)
            for (int x = 0; x < Data.GetLength(0); x++)
                FlatData[i++] = Data[x, y, z];

    DataStream TextureStream = new DataStream(FlatData, true, true);
    DataBox TextureBox = new DataBox(texDesc.Width * 4, texDesc.Width * texDesc.Height * 4, TextureStream);
    Texture3D valTex = new Texture3D(Renderer.device, texDesc, TextureBox);

    var viewDesc = new SlimDX.Direct3D11.ShaderResourceViewDescription()
    {
        Format = texDesc.Format,
        Dimension = SlimDX.Direct3D11.ShaderResourceViewDimension.Texture3D,
        MipLevels = texDesc.MipLevels,
        MostDetailedMip = 0,
        ArraySize = 1,
        CubeCount = 1,
        ElementCount = 1
    };
    ShaderResourceView valTexSRV = new ShaderResourceView(Renderer.device, valTex, viewDesc);

    TextureObject3D tex = new TextureObject3D();
    tex.Device = Renderer.device;

    tex.Size = TextureStream.Length;
    tex.TextureStream = TextureStream;
    tex.TextureBox = TextureBox;
    tex.Texture = valTex;
    tex.TextureSRV = valTexSRV;

    return tex;
}

```

This is the code from the render engine where values are assigned to the effect and instructions are sent to the GPU:

```
private void RenderVolume()
{
    // Rasterizer states
    RasterizerStateDescription RSD_Front = new RasterizerStateDescription();
    RSD_Front.FillMode = SlimDX.Direct3D11.FillMode.Solid;
    RSD_Front.CullMode = CullMode.Back;
    RSD_Front.IsFrontCounterclockwise = false;

    RasterizerStateDescription RSD_Rear = new RasterizerStateDescription();
    RSD_Rear.FillMode = SlimDX.Direct3D11.FillMode.Solid;
    RSD_Rear.CullMode = CullMode.Front;
    RSD_Rear.IsFrontCounterclockwise = false;

    RasterizerState RS_OLD = Device.ImmediateContext.Rasterizer.State;
    RasterizerState RS_FRONT = RasterizerState.FromDescription(Renderer.device, RSD_Front);
    RasterizerState RS_REAR = RasterizerState.FromDescription(Renderer.device, RSD_Rear);

    // Calculate world view matrix
    Matrix wvp = _world * _view * _proj;

    RenderTargetView NullRTV = null;

    // First we need to render to the rear texture
    SetupBlend(false);
    PrepareRTV(RearTextureView);
    SetBuffers();
    Device.ImmediateContext.Rasterizer.State = RS_REAR;
    Renderer.RayCasting101FX_WVP.SetMatrix(wvp);
    Renderer.RayCasting101FX_ScaleFactor.Set(ScaleFactor);
    ExecuteTechnique(Renderer.RayCasting101FX_RenderPosition);
    Device.ImmediateContext.Flush();
    Device.ImmediateContext.OutputMerger.SetTargets(NullRTV);

    // Now we draw to the front texture
    SetupBlend(false);
    PrepareRTV(FrontTextureView);
    SetBuffers();
    Device.ImmediateContext.Rasterizer.State = RS_FRONT;
    Renderer.RayCasting101FX_WVP.SetMatrix(wvp);
    Renderer.RayCasting101FX_ScaleFactor.Set(ScaleFactor);
    ExecuteTechnique(Renderer.RayCasting101FX_RenderPosition);
    Device.ImmediateContext.Flush();
    Device.ImmediateContext.OutputMerger.SetTargets(NullRTV);

    SetupBlend(false);

    //Set Render Target View
    Device.ImmediateContext.OutputMerger.SetTargets(SampleRenderView);

    // Set Viewport
    Device.ImmediateContext.Rasterizer.SetViewports(new Viewport(0, 0, WindowWidth, WindowHeight, 0.0f, 1.0f));

    // Clear screen
    Device.ImmediateContext.ClearRenderTargetView(SampleRenderView, new Color4(1.0F, 0.0F, 0.0F, 0.0F));

    if (Wireframe)
    {
        RenderWireframeBack();
        Device.ImmediateContext.Rasterizer.State = RS_FRONT;
    }

    SetBuffers();

    // Assign effect variables
    Renderer.RayCasting101FX_WVP.SetMatrix(wvp);
    Renderer.RayCasting101FX_ScaleFactor.Set(ScaleFactor);
    Renderer.RayCasting101FX_Back.SetResource(new ShaderResourceView(Renderer.device, RearTexture));// RearTextureSRV);
    Renderer.RayCasting101FX_Front.SetResource(new ShaderResourceView(Renderer.device, FrontTexture));//FrontTextureSRV);
    Renderer.RayCasting101FX_Volume.SetResource(new ShaderResourceView(Renderer.device, Data.Texture));
    Renderer.RayCasting101FX_StepSize.Set(StepSize);
    Renderer.RayCasting101FX_Iterations.Set(Iterations);

    Renderer.RayCasting101FX_Width.Set(DataWidth);
    Renderer.RayCasting101FX_Height.Set(DataHeight);
    Renderer.RayCasting101FX_Depth.Set(DataDepth);

    // Run effect
    ExecuteTechnique(Renderer.RayCasting101FX_RayCastSimple);

    if (Wireframe)
    {
        RenderWireframeFront();
        Device.ImmediateContext.Rasterizer.State = RS_FRONT;
    }

    Device.ImmediateContext.Flush();

    CanvasInvalid = false;

    sw.Stop();

    this.LastFrame = sw.ElapsedTicks / 10000.0;
}

private void PrepareRTV(RenderTargetView rtv)
{
    //Set Depth Stencil and Render Target View
    Device.ImmediateContext.OutputMerger.SetTargets(rtv);

    // Set Viewport
    Device.ImmediateContext.Rasterizer.SetViewports(new Viewport(0, 0, WindowWidth, WindowHeight, 0.0f, 1.0f));

    // Clear render target
    Device.ImmediateContext.ClearRenderTargetView(rtv, new Color4(1.0F, 0.0F, 0.0F, 0.0F));
}

private void SetBuffers()
{
    // Setup buffer info
    Device.ImmediateContext.InputAssembler.InputLayout = Renderer.RayCastVBLayout;
    Device.ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
    Device.ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(Renderer.VertexBuffer, Renderer.VertexPC.Stride, 0));
    Device.ImmediateContext.InputAssembler.SetIndexBuffer(Renderer.IndexBuffer, Format.R32_UInt, 0);
}

private void ExecuteTechnique(EffectTechnique T)
{
    for (int p = 0; p < T.Description.PassCount; p++)
    {
        T.GetPassByIndex(p).Apply(Device.ImmediateContext);
        Device.ImmediateContext.DrawIndexed(36, 0, 0);
    }
}

```

Finally, here's the shader in its entirety. Taken from the blog post above and modified somewhat.

```
float4x4 World;
float4x4 WorldViewProj;
float4x4 WorldInvTrans;

float3 StepSize;
int Iterations;

int Side;

float4 ScaleFactor;

int Width;
int Height;
int Depth;

Texture2D<float3> Front;
Texture2D<float3> Back;
Texture3D<float1> Volume;

SamplerState FrontSS = sampler_state
{
    Texture = <Front>;
    Filter = MIN_MAG_MIP_POINT;

    AddressU = Border; // border sampling in U
    AddressV = Border; // border sampling in V
    BorderColor = float4(0, 0, 0, 0); // outside of border should be black
};

SamplerState BackSS = sampler_state
{
    Texture = <Back>;
    Filter = MIN_MAG_MIP_POINT;

    AddressU = Border; // border sampling in U
    AddressV = Border; // border sampling in V
    BorderColor = float4(0, 0, 0, 0); // outside of border should be black
};

SamplerState VolumeSS = sampler_state
{
    Texture = <Volume>;
    Filter = MIN_MAG_MIP_LINEAR;

    AddressU = Border; // border sampling in U
    AddressV = Border; // border sampling in V
    AddressW = Border; // border sampling in W
    BorderColor = float4(0, 0, 0, 0); // outside of border should be black
};

struct VertexShaderInput
{
    float3 Position : POSITION;
    float4 texC     : COLOR;
};

struct VertexShaderOutput
{
    float4 Position     : SV_POSITION;
    float3 texC         : TEXCOORD0;
    float4 pos          : TEXCOORD1;
};

VertexShaderOutput PositionVS(VertexShaderInput input)
{
    VertexShaderOutput output;

    output.Position = float4(input.Position, 1.0);
    output.Position = mul(output.Position * ScaleFactor, WorldViewProj);

    output.texC = input.texC.xyz;
    output.pos = output.Position;

    return output;
}

float4 PositionPS(VertexShaderOutput input) : SV_TARGET // : COLOR0
{
    return float4(input.texC, 1.0f);
}

float4 WireFramePS(VertexShaderOutput input) : SV_TARGET // : COLOR0
{
    return float4(1.0f, .5f, 0.0f, .85f);
}

//draws the front or back positions, or the ray direction through the volume
float4 DirectionPS(VertexShaderOutput input) : SV_TARGET // : COLOR0
{
    float2 texC = input.pos.xy /= input.pos.w;
    texC.x =  0.5f * texC.x + 0.5f;
    texC.y = -0.5f * texC.y + 0.5f;

    float3 front = Front.Sample(FrontSS, texC).rgb;// tex2D(FrontS, texC).rgb;
    float3 back = Back.Sample(BackSS, texC).rgb; // tex2D(BackS, texC).rgb;

    if(Side == 0)
    {
        float4 res = float4(front, 1.0f);
        return res;

    }
    if(Side == 1)
    {
        float4 res = float4(back, 1.0f);
        return res;
    }

    return float4(abs(back - front), 1.0f);
}

float TrilinearSample(float3 pos)
{
    float X = pos.x * Width;
    float Y = pos.y * Height;
    float Z = pos.z * Depth;

    float iX = floor(X);
    float iY = floor(Y);
    float iZ = floor(Z);

    float iXn = iX + 1;
    float iYn = iY + 1;
    float iZn = iZ + 1;

    float XD = X - iX;
    float YD = Y - iY;
    float ZD = Z - iZ;

    float LL = lerp(Volume[float3(iX, iY, iZ)], Volume[float3(iX, iY, iZn)], ZD);
    float LR = lerp(Volume[float3(iXn, iY, iZ)], Volume[float3(iXn, iY, iZn)], ZD);

    float UL = lerp(Volume[float3(iX, iYn, iZ)], Volume[float3(iX, iYn, iZn)], ZD);
    float UR = lerp(Volume[float3(iXn, iYn, iZ)], Volume[float3(iXn, iYn, iZn)], ZD);

    float L = lerp(LL, UL, YD);
    float R = lerp(LR, UR, YD);

    //return ZD;

    return lerp(L, R, XD);

    return 0.0F;
}

float4 RayCastSimplePS(VertexShaderOutput input) : SV_TARGET // : COLOR0
{
    //calculate projective texture coordinates
    //used to project the front and back position textures onto the cube
    float2 texC = input.pos.xy /= input.pos.w;
    texC.x =  0.5f* texC.x + 0.5f;
    texC.y = -0.5f* texC.y + 0.5f;

    float3 front = Front.Sample(FrontSS, texC).rgb; // tex2D(FrontS, texC).xyz;
    float3 back = Back.Sample(BackSS, texC).rgb; // tex2D(BackS, texC).xyz;

    float3 dir = normalize(back - front);
    float4 pos = float4(front, 0);

    float4 dst = float4(0, 0, 0, 0);
    float4 src = 0;

    float value = 0;

    //Iterations = 1500;

    float3 Step = dir * StepSize; // / (float)Iterations;
    float3 TotalStep = float3(0, 0, 0);

    value = Volume.Sample(VolumeSS, pos.xyz).r;

    int i = 0;
    for(i = 0; i < Iterations; i++)
    {
        pos.w = 0;
        //value = Volume.SampleLevel(VolumeSS, pos.xyz, 0);
        value = TrilinearSample(pos.xyz); // tex3Dlod(VolumeS, pos).r;

        // Radar reflectivity related threshold values
        if (value < 40)
            value = 40;
        if (value > 60)
            value = 60;

        value = (value - 40.0) / 20.0;

        src =  (float4)(value);
        src.a /= (Iterations / 50.0);

        //Front to back blending
        // dst.rgb = dst.rgb + (1 - dst.a) * src.a * src.rgb
        // dst.a   = dst.a   + (1 - dst.a) * src.a
        src.rgb *= src.a;
        dst = (1.0f - dst.a) * src + dst;

        //break from the loop when alpha gets high enough
        if (dst.a >= .95f)
            break;

        //advance the current position
        pos.xyz += Step;
        TotalStep += Step;

        //break if the position is greater than <1, 1, 1>
        if (pos.x > 1.0f || pos.y > 1.0f || pos.z > 1.0f || pos.x < 0.0f || pos.y < 0.0f || pos.z < 0.0f)
            break;
    }

    return dst;
}

technique11 RenderPosition
{
    pass Pass1
    {
        SetVertexShader(CompileShader(vs_4_0, PositionVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, PositionPS()));
        //VertexShader = compile vs_2_0 PositionVS();
        //PixelShader = compile ps_2_0 PositionPS();
    }
}

technique11 RayCastDirection
{
    pass Pass1
    {
        SetVertexShader(CompileShader(vs_4_0, PositionVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, DirectionPS()));
        //VertexShader = compile vs_2_0 PositionVS();
        //PixelShader = compile ps_2_0 DirectionPS();
    }
}

technique11 RayCastSimple
{
    pass Pass1
    {
        SetVertexShader(CompileShader(vs_4_0, PositionVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, RayCastSimplePS()));
        //VertexShader = compile vs_3_0 PositionVS();
        //PixelShader = compile ps_3_0 RayCastSimplePS();
    }
}

technique11 WireFrame
{
    pass Pass1
    {
        SetVertexShader(CompileShader(vs_4_0, PositionVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, WireFramePS()));
        //VertexShader = compile vs_2_0 PositionVS();
        //PixelShader = compile ps_2_0 WireFramePS();
    }
}

```

Any insight is appreciated. At this point I'm just guessing at possible issues and seeing what changes. Mostly just breaking things though.

# Answer
> 1 votes
I figured it out. It had absolutely nothing to do with the Texture3D, sampler, or anything else that I was wanting to blame.

Upon zooming in really far, I noticed that it probably wasn't the 3D texture's fault - it looked like the ray directions were being somehow miscalculated. The pixelated areas are looking slightly different directions from each other, causing tight gradients to get broken up.

It turns out issue was the textures I was drawing the front/rear faces of the geometry to. They were initialized as B8G8R8A8\_UNorm. As soon as I changed them to R32G32B32A32\_Float it worked. It was just insufficient precision all along.

Now it works properly:

Live and learn!

---
Tags: c#, directx11, slimdx
---


# Question
Title: Instantiate prefab button inside of panel
I have a Canvas GameObject with a panel inside of it and a button prefab of the default button.

When I drag the button from my resources folder onto the Canvas in the hierarchy, it places itself where I expect it to, into the panel.

However when I instantiate it like below:

```
GameObject button = Instantiate(Resources.Load("UI/Dialogue/Button"), new Vector3(0, 0, 0), Quaternion.identity, MyCanvas.transform) as GameObject;

```

it gets placed into the center of the screen because of the second parameter. However, I can't set it as a child of the parent because that doesn't happen until the last parameter. It also doesn't feel right to figure out the exact Vector3 to plug in so that it looks like its on top of the panel.

Is there a way to instantiate the button onto the panel in code as it works when dragging it from the resources folder onto the Canvas in the hierarchy?

# Answer
> 3 votes
try this one:

```
Instantiate(T original, Transform parent);

```

or this one:

```
Instantiate(T original, Transform parent, bool worldPositionStays);

```

instead of this one

```
public static T Instantiate(T original, Vector3 position, Quaternion rotation, Transform parent);

```

---
Tags: unity
---


title: Combat numbers in an MVC

text:
# Question
Title: Combat numbers in an MVC
Bear with me this will take some explaining...

I'm trying to design my game as close to Model-View-Controller design principles as possible. At least in and so far as I understand those principles.

I have two relevant classes in my View and Model respectively (with an irrelevant-in-this-case `playerInput` class acting as the controller)

`BattleSerializable` (My model that handles battle logic) `BattleView` (My view that handles battle display stuff)

`BattleSerializabl`e has a method called `DoDamage` that subtracts health from a player. `BattleView` has a method `DoDamageView` that calls the model's method (`DoDamage`) and then renders a number on the screen to indicate the amount of damage done.

So far so good.

But there's a friendly fire penalty! In the sense that if you do damage to an ally, *you* also take damage.

Ok, so now I can go one of three ways:

1) My `BattleView` can handle the friendly fire logic and call the `DoDamage` method twice in the case of a friendly fire occurrence, but this goes against what "View" is supposed to do. It doesn't make sense that `BattleView` should handle friendly fire logic. It should handle view logic only.

2) My `BattleSerializable` class can handle the friendly fire logic, but now I have to return a complex custom return object instead of a simple integer to handle all the state that changed. This seems needlessly complex or, at the very least, in-eloquent.

3) Instead of calling my model method from the view method, I could have the model run independently and, from the view, "poll" the Model every frame for changes and then render combat numbers if a change is detected. This seems inefficient and in-eloquent to me as well.

What is the preferred way to design this?

# Answer
> 8 votes
You are correct that it's not the View's job in an MVC architecture to implement any game mechanics like friendly fire.

But whether it's the controller's job or the model's job to implement game mechanics is a matter of debate.

There are basically two philosphies here:

## Thin Model

In a thin model MVC architecture, the model is just a dumb data-structure and the game mechanics are implemented in the controller(s):

* The **view** should just visualize what happens in the model and provide the UI through which the player gives commands.
* The **model** should not implement game mechanics either. It should just be concerned with storing and maintaining the state of the game.
* Implementing the actual game mechanics should be the job of the **controller**.

For example, when the user makes an input through the view like "My character A uses attack B on enemy C", that input is handled by the `BattleController`. The battle controller calculates the damage and calls the appropriate methods on the model, like `DoDamage(enemyC, 10)` and `DoDamage(allyA, 5)`.

## Fat Model

In a fat model MVC architecture, the model is smart and implements the game mechanics itself:

* The **view** still visualizes what happens in the model and provides the UI.
* The **controller** acts like a glue between view and model. It receives user input from the view and translates it into commands for the model.
* The **model** accepts those commands, handles the game mechanics, modifies the game state and informs the view about it.

For example, the user does some clicks on the view, the controller interprets these clicks and realizes they mean: "Player wants character A to perform attack B on enemy C" and sends that command to the model by calling a method like `model.doAttack(attackB, characterA, enemyC);`.

The model then determines what that means. It looks up what attack B does, sees that it does 5 damage on the user and 10 damage on the target, calculates that damage, applies it to these entities, checks if they are still alive and then tells the view to visualize all that.

---

Which one you choose is up to you. Personally I would prefer to use a thin model with smarter controllers when I had a game with lots of complicated game mechanics but where all these mechanics end up interacting with all game entities in the same way (I would also call these controllers "Systems" and claim I am doing ECS). But if I had rather simple basic game mechanics but lots of gimmicky entities which twist these rules by using unique mechanics, I would prefer to put more logic in the model so the entities can handle their own logic through polymorphy.

Also keep in mind that design patterns are just suggestions how you can structure your game, not immutable laws. If you feel that diverting from them makes for a cleaner architecture in your specific case, by all means, divert from them.

---

> My BattleSerializable class can handle the friendly fire logic, but now I have to return a complex custom return object instead of a simple integer to handle all the state that changed. This seems needlessly complex or, at the very least, in-eloquent.

The communication from the view to the model shouldn't happen through return values at all.

You don't know what model changes a player action will trigger. It is possible that it results in a whole cascade of changes. An AoE attack damages one enemy, poisons another, kills a third, the killed enemy explodes, the explosion kills off the first enemy, etc. etc.. How are you going to tell that story to the view? You would have to return a whole array of complex custom objects. But wait, what about model changes which are not triggered by the player? The enemy actions, for example? How do you communicate those to the view when the view wasn't the one who made the method call?

What you should do instead is have the model communicate with the view explicitly. There are different ways to do that:

* Push-Event communication: When something happens in the model, the model calls methods from the view to inform it about these events.
* Pull-Event communication: The model keeps a queue of events. The view empties that event queue and visualizes the actions it finds in it.
* Polling: The view iterates the whole model and updates its visualization of the game state. This often requires that the view keeps a separate model so it can detect changes. This pattern is called Model - View - ViewModel.

---
Tags: mvc
---


title: Polygons depth sorting in Z-buffer

text:
# Question
Title: Polygons depth sorting in Z-buffer
Why is it that the Z-buffer algorithm does not require polygons to be depth sorted to function correctly?

# Answer
The Z-Buffer simply saves the Z value of each pixel as you draw them. That means that when you try to draw a new pixel, you compare its Z value with the one saved on the Z-Buffer.

That means that once the whole scene is drawn, and the game decided to draw one last polygon on the very far background, the value of the pixels on the Z-Buffer corresponding to that polygon will be higher than the Z value of the pixels belonging to the polygon, so they will not be drawn at all.

This guarantees that the scene will be rendered correctly, and no polygon will be drawn on top of another where it shouldn't. However the negative is the overdraw. Although there is no guarantee which polygon will be drawn first (depends on engine/framework used), there's a high chance a pixel on the screen will be drawn more than once.

As mentioned in the comments, for performance reasons, it's best to draw polygons from front to back, so that most polygons that are obscured won't be rendered at all.

Also an exception to this are semi-transparent polygons, which have to be Z-sorted and drawn after all opaque polygons are drawn.

For more information, see Z-buffering on Wikipedia
> 1 votes

---
Tags: 3d, graphics, graphics-programming
---


title: Is it still possible to install Unity?

text:
# Question
Title: Is it still possible to install Unity?
When trying to install Unity I am getting the following error:

> The download of version ... was cancelled.

I checked that there are no spaces in the path.

Also I can not Sign in. When I provide the correct email and password the Sign in window just closes with no result.

Also I tried to report a bug using the Report Bug feature, but it seems not to work.

Also I tried to post a question on Unity Forum. But the Sign In over there does not work as well.

What else may I try? Thank you.

# Answer
> 3 votes
If the Unity Hub is not working, you can still always download any version of Unity directly from their website:

https://unity3d.com/get-unity/download/archive

---
Tags: unity, ide, installer, support
---


title: Using instancing for everything?

text:
# Question
Title: Using instancing for everything?
Instancing improves performance (significantly) when rendering multiple (hunders? thousands?) copies of the same mesh at once. But how much overhead does it have when rendering exactly one copy with one draw call? Would it be a good or a bad idea to use instancing for all geometry rendered by engine?

Edit: Let's say we're creating an FPS game. Most of the objects have only one instance: a knife, a gun, a machine gun, a building and a radio tower. But there are also some objects with multiple instances: trees (e.g. 3 kinds of trees with hundreds of instances), grass and so on... What I mean is: instead of rendering the one-instance objects the "traditional" way and trees and grass using instancing, we render **all of them** using instancing. So our radio tower has only one instance (whose information we store in an instance data buffer) and we render that tower using some kind of `DrawInstanced()` call with instance count equal `1`. Same with all other objects (of course, trees and grass have multiple instances).

So my question is: is it a bad idea to draw a single instance of an object using instancing? Does instancing have too much of an overhead (memory- and performance-wise) or is it in any way undesired for rendering single-instance objects?

# Answer
> 20 votes
Under D3D9 with XPDM you almost certainly want to instance wherever possible. Draw call overhead is just so high that it makes sense. In that scenario the crossover-point can be as low as 2 or 3 instances.

If you've only got one instance of a given mesh, it may on the surface seem tempting to draw it non-instanced. However, look at what's involved:

* You need to switch from loading data into a per-instance buffer to uploading shader constants.
* You need to keep two copies of your vertex shader: one for instanced and one for non-instanced.
* You need to keep two copies of your rendering code: likewise.
* You need to switch shaders.
* You need to switch vertex formats.
* You may need to switch vertex buffers.
* And then you need to do it all over again if you're going back to instanced drawing for the next group of meshes.

Even if you've only got a single mesh (like the gun model in an FPS) there are cases where instancing is useful. Let's say you're doing multipass light accumulation in a forward renderer and with a z-prepass. Instead of an extra pass for each light, you make your lights per-instance data and you draw it instanced.

Based on the first scenario, the moral of the story is that if any object class can use instancing at all, it makes sense to always use instancing for all objects of that class.

Based on the second scenario, the moral of the story is that instancing can have non-obvious uses that go beyond just saying "I need to draw 20 trees".

# Answer
> 12 votes
(On my system, didn't test it anywhere else) In GL, instancing a single mesh (drawing with count = 1) has some nasty overhead, but I don't know where it comes from. I strongly suggest not doing it.

I tested this in a practical application a couple of months ago. I coded some global illumination algorithms in the Crytek Sponza scene, which consists of roughly 350 or so meshes (don't remember exactly), of which a couple share a handful of instances. At the beginning I did it like you suggest, just instance everything and draw the rest with instance count of 1, since it simplified the rendering code a bit.

Later when optimizing the renderer, just switching back from instancing the count=1 objects to submitting them the usual way saved me about **3.5 milliseconds** per frame worth of time on an i7 3770k (and GTX 770). Switching the meshes with multiple instances to just doing them the traditional way saved me another 0.5ms. Overall the application went from ~120 FPS to about ~230 FPS.

These figures of course always depend on where the bottlenecks are in your application, and the latter 0.5ms might actually become a slow-down in an application where you're very draw-call bound. But otherwise, in my experience instancing has some nasty overhead if you're not drawing a lot of things at once.

# Answer
> 2 votes
You can be for certain that drawing a single object instanced is more expensive than drawing a single object normally. For instancing the GPU is preparing for a large amount of objects and this preparation will be different than for a single object. However how large this performance gap is can only be found by experimenting and is very much depending on your actual rendering set-up. The only way to know for sure is by testing it yourself. Benchmarking a single draw call is hard here are several ideas on how you could proceed.

# Answer
> 2 votes
It's been 4 years... and I think its safe to say that is perfectly fine to submit "instanced" draw calls with 1. As you may have noticed, new APIs DX12 and Vk both have an instance count that can be from 0 to *NUM\_INSTANCES*. Also note that there is no *DrawIndexed(...)*.

**EDIT**

As a note of caution, the above is probably fine with this modern APIs, maybe using something old like Gl\<3.3 or perhaps DX11 will require some profiling as mentioned by other users.

---
Tags: mesh, instancing
---


# Question
Title: SRTM data represented in 3D using Unity Terrain
I am new to using Terrain height maps in Unity.

I'm trying to use real-world terrain height data, using sources including:

* The US Geological Survey (files like N24E054.hgt)
* Google Maps (SRTM hdr files, tfw files, and tif files)

I want to import this high definition terrain data into a Unity terrain.

In Unity, it seems like terrain can only import Raw data representation.

How can I use an hgt file to shape a Unity Terrain?

# Answer
i used an application called L3dt, which can import many format of heightmap and export in many including RAW

free version here (you can also email request a free trial of the Pro Edition): http://www.bundysoft.com/L3DT/downloads/
> 1 votes

# Answer
I used terrain.party website to get the maps. It works pretty well. You feed it location coodinates and returns the maps.

Gimp is a nice program to use to view and export the file to Raw.

Then you import the raw heightmap to use as terrain.
> 1 votes

# Answer
Uset VTBuilder and then export to your prefered format:

> Export elevation grids to ArcInfo ASCII Grid, GeoTIFF, TerraGen, BMP, STM, MSI Planet, VRML ElevationGrid, RAW, ChunkLOD (.chu), PNG 16-bit, 3TX, and more.
> 0 votes

---
Tags: unity, terrain, terrain-rendering, heightmap
---


# Question
Title: Efficient way of drawing outlines around sprites
I'm using XNA to program a game, and have been experimenting with various ways to achieve a 'selected' effect on my sprites. The trouble I am having is that each clickable that is drawn in the spritebatch is drawn using more than a single sprite (each object can be made up of up to 6 sprites).

I'd appreciate it if someone could advise me on how I could achieve adding an outline to my sprites of X pixels (so the outline width can be various numbers of whole pixels).

Thanks in advance,

* Greg.

# Answer
By far the easiest way to do this (so probably the best way, unless you are really strapped for performance) is to have two copies of your sprites.

* The regular version
* A"fat", uncoloured version - basically a white version of your sprite X-many pixels "fatter" than the original.

**Draw your entire object using the "fat" version, then draw the regular version over the top.**

By making the "fat" version white, you can use SpriteBatch's built-in colour tinting to change the selection colour dynamically.

To generate your "fat" verison I recommend writing a Content Pipeline Extension that can automatically take your original sprites, read their alpha channel, create a new alpha channel by sampling the maximum alpha channel in the original image X-many pixels around each pixel, and setting RGB = (1,1,1).

You will have to make sure your sprites all have sufficient transparent border to add the outline (you could check this in the content processor - and even make room if necessary).

If you only have a few sprites, then you could just use a good image editor (GIMP, Photoshop) and do it by hand: Alpha channel to selection, expand selection, selection to alpha, fill colour channels white.
> 20 votes

# Answer
I guess you need to draw all the pieces who each object to a single sprite first. Then I think you'd have to write a shader to detect the edges of the sprite a draw a pixel where-ever it finds an edge. I expect there must be some shaders out there already to do this, which you could either use or port.
> 4 votes

# Answer
Depending on requirements, what might also be effective is just creating an outline on-demand for the sprite. I'm assuming your sprites have transparency, and are irregularly shaped rather than just being rectangles (while this would work fine for that, outline rectangles should be Trivial).

```
when selected:
   outline = new sprite canvas of appropriate size
   for sprite in object:
      # use larger numbers for thicker outlines
      for x in (-1, 0, 1) and y in (-1, 0, 1):
         render sprite mask into canvas at x,y with desired color

```

Note that you don't need to do this every draw (although I suppose you could), but just create the new outline sprite when switching sprites.
> 4 votes

# Answer
The simplest brute force approach is to build two copies of each sprite, a normal and a highlighted one. Then just swap them when highlighted.

If you've got memory to spare there is no need to get more complicated then that. Plus artists have complete control over the look when highlighted so you can do an outline or anything else you'd like.
> 1 votes

# Answer
How about for each sprite, also have another sprite that's an outline of the base sprite. When drawing an outlined object, draw the base sprites, then make a mask of the combined rendering, then draw the outline sprites excluding the mask.
> 1 votes

# Answer
A few different solutions with different trade offs.

Easiest: Render the object using a flat color multiple times and jitter the position (offset left, up, down, right etc), this will create an outlines version of whatever you render on top of it, but has performance costs and won’t allow for fat borders without a lot of extra renders. A one or two pixel border may be okay with 4x.

Fastest: Preprocess the texture and have a copy that is already bordered, or is just the border, or is a flat greyscale 8-bit mask that you can colorize in a shader. This will likely be fast at the cost of memory.

Best: My opinion, but generating a Signed Distance Field (SDF) representation of your object would likely be the best solution. These textures can be much smaller than the source texture and still capture useful data. Essentially each pixel encodes how far away it is from the object used to generate it. With this data in hand, you can write all kinds of effects from glows to outlines. The border could change in size and color etc, and is still a relatively cheap shader and only one extra draw. Downside is tooling, and preprocessing.
> 1 votes

# Answer
I'm not sure of effiency, but the easiest way I can see would be to draw a larger version of the sprite in the colour you want selected first. Draw the sprite on top of that. You'll only see the edge of the first sprite, giving the effect of selection.

EDIT: However, as you can see from the comments, this isn't a good idea.
> 0 votes

# Answer
I agree with scaling up the sprite. By Far the easiest route, and you can apply it to selecting ANY sprite without having to create additional sprites especially for this purpose.

* i.e. spriteOutline.Scale = spriteOriginal.Scale * 0.1f; spriteOutline.Color = new Color(255, 0, 0, 255);
> 0 votes

# Answer
Replace the color of the original sprite with outline color (or even tint it if you like). Render this flat-shaded or tinted sprite four times with a 1 pixel offset: at x,y =(-1,-1), then (+1,-1), then (-1,+1) then (+1, +1). Repeat for all sprites that make up the object.

After that, render the original sprites in proper order on top at (0,0).
> 0 votes

---
Tags: 2d, xna, sprites
---


# Question
Title: Error: "JSON must represent an object type" when parsing array of objects
I'm trying to use Json to hold game dialog in a text asset file. I've tried to make a barebones project to test this and it is failing with the Error Message: ArgumentException: JSON must represent an object type.

I have a class called LineData which has a few properties each line of dialog contains. In the Json there are just two lines for now. When I import and parse it to try and make a reference to one of the lines of dialog it fails.

Here is all the code:

**dialogJson.JSON:**

```
[
{
    "lineID": "BEDROOM_DAVE_0001",
    "lineDialog": "Yaawwn, up i get for another fun packed day.",
    "lineDuration": 3
},
{
    "lineID": "BEDROOM_DAVE_0002",
    "lineDialog": "Well I think I need a cigarette before I get to work!",
    "lineDuration": 3
}
]

```

**LineData.cs**

```
using System;

[Serializable]
public class LineData
{
    public string lineID;
    public string lineDialog;
    public float lineDuration;
}

```

**GameController.cs**

```
using UnityEngine;

public class GameController : MonoBehaviour
{
    TextAsset Dialog_Data;

    private void Start()
    {
        Dialog_Data = Resources.Load<TextAsset>("txt/dialogJson");

        LineData line1 = JsonUtility.FromJson<LineData>(Dialog_Data.text);
        Debug.Log("line 1 dialog = " + line1.lineDialog);
    }
}

```

NOTE: I read here (https://answers.unity.com/questions/1503047/json-must-represent-an-object-type.html) that Unity "can't parse if the json consists of an array of objects". But I don't understand his explanation on how to get around this. Thanks

EDIT: I now have it without error, but the debug message is just empty didnt seem to get any data) . Here is the json now after the edits:

```
{ "LineData":
[
{
    "lineID": "BEDROOM_DAVE_0001",
    "lineDialog": "Yaawwn, up i get for another fun packed day.",
    "lineDuration": 3
},
{
    "lineID": "BEDROOM_DAVE_0002",
    "lineDialog": "Well I think I need a cigarette before I get to work!",
    "lineDuration": 3
}
]
}

```

I've also altered the GameController.cs like this (but now it says Index is outside array bounds:

```
public class GameController : MonoBehaviour
{
TextAsset Dialog_Data;

private void Start()
{
    LineData[] lines = new LineData[2];
    Dialog_Data = Resources.Load<TextAsset>("txt/dialogJson");
    lines = JsonUtility.FromJson<LineData[]>(Dialog_Data.text);
    Debug.Log("line 1 dialog = " + lines[0].lineDialog);
}
}

```

# Answer
When you write a line like this:

```
LineData line1 = JsonUtility.FromJson<LineData>(Dialog_Data.text);

```

You're saying "the JSON in this text string represents exactly one instance of the type `LineData`". ie. the program is expecting something like this:

```
{
    "lineID": "BEDROOM_DAVE_0001",
    "lineDialog": "Yaawwn, up i get for another fun packed day.",
    "lineDuration": 3
}

```

That's everything it needs to be able to populate exactly one `LineData` object.

When instead you give it JSON like this:

```
[
    {
        "lineID": "BEDROOM_DAVE_0001",
        "lineDialog": "Yaawwn, up i get for another fun packed day.",
        "lineDuration": 3
    },
    {
        "lineID": "BEDROOM_DAVE_0002",
        "lineDialog": "Well I think I need a cigarette before I get to work!",
        "lineDuration": 3
    }
]

```

Then you're breaking your promise to the program that you were going to give it exactly one instance of type `LineData`. Instead you've given it *two* instances packed into an array of type `LineData[]`. In the eyes of a CPU, this is as different as being handed a chocolate bar to eat versus having a shipping container full of chocolate bars dropped on your foot. ;)

So, we need to tell the program to expect a shipping container. First, by defining what a shipping container full of `LineData` looks like:

```
[Serializable]
public class LineDataCollection {
    public LineData[] lines;
}

```

Then formatting our JSON to match this definition (one member named "lines" that holds an array of LineData objects):

```
{
    "lines": [
        { /* Your first line data goes here */ },
        { /* Your second line data goes here... */ }
     ]
}

```

Then we need to tell our code to unpack a shipping container worth from the text, instead of just one `LineData`:

```
LineDataCollection allLines = JsonUtility.FromJson<LineDataCollection>(Dialog_Data.text);
// Select the first line from the collection, and print its dialogue:
Debug.Log("line 1 dialog = " + allLines.lines[0].lineDialog);

```
> 2 votes

---
Tags: unity, c#, serialization, json
---


title: Doubt about font inclusion (GAMEMAKER)?

text:
# Question
Title: Doubt about font inclusion (GAMEMAKER)?
The default font of the GameMaker is **arial**, but it does not contain special characters that are present in the **portuguese language**.

Soon I had to add a new font, but I activated the **ASCII** option so that the characters I needed were included.

Hence come my doubt: Even the new font being arial I need to enable the option **include in Asset Package** for the game to work properly?

And if I have to enable it, where I put the file, and more. Does it need to have a specific name?

# Answer
> 0 votes
Game Maker takes the fonts installed in the OS. You should include your font in your asset package when it is a font you downloaded and is not present in other systems where the game is to be played. Anyway, what GM does is to create a PNG file with all the glyphs selected in the font properties in the same way as a sprite font.

---
Tags: game-maker, fonts
---


# Question
Title: What is the difference between phy_position_x and x in GameMaker: Studio?
This is not covered anywhere in the documentation that I can find.

I am using the physics engine, and the reported phy\_position\_x and x values are different, such that (phy\_position\_x, phy\_position\_y) is (0, 0) and (x, y) is (origin x, origin y).

Why are they different and is one preferred over the other in code?

# Answer
It appears that `phy_position_x` and `phy_position_y` are in the top-left of the object fixture.

`x` and `y` are at the sprite origin.

The `phy_com_x` and `phy_com_y` are at the center point of the fixture. These are usually the same as the sprite origin. In the documentation, linked here, there is a way to modify this, but initially it is the center of the collision shape from the Physics panel.
> 0 votes

# Answer
You can see the documentation for all three:

> **Returns**: Real
>
> **Description**: The x value of an instance is the horizontal position in the current room, measured in pixels. This value can be either 0, positive or minus, where 0 is the left hand side of the room and moving right increases x, moving left decreases x (a negative value for x means that the instance has gone outside the left side of the room). You can even give x a real value like 12.345, but as you cannot get .345 of a pixel, the instance may not appear to have moved, although these values will be maintained and used internally by GameMaker: Studio and are perfectly valid.
>
> By setting the x (and y) values you can make the object jump around the room to the position of your choice, or you can add and subtract to them by smaller amounts to give the illusion of movement without actually using the built in speed and direction functions. This should be taken into account when making your games as often one type of movement lends itself to a particular style of game-play more than another.

phy\_position\_x

> **Returns**: Real
>
> **Description**: This variable can be used to get (or to set) the x position of the instance within the game room physics world. Please note that the physics world may present errors when instances are moved by directly setting this variable as it will interrupt the continuous simulation.

phy\_com\_x

> **Returns**: Real
>
> **Description**: This read-only variable will return the x position of the instances center of mass. This is calculated automatically based on the density, inertia and mass of the instance as defined by the appropriate functions.

As the name implies, the `phy_position_x` is the position of the physics object that's representing the object. It's different from the `phy_com_x` because the `phy_com_x` is at the center of the mass of the physics object, most likely at the center of the object.
> 2 votes

# Answer
phy\_position\_x and phy\_position\_y are the position variables for use on a physics enabled world. x and y variables are the position of an object in a world (room) without physics.

That's the diference of them.
> 0 votes

---
Tags: game-maker
---


title: Getting event types in Pygame

text:
# Question
Title: Getting event types in Pygame
I want to have the type of an event from the event queue to decide certain actions (i.e. if it is a joystick event or a keyboard one), but the `dir` of events is an empty list:

```
for e in pygame.event.get():
    print dir(e)

```

Although in the documentation i read:

> The queue is a regular queue of pygame.event.EventTypepygame object for representing SDL events event objects

i can't access a `__dict__` attribute. The above code prints a bunch of empty lists: `[] [] [] []` etc. In pygame 1.9.4 installed from pip i could run:

```
if e.type == pygame.JOYBUTTONDOWN:
    e.__dict__["joy"]

```

and i could get the number of joystick button pressed, but this is not working in 1.9.4 installed with `sudo apt install` (on Debian):

```
print event.__dict__
AttributeError: event member not defined

```

# Answer
> 1 votes
You should do if-elif-elif with e.type. First import the event constants you need to check from pygame.constants For example

```
from pygame.constants import QUIT, MOUSEBUTTONDOWN
while true:
    for e in pygame.event.get():
        if e.type == QUIT:
            #close the game
        elif e.type == MOUSEBUTTONDOWN:
            #mouse click

```

The dir() function gives the directory where a module is located, that doesn't work as you think

---
Tags: python, pygame
---


title: Specific path for ai for follow

text:
# Question
Title: Specific path for ai for follow
I have an entity's following details:

* x, y
* vx, vy
* angle to x axis
* its target

I want to reach the target by a parabolic path, how to implement an ai that follow a particular path from any given point to another like parabolic or sine wave.

# Answer
Any quadratic Bézier curve traces out a parabola, so we just need three control points. We already have two - the object's initial position and its target, so we need just one more.

To ensure continuity with the object's initial position, we can place the middle control point along the line `(x + u * vx, y + u * vy)` for any positive coefficient `u` we like.

Then we can plot the complete path from the start position `P`, via this middle control point `M`, to the target point `T` by varying the parameter `s` from 0 to 1:

$$p(s) = (1-s)^2 P + 2s(1-s)M + s^2 T$$

We can also think of this parabola as a ballistic trajectory under a constant acceleration `a`. over a time duration `t = 2u`, using the value of `u` we picked above to select the middle control point `M`.

The constant acceleration vector `a`is then:

$$a = \left(T - \left(P + t * V\right)\right)\frac 2 {t^2}$$

(Where `V` is the initial velocity)

This is based on the Bézier constructions used in this previous answer about acceleration planning.
> 2 votes

# Answer
Take a look at my answer here

With this basics of letting an Object follow a path, you just need to create an animation curve containing your specific shaped path and let the Object follow it. Just fill the animation curve with keyframes "by hand" or copy the values of e.g. the Mathf.sin function into it.

You can iterate the next point to move to by just passing the time as index (needs to be converted to integer) for the next keyframe of the animation curve. More keyframes smoothen the movement and makes the object follow your curve more accurately.
> 0 votes

# Answer
The term "parabolic" is confusing here. I will assume that you just mean that the movement has to be smooth, without hard discontinuities.

If you properly steer your NPC, their routes will automatically be curve-like and smooth. What is proper steering? You need to steer them doubly-indirect.

This means:

1. you do not set their positions directly.
2. You do not even set their velocities directly.
3. You set an acceleration (or a force on their physics body.)

The force/acceleration will lead to a change in their velocity, which will lead to a change in their position.

Making an NPC reach a certain location in the world then becomes a hard task: you need to steer towards their goal, if still far away from it. When near, you need to steer in the opposite direction to slow them down, otherwise they will overshoot the target location.

The best tool to steer your NPC around a world by settings forces, is the Proportional Integral Differential Controller, or PID Controller.

I wrote a primer on PID Control that will get you up to speed. It includes code.

Personally, I use two PID controllers per NPC. One PID controller to move fw/bw, and a second PID controller (angular) to turn L/R.
> 0 votes

---
Tags: physics, ai
---


# Question
Title: Unity game crashing when dialogue with NPC initiated
I have 3 NPCs in my "Game". When the player walks up to any of them, they're supposed to have their own dialogue; I've tested this, and they do.

I tried to create a display that shows this dialogue text using a TextMeshProUGUI attached to a blank GameObject called dialogDisplay (tagged DialogDisplay). There is one DialogDisplay object in the scene that I'm trying to get each of my NPC's to use. I tried to make the display object inactive in the NPC Start() function, and enable it when it's time to display the NPC's next sentence.

When I run my game, I get an error on line 21, where SetActive() is called: "Object Reference Not Set to an Instance of an Object".

Here's the NPC script (DisplayNextSentence() is at the bottom, where dialogDisplay is used):

```
public class NPC : Character {
private bool charInRange;
public Dialogue dialogue;
public bool talkedTo = false;
private Queue<string> sentences;
public TextMeshProUGUI textPro;
public GameObject dialogDisplay;
private bool isTalking;

// Use this for initialization
void Start () {
    charInRange = false;
    textPro = FindObjectOfType<TextMeshProUGUI>();
    dialogDisplay = GameObject.FindGameObjectWithTag("DialogDisplay");
    dialogDisplay.SetActive(false);
}

// Update is called once per frame
void Update () {
    //if player is in range and presses space, triggers NPC dialogue
    if (charInRange && Input.GetKeyDown(KeyCode.Space))
    {
        TriggerDialogue();
    }
}

//if Player gameObject is in NPC collider, player is in range
void OnTriggerEnter2D(Collider2D other)
{
    if(other.gameObject.tag == "Player")
    {
        charInRange = true;
    }
}

//if player exits NPC collider, player is not in range
void OnTriggerExit2D(Collider2D other)
{
    if (other.gameObject.tag == "Player")
    {
        charInRange = false;
    }
}

//if NPC has been talked to before, displays next sentence; if not, loads dialogue and displays first sentence
private void TriggerDialogue()
{
    if (!talkedTo)
    {
        talkedTo = true;
        StartDialogue(dialogue);
    }
    else
    {
        DisplayNextSentence();
    }
}

//loads a queue with lines from Dialogue and displays first sentence
public void StartDialogue(Dialogue dialogue)
{
    sentences = new Queue<string>();

    foreach (string sentence in dialogue.sentences)
    {
        sentences.Enqueue(sentence);
    }

    DisplayNextSentence();
}

//displays next sentence in the queue
public void DisplayNextSentence()
{
    string sentence;
    bool done = false;

    //if last sentence in the queue, display it again
    if (sentences.Count == 1)
    {
        sentence = sentences.Peek();
        textPro.text = sentence;
        Debug.Log(sentence);
        return;
    }

    sentence = sentences.Dequeue();
    textPro.text = sentence;
    dialogDisplay.SetActive(true);
    while (!done) {
        Debug.Log("In WHile Looop");
        if (Input.GetKeyDown(KeyCode.A))
        {
            done = true;
        }
    }
    dialogDisplay.SetActive(false);
}
}

```

Grateful for any insight or tips you can provide. Happy to provide further information if it helps. Thank you!

# Answer
> 1 votes
"Object Reference Not Set to an Instance of an Object" occurs when whatever Object you're trying to use doesn't actually contain anything.

It is most likely coming from `dialogDisplay = GameObject.FindGameObjectWithTag("DialogDisplay");`, check to see if the GameObject in the scene has that tag attached to it.

---
Tags: unity, c#
---


# Question
Title: How do you setup a scrollable overworld map on an HTML/JQuery based game?
**Problem and Requirements**

I'm putting together a simple game that will involve an overworld map consisting of 12px x 12px square terrain tiles. These maps may be as large as 500x500 in size (so 250k tiles). I would like the player to be able to drag their way around this map quickly and easily, much like you can in Lords Mobile or other similar mobile games.

It would be preferable if the user could easily zoom in and out. I will also be placing interactive 'nodes' of various sorts on this map.

**Technologies and Stats**

Languages:

* Lucee backend to generate these maps
* HTML and JQuery for display
* I'm willing to use other Javascript libraries, but would prefer not to have to learn some whole new framework unless absolutely necessary.

Devices:

* Game will be designed primarily for mobile devices, but should run in any browser on any device.
* Due to mobile support, resources will be limited.
* I will likely create an Android app made up of a splash screen and a webview. My Java skills are lacking (and I dislike Java) so I really don't want a Java based solution.

Map Stats:

* Maps are expected to be between 200x200 and 500x500.
* They may need to be larger, possibly in excess of 1200x1200. So I would like a scaleable approach.

**Possible/Rejected Solutions**

The obvious first thought was to create a large container div, and an \< img \> for each tile absolutely positioned within that container. However, a quarter of a million img tags, each with events attached, is insane, so I rejected this almost as soon as I thought of it. I tested it anyway on my gaming PC just in case and memory usage shot through the roof and there was significant lag. This would be completely impractical on a phone or other mobile device.

So then I thought that since the world map won't really ever change, maybe I could create one large image, and just pickup where the player taps via the click event properties and calculate the tile from that. However, for a 500x500 map of 12x12 tiles, that would be a 6000x6000 image (36 megapixel). Again, I would be concerned about a mobile device handling that, especially with hundreds of 'nodes' and other 'stuff' dropped on top of it.

So I thought maybe I could just build a container div at the full 6000x6000 size, and then load terrain tiles just for the 30-40 terrains within (and surrounding) the viewport. As the user tries to scroll I could dynamically generate the other img tags based on data either from an AJAX call or an array that holds all of the terrain data (if it's not too resource intensive). This seems overly complex, though, and I'd prefer a simpler solution, especially if this is going to lead to any sort of lag.

**Question**

How do other HTML/Javascript based games handle this sort of large scale overworld map? I can try to muddle through this myself, but this must be a very common need and I'm sure there are great solutions already out there.

# Answer
> 2 votes
Well, Jay's answer was technically correct, and gave me a good starting point. So +1 to him for that. However, I wanted to take the time to post a fuller answer for others who happen across this question, now that I've figured out some basics.

**The Various Attempts**

First, I wanted to talk about the other possibilities I explored:

* First I tried using CFML to create the HTML code on the server and write it out to the browser, as described in the question. For a 200x200 tile map it took over 20 seconds to load and render on a PC. This was obviously unworkable.
* Then I tried stitching the tiles together into one large image, as described above. As a PNG its filesize was 62MB. I didn't bother going any further here.

I settled on the idea of loading only a small portion of the total map at a time, since the user can only see a few tiles anyway, and all of my following attempts built on that approach.

* For my first partial success, I tried having JS pull a list of all local tiles (within 10 tiles of the viewing position) from the database in array format, which took a few hundred ms. Then I looped through that, looked to see if a tile was drawn for those coordinates yet, and wrote an img tag out to a container div if not. This processed in a few hundred ms too. However, after 40+ tiles were loaded the 'draggable' animation became very choppy on mobile, and after a 1000 or so the same happened on PC. Even a 200x200 map would contain 40k tiles, so this code was set aside as a backup.
* Next I explored a very similar approach, except that instead of writing img files into a div I drew the images out to a canvas element. This worked exceptionally well; not only did it load and run faster than the last attempt, but the choppiness went away completely. Regardless of how many tiles I drew into the canvas, it dragged as a whole with perfect smoothness. Much closer!
* However, each time the canvas was dragged and I had to go out to the server for more tile data, I incurred another 500+ ms hit. This was bothersome, not to mention the server strain caused by all those requests. So I decided to try loading the whole array of tile data at the start, now that everything else was running smoothly. To my surprise, even my phone didn't hesitate at loading a full 200x200 array into memory. That allowed me to cut out the ajax call completely and just to on-demand draws to the canvas based on in-memory data. Sweet!

By the end of the night I had a scrollable map, that loaded into a phone without hesitation, with smooth animation, just waiting for interactive elements to be dropped on top.

**Final Working Example**

My actual code has a number of dependencies, but here is a rudimentary example. It still needs some work, but demonstrates the basic principles in a functional script:

```
<head>
    <!DOCTYPE html>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">

    <script     src="https://code.jquery.com/jquery-3.3.1.min.js"
                integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
                crossorigin="anonymous"></script>
    <script     src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
                integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
                crossorigin="anonymous"></script>
    <script src="/JS/jquery.ui.touch-punch.min.js" type="text/javascript"></script>
    <script src="/JS/utilityFunctions.js" type="text/javascript"></script>
</head>

<style>
    #mapContainer   {width:500px; height:500px; overflow:hidden;}
    #mapCanvas      {width:2500px; height:2500px;}
    .terrainTile    {width:50; height:50; position:absolute;}
</style>

<div id="mapContainer">
    <canvas id="mapCanvas" width="2500" height="2500">

    </canvas>
</div>

<script>
    var realmSize       = 50;       // Total number of tiles on each axis
    var divSize         = 2500;     // Total canvas size in pixels: realmSize * tileSize
    var containerSize   = 500;      // Size of the viewable area
    var tileSize        = 50;       // Size of each tile
    var curPosX         = 3;        // Default current position
    var curPosY         = 3;
    var minDragXY       = 0 - (divSize - containerSize);    // The furthest we can drag the canvas (so it's edge lines up with the container's edge)
    var loadTileDelta   = 5;        // How far in any direction to load onto the canvas
    var terrainImgArr   = [];

    // First we load the images we want to use for the tiles.  I named mine to correspond to the terrain ID in my database for now.
    for (x=1; x<=13; x++) {
        terrainImgArr[x] = new Image(tileSize, tileSize);
        terrainImgArr[x].src = '/imgs/' + x + '.png';
    }

    // Create a three dimensional JS array of realmSize x realmSize x 2.  For any given x,y position, this will hold the terrain ID value in one cell and whether it's been drawn to the screen yet in the other.
    var mapTerrain  = ThreeDimensionalArray(realmSize, realmSize, 2);

    function mapLoad() {
        // This function does an ajax call to go out and get the data from my database.  I copied and pasted the response here so anyone viewing this can have a working demo...
        var mapData = "1,1,12|1,2,12|1,3,12|1,4,12|1,5,12|1,6,12|1,7,12|1,8,6|1,9,6|1,10,6|1,11,12|1,12,12|1,13,12|1,14,6|1,15,6|1,16,1|1,17,1|1,18,1|1,19,1|1,20,2|1,21,2|1,22,2|1,23,12|1,24,13|1,25,13|1,26,12|1,27,3|1,28,3|1,29,1|1,30,1|1,31,1|1,32,8|1,33,1|1,34,1|1,35,1|1,36,1|1,37,1|1,38,1|1,39,1|1,40,1|1,41,1|1,42,2|1,43,2|1,44,2|1,45,2|1,46,2|1,47,2|1,48,2|1,49,2|1,50,2|2,1,12|2,2,12|2,3,12|2,4,12|2,5,12|2,6,12|2,7,6|2,8,6|2,9,6|2,10,6|2,11,6|2,12,6|2,13,6|2,14,6|2,15,1|2,16,1|2,17,1|2,18,1|2,19,1|2,20,2|2,21,2|2,22,2|2,23,12|2,24,12|2,25,12|2,26,12|2,27,3|2,28,3|2,29,3|2,30,1|2,31,8|2,32,8|2,33,8|2,34,1|2,35,1|2,36,1|2,37,1|2,38,1|2,39,1|2,40,1|2,41,1|2,42,1|2,43,2|2,44,2|2,45,2|2,46,2|2,47,2|2,48,2|2,49,2|2,50,2|3,1,6|3,2,6|3,3,6|3,4,2|3,5,2|3,6,6|3,7,6|3,8,6|3,9,6|3,10,6|3,11,6|3,12,6|3,13,6|3,14,6|3,15,1|3,16,1|3,17,1|3,18,1|3,19,1|3,20,2|3,21,2|3,22,2|3,23,2|3,24,12|3,25,12|3,26,6|3,27,3|3,28,3|3,29,3|3,30,8|3,31,8|3,32,8|3,33,8|3,34,8|3,35,1|3,36,1|3,37,1|3,38,1|3,39,1|3,40,3|3,41,3|3,42,3|3,43,1|3,44,2|3,45,2|3,46,2|3,47,2|3,48,2|3,49,2|3,50,2|4,1,6|4,2,6|4,3,2|4,4,2|4,5,2|4,6,2|4,7,6|4,8,6|4,9,6|4,10,6|4,11,6|4,12,6|4,13,6|4,14,2|4,15,1|4,16,1|4,17,1|4,18,1|4,19,1|4,20,2|4,21,2|4,22,2|4,23,2|4,24,12|4,25,12|4,26,6|4,27,3|4,28,3|4,29,3|4,30,8|4,31,8|4,32,8|4,33,8|4,34,8|4,35,1|4,36,1|4,37,1|4,38,1|4,39,1|4,40,3|4,41,3|4,42,3|4,43,1|4,44,2|4,45,2|4,46,2|4,47,2|4,48,2|4,49,2|4,50,2|5,1,6|5,2,2|5,3,1|5,4,1|5,5,1|5,6,1|5,7,1|5,8,6|5,9,6|5,10,6|5,11,1|5,12,2|5,13,2|5,14,2|5,15,1|5,16,1|5,17,1|5,18,1|5,19,1|5,20,1|5,21,2|5,22,2|5,23,2|5,24,6|5,25,6|5,26,2|5,27,1|5,28,3|5,29,3|5,30,8|5,31,8|5,32,8|5,33,8|5,34,8|5,35,1|5,36,1|5,37,1|5,38,1|5,39,1|5,40,3|5,41,3|5,42,1|5,43,1|5,44,2|5,45,2|5,46,2|5,47,2|5,48,2|5,49,2|5,50,2|6,1,6|6,2,2|6,3,1|6,4,1|6,5,1|6,6,1|6,7,1|6,8,1|6,9,1|6,10,1|6,11,2|6,12,2|6,13,2|6,14,2|6,15,2|6,16,1|6,17,1|6,18,1|6,19,1|6,20,1|6,21,2|6,22,2|6,23,2|6,24,2|6,25,2|6,26,2|6,27,1|6,28,1|6,29,1|6,30,1|6,31,1|6,32,8|6,33,8|6,34,8|6,35,1|6,36,1|6,37,2|6,38,2|6,39,2|6,40,1|6,41,1|6,42,1|6,43,1|6,44,2|6,45,2|6,46,2|6,47,2|6,48,2|6,49,2|6,50,2|7,1,6|7,2,1|7,3,1|7,4,1|7,5,1|7,6,1|7,7,1|7,8,1|7,9,1|7,10,2|7,11,2|7,12,2|7,13,2|7,14,2|7,15,6|7,16,6|7,17,1|7,18,1|7,19,1|7,20,1|7,21,1|7,22,2|7,23,2|7,24,2|7,25,2|7,26,1|7,27,1|7,28,1|7,29,1|7,30,1|7,31,1|7,32,1|7,33,8|7,34,8|7,35,1|7,36,1|7,37,2|7,38,2|7,39,2|7,40,2|7,41,1|7,42,1|7,43,1|7,44,2|7,45,2|7,46,2|7,47,2|7,48,2|7,49,2|7,50,2|8,1,6|8,2,1|8,3,1|8,4,8|8,5,8|8,6,1|8,7,1|8,8,1|8,9,2|8,10,2|8,11,2|8,12,2|8,13,2|8,14,6|8,15,6|8,16,6|8,17,6|8,18,1|8,19,1|8,20,1|8,21,1|8,22,2|8,23,2|8,24,2|8,25,1|8,26,1|8,27,1|8,28,1|8,29,1|8,30,1|8,31,1|8,32,1|8,33,8|8,34,8|8,35,1|8,36,1|8,37,2|8,38,2|8,39,2|8,40,2|8,41,1|8,42,1|8,43,1|8,44,2|8,45,2|8,46,2|8,47,2|8,48,2|8,49,2|8,50,2|9,1,6|9,2,1|9,3,1|9,4,8|9,5,8|9,6,1|9,7,1|9,8,1|9,9,2|9,10,2|9,11,6|9,12,6|9,13,6|9,14,6|9,15,6|9,16,6|9,17,6|9,18,1|9,19,1|9,20,1|9,21,1|9,22,2|9,23,2|9,24,2|9,25,2|9,26,2|9,27,2|9,28,2|9,29,2|9,30,2|9,31,1|9,32,1|9,33,1|9,34,8|9,35,1|9,36,1|9,37,2|9,38,2|9,39,2|9,40,2|9,41,1|9,42,1|9,43,1|9,44,2|9,45,2|9,46,2|9,47,2|9,48,2|9,49,2|9,50,2|10,1,6|10,2,1|10,3,1|10,4,8|10,5,8|10,6,1|10,7,1|10,8,1|10,9,2|10,10,2|10,11,2|10,12,6|10,13,6|10,14,6|10,15,6|10,16,6|10,17,6|10,18,1|10,19,1|10,20,1|10,21,2|10,22,2|10,23,2|10,24,2|10,25,2|10,26,2|10,27,2|10,28,2|10,29,2|10,30,2|10,31,2|10,32,1|10,33,1|10,34,1|10,35,1|10,36,1|10,37,1|10,38,2|10,39,2|10,40,2|10,41,3|10,42,1|10,43,1|10,44,2|10,45,2|10,46,2|10,47,2|10,48,2|10,49,2|10,50,2|11,1,6|11,2,1|11,3,1|11,4,1|11,5,8|11,6,1|11,7,1|11,8,1|11,9,2|11,10,2|11,11,2|11,12,2|11,13,2|11,14,6|11,15,6|11,16,6|11,17,6|11,18,1|11,19,1|11,20,2|11,21,2|11,22,2|11,23,2|11,24,2|11,25,2|11,26,2|11,27,2|11,28,2|11,29,2|11,30,2|11,31,2|11,32,1|11,33,1|11,34,1|11,35,1|11,36,1|11,37,1|11,38,2|11,39,2|11,40,2|11,41,1|11,42,1|11,43,2|11,44,2|11,45,2|11,46,2|11,47,2|11,48,2|11,49,2|11,50,2|12,1,6|12,2,6|12,3,1|12,4,1|12,5,8|12,6,1|12,7,1|12,8,1|12,9,2|12,10,2|12,11,2|12,12,1|12,13,1|12,14,1|12,15,1|12,16,6|12,17,6|12,18,1|12,19,2|12,20,2|12,21,2|12,22,2|12,23,2|12,24,2|12,25,2|12,26,2|12,27,2|12,28,2|12,29,2|12,30,2|12,31,2|12,32,1|12,33,1|12,34,8|12,35,8|12,36,1|12,37,1|12,38,2|12,39,2|12,40,2|12,41,2|12,42,2|12,43,2|12,44,2|12,45,2|12,46,2|12,47,2|12,48,2|12,49,2|12,50,2|13,1,6|13,2,6|13,3,1|13,4,1|13,5,8|13,6,8|13,7,1|13,8,1|13,9,1|13,10,1|13,11,1|13,12,1|13,13,1|13,14,1|13,15,1|13,16,2|13,17,2|13,18,2|13,19,2|13,20,2|13,21,2|13,22,2|13,23,2|13,24,2|13,25,3|13,26,3|13,27,2|13,28,2|13,29,2|13,30,2|13,31,2|13,32,1|13,33,1|13,34,8|13,35,8|13,36,1|13,37,1|13,38,1|13,39,2|13,40,2|13,41,2|13,42,2|13,43,2|13,44,2|13,45,2|13,46,2|13,47,2|13,48,2|13,49,1|13,50,2|14,1,6|14,2,6|14,3,1|14,4,1|14,5,8|14,6,8|14,7,1|14,8,1|14,9,1|14,10,1|14,11,1|14,12,1|14,13,1|14,14,1|14,15,1|14,16,2|14,17,2|14,18,2|14,19,2|14,20,2|14,21,2|14,22,2|14,23,2|14,24,3|14,25,3|14,26,3|14,27,2|14,28,2|14,29,2|14,30,2|14,31,1|14,32,1|14,33,8|14,34,8|14,35,8|14,36,1|14,37,1|14,38,1|14,39,2|14,40,2|14,41,2|14,42,2|14,43,2|14,44,2|14,45,2|14,46,2|14,47,2|14,48,1|14,49,1|14,50,1|15,1,6|15,2,6|15,3,6|15,4,1|15,5,8|15,6,8|15,7,8|15,8,1|15,9,1|15,10,1|15,11,1|15,12,1|15,13,1|15,14,1|15,15,1|15,16,2|15,17,2|15,18,2|15,19,2|15,20,2|15,21,2|15,22,2|15,23,2|15,24,2|15,25,3|15,26,2|15,27,2|15,28,2|15,29,2|15,30,2|15,31,1|15,32,1|15,33,8|15,34,8|15,35,8|15,36,1|15,37,1|15,38,1|15,39,2|15,40,2|15,41,2|15,42,2|15,43,2|15,44,2|15,45,2|15,46,2|15,47,1|15,48,1|15,49,1|15,50,1|16,1,6|16,2,6|16,3,6|16,4,1|16,5,1|16,6,8|16,7,8|16,8,1|16,9,1|16,10,1|16,11,1|16,12,1|16,13,1|16,14,1|16,15,2|16,16,2|16,17,2|16,18,2|16,19,2|16,20,2|16,21,2|16,22,2|16,23,2|16,24,2|16,25,2|16,26,2|16,27,2|16,28,2|16,29,2|16,30,2|16,31,1|16,32,1|16,33,8|16,34,8|16,35,1|16,36,1|16,37,1|16,38,1|16,39,2|16,40,2|16,41,2|16,42,2|16,43,2|16,44,2|16,45,2|16,46,2|16,47,2|16,48,1|16,49,1|16,50,1|17,1,6|17,2,6|17,3,6|17,4,1|17,5,1|17,6,1|17,7,1|17,8,1|17,9,1|17,10,1|17,11,1|17,12,1|17,13,1|17,14,1|17,15,2|17,16,2|17,17,2|17,18,2|17,19,2|17,20,2|17,21,2|17,22,2|17,23,2|17,24,2|17,25,2|17,26,2|17,27,2|17,28,2|17,29,2|17,30,1|17,31,1|17,32,8|17,33,8|17,34,8|17,35,1|17,36,1|17,37,1|17,38,2|17,39,2|17,40,2|17,41,2|17,42,2|17,43,2|17,44,2|17,45,2|17,46,2|17,47,2|17,48,1|17,49,1|17,50,1|18,1,6|18,2,6|18,3,6|18,4,1|18,5,1|18,6,1|18,7,1|18,8,1|18,9,1|18,10,1|18,11,1|18,12,1|18,13,1|18,14,1|18,15,2|18,16,2|18,17,2|18,18,2|18,19,2|18,20,2|18,21,2|18,22,2|18,23,2|18,24,2|18,25,2|18,26,2|18,27,2|18,28,2|18,29,2|18,30,1|18,31,1|18,32,8|18,33,8|18,34,1|18,35,1|18,36,1|18,37,1|18,38,2|18,39,2|18,40,2|18,41,2|18,42,2|18,43,2|18,44,2|18,45,2|18,46,2|18,47,2|18,48,1|18,49,1|18,50,1|19,1,6|19,2,6|19,3,6|19,4,1|19,5,1|19,6,1|19,7,1|19,8,1|19,9,1|19,10,1|19,11,1|19,12,1|19,13,1|19,14,1|19,15,2|19,16,2|19,17,2|19,18,2|19,19,2|19,20,6|19,21,6|19,22,6|19,23,2|19,24,2|19,25,2|19,26,2|19,27,2|19,28,2|19,29,2|19,30,1|19,31,1|19,32,1|19,33,8|19,34,1|19,35,1|19,36,1|19,37,1|19,38,2|19,39,2|19,40,2|19,41,2|19,42,2|19,43,2|19,44,2|19,45,2|19,46,2|19,47,2|19,48,1|19,49,1|19,50,1|20,1,12|20,2,6|20,3,6|20,4,1|20,5,1|20,6,1|20,7,1|20,8,1|20,9,1|20,10,1|20,11,1|20,12,1|20,13,1|20,14,1|20,15,2|20,16,2|20,17,2|20,18,2|20,19,2|20,20,6|20,21,6|20,22,6|20,23,2|20,24,2|20,25,2|20,26,2|20,27,2|20,28,2|20,29,2|20,30,1|20,31,1|20,32,1|20,33,1|20,34,1|20,35,1|20,36,1|20,37,2|20,38,2|20,39,2|20,40,2|20,41,2|20,42,2|20,43,2|20,44,2|20,45,2|20,46,2|20,47,2|20,48,1|20,49,1|20,50,1|21,1,12|21,2,6|21,3,2|21,4,1|21,5,1|21,6,1|21,7,1|21,8,1|21,9,1|21,10,1|21,11,1|21,12,1|21,13,1|21,14,2|21,15,2|21,16,2|21,17,2|21,18,2|21,19,2|21,20,2|21,21,6|21,22,6|21,23,2|21,24,2|21,25,2|21,26,2|21,27,2|21,28,2|21,29,2|21,30,1|21,31,1|21,32,1|21,33,1|21,34,1|21,35,1|21,36,1|21,37,2|21,38,2|21,39,2|21,40,2|21,41,2|21,42,2|21,43,2|21,44,2|21,45,2|21,46,2|21,47,2|21,48,2|21,49,2|21,50,1|22,1,6|22,2,6|22,3,1|22,4,1|22,5,1|22,6,1|22,7,1|22,8,1|22,9,1|22,10,1|22,11,1|22,12,1|22,13,1|22,14,1|22,15,2|22,16,2|22,17,2|22,18,2|22,19,2|22,20,2|22,21,2|22,22,2|22,23,2|22,24,2|22,25,2|22,26,2|22,27,2|22,28,2|22,29,2|22,30,1|22,31,1|22,32,1|22,33,1|22,34,1|22,35,1|22,36,2|22,37,2|22,38,2|22,39,2|22,40,2|22,41,2|22,42,2|22,43,2|22,44,2|22,45,2|22,46,2|22,47,2|22,48,2|22,49,1|22,50,3|23,1,6|23,2,6|23,3,1|23,4,1|23,5,1|23,6,1|23,7,1|23,8,1|23,9,1|23,10,1|23,11,1|23,12,1|23,13,1|23,14,1|23,15,2|23,16,2|23,17,2|23,18,2|23,19,2|23,20,2|23,21,2|23,22,2|23,23,2|23,24,2|23,25,2|23,26,2|23,27,2|23,28,2|23,29,1|23,30,1|23,31,1|23,32,1|23,33,1|23,34,1|23,35,2|23,36,2|23,37,2|23,38,2|23,39,2|23,40,2|23,41,2|23,42,2|23,43,2|23,44,2|23,45,2|23,46,2|23,47,2|23,48,2|23,49,3|23,50,3|24,1,6|24,2,2|24,3,1|24,4,1|24,5,1|24,6,1|24,7,1|24,8,1|24,9,2|24,10,1|24,11,1|24,12,6|24,13,6|24,14,1|24,15,2|24,16,2|24,17,2|24,18,2|24,19,2|24,20,2|24,21,1|24,22,1|24,23,1|24,24,2|24,25,2|24,26,1|24,27,1|24,28,1|24,29,1|24,30,2|24,31,2|24,32,2|24,33,1|24,34,2|24,35,2|24,36,2|24,37,2|24,38,2|24,39,2|24,40,2|24,41,2|24,42,2|24,43,2|24,44,2|24,45,2|24,46,2|24,47,2|24,48,2|24,49,3|24,50,3|25,1,6|25,2,2|25,3,1|25,4,1|25,5,1|25,6,1|25,7,1|25,8,2|25,9,2|25,10,1|25,11,1|25,12,6|25,13,6|25,14,1|25,15,1|25,16,2|25,17,2|25,18,2|25,19,1|25,20,1|25,21,1|25,22,1|25,23,1|25,24,1|25,25,1|25,26,1|25,27,1|25,28,1|25,29,1|25,30,2|25,31,2|25,32,2|25,33,2|25,34,2|25,35,2|25,36,2|25,37,2|25,38,2|25,39,2|25,40,2|25,41,2|25,42,2|25,43,2|25,44,2|25,45,2|25,46,2|25,47,2|25,48,2|25,49,3|25,50,3|26,1,6|26,2,2|26,3,2|26,4,1|26,5,1|26,6,1|26,7,1|26,8,2|26,9,1|26,10,1|26,11,6|26,12,6|26,13,1|26,14,1|26,15,1|26,16,1|26,17,1|26,18,1|26,19,1|26,20,1|26,21,1|26,22,1|26,23,1|26,24,1|26,25,1|26,26,1|26,27,1|26,28,1|26,29,1|26,30,2|26,31,2|26,32,2|26,33,2|26,34,2|26,35,2|26,36,2|26,37,2|26,38,2|26,39,2|26,40,2|26,41,2|26,42,2|26,43,2|26,44,2|26,45,2|26,46,2|26,47,2|26,48,3|26,49,3|26,50,3|27,1,6|27,2,6|27,3,1|27,4,1|27,5,1|27,6,1|27,7,1|27,8,1|27,9,1|27,10,1|27,11,6|27,12,1|27,13,8|27,14,1|27,15,1|27,16,1|27,17,1|27,18,1|27,19,1|27,20,1|27,21,1|27,22,1|27,23,1|27,24,1|27,25,1|27,26,1|27,27,1|27,28,1|27,29,2|27,30,2|27,31,2|27,32,2|27,33,2|27,34,3|27,35,2|27,36,2|27,37,2|27,38,2|27,39,2|27,40,2|27,41,2|27,42,2|27,43,2|27,44,2|27,45,2|27,46,2|27,47,2|27,48,3|27,49,3|27,50,3|28,1,6|28,2,6|28,3,1|28,4,1|28,5,1|28,6,1|28,7,1|28,8,1|28,9,1|28,10,1|28,11,1|28,12,1|28,13,8|28,14,1|28,15,1|28,16,1|28,17,1|28,18,1|28,19,1|28,20,1|28,21,1|28,22,1|28,23,1|28,24,1|28,25,1|28,26,1|28,27,1|28,28,1|28,29,2|28,30,2|28,31,2|28,32,2|28,33,3|28,34,3|28,35,2|28,36,2|28,37,2|28,38,2|28,39,2|28,40,2|28,41,2|28,42,2|28,43,2|28,44,2|28,45,2|28,46,2|28,47,2|28,48,3|28,49,3|28,50,3|29,1,6|29,2,6|29,3,1|29,4,1|29,5,1|29,6,1|29,7,1|29,8,1|29,9,1|29,10,1|29,11,1|29,12,1|29,13,8|29,14,8|29,15,1|29,16,1|29,17,1|29,18,3|29,19,3|29,20,1|29,21,1|29,22,1|29,23,1|29,24,1|29,25,1|29,26,1|29,27,1|29,28,1|29,29,2|29,30,2|29,31,2|29,32,2|29,33,3|29,34,3|29,35,2|29,36,2|29,37,2|29,38,2|29,39,2|29,40,2|29,41,2|29,42,2|29,43,2|29,44,2|29,45,2|29,46,2|29,47,2|29,48,3|29,49,3|29,50,3|30,1,6|30,2,6|30,3,1|30,4,1|30,5,1|30,6,1|30,7,1|30,8,1|30,9,6|30,10,6|30,11,1|30,12,1|30,13,8|30,14,8|30,15,8|30,16,1|30,17,1|30,18,1|30,19,3|30,20,1|30,21,1|30,22,2|30,23,1|30,24,1|30,25,1|30,26,1|30,27,1|30,28,1|30,29,2|30,30,2|30,31,2|30,32,2|30,33,3|30,34,3|30,35,2|30,36,2|30,37,2|30,38,2|30,39,2|30,40,2|30,41,2|30,42,2|30,43,2|30,44,2|30,45,2|30,46,2|30,47,2|30,48,3|30,49,3|30,50,3|31,1,6|31,2,6|31,3,8|31,4,8|31,5,8|31,6,8|31,7,1|31,8,1|31,9,1|31,10,1|31,11,1|31,12,1|31,13,1|31,14,8|31,15,8|31,16,1|31,17,1|31,18,1|31,19,1|31,20,1|31,21,1|31,22,2|31,23,1|31,24,1|31,25,1|31,26,1|31,27,1|31,28,1|31,29,2|31,30,2|31,31,2|31,32,2|31,33,3|31,34,3|31,35,2|31,36,2|31,37,2|31,38,2|31,39,2|31,40,2|31,41,2|31,42,2|31,43,2|31,44,1|31,45,1|31,46,2|31,47,2|31,48,3|31,49,3|31,50,3|32,1,6|32,2,6|32,3,8|32,4,8|32,5,8|32,6,8|32,7,8|32,8,8|32,9,1|32,10,1|32,11,1|32,12,1|32,13,1|32,14,8|32,15,8|32,16,1|32,17,1|32,18,1|32,19,1|32,20,1|32,21,1|32,22,1|32,23,1|32,24,1|32,25,1|32,26,1|32,27,1|32,28,1|32,29,2|32,30,2|32,31,2|32,32,2|32,33,3|32,34,3|32,35,2|32,36,2|32,37,2|32,38,2|32,39,2|32,40,2|32,41,2|32,42,2|32,43,2|32,44,1|32,45,1|32,46,2|32,47,2|32,48,2|32,49,2|32,50,3|33,1,6|33,2,6|33,3,6|33,4,8|33,5,8|33,6,8|33,7,8|33,8,1|33,9,1|33,10,1|33,11,1|33,12,1|33,13,1|33,14,1|33,15,8|33,16,1|33,17,1|33,18,1|33,19,1|33,20,1|33,21,1|33,22,1|33,23,1|33,24,1|33,25,1|33,26,1|33,27,1|33,28,1|33,29,2|33,30,2|33,31,2|33,32,2|33,33,2|33,34,2|33,35,2|33,36,2|33,37,2|33,38,2|33,39,2|33,40,2|33,41,2|33,42,2|33,43,2|33,44,2|33,45,1|33,46,2|33,47,2|33,48,2|33,49,2|33,50,2|34,1,6|34,2,6|34,3,6|34,4,6|34,5,8|34,6,1|34,7,1|34,8,1|34,9,1|34,10,1|34,11,1|34,12,1|34,13,1|34,14,1|34,15,1|34,16,1|34,17,1|34,18,1|34,19,1|34,20,1|34,21,1|34,22,1|34,23,1|34,24,1|34,25,1|34,26,1|34,27,1|34,28,1|34,29,1|34,30,2|34,31,2|34,32,2|34,33,2|34,34,2|34,35,2|34,36,2|34,37,2|34,38,2|34,39,2|34,40,2|34,41,2|34,42,2|34,43,2|34,44,2|34,45,2|34,46,2|34,47,2|34,48,2|34,49,2|34,50,2|35,1,6|35,2,6|35,3,6|35,4,6|35,5,6|35,6,1|35,7,1|35,8,1|35,9,1|35,10,1|35,11,1|35,12,1|35,13,1|35,14,1|35,15,1|35,16,1|35,17,1|35,18,1|35,19,1|35,20,1|35,21,1|35,22,1|35,23,1|35,24,1|35,25,1|35,26,1|35,27,1|35,28,1|35,29,1|35,30,2|35,31,2|35,32,2|35,33,2|35,34,2|35,35,2|35,36,2|35,37,2|35,38,2|35,39,2|35,40,2|35,41,2|35,42,2|35,43,2|35,44,2|35,45,2|35,46,2|35,47,2|35,48,2|35,49,2|35,50,2|36,1,6|36,2,6|36,3,6|36,4,6|36,5,6|36,6,1|36,7,2|36,8,2|36,9,2|36,10,2|36,11,1|36,12,1|36,13,1|36,14,1|36,15,1|36,16,1|36,17,1|36,18,1|36,19,1|36,20,1|36,21,1|36,22,1|36,23,1|36,24,1|36,25,1|36,26,1|36,27,1|36,28,1|36,29,1|36,30,2|36,31,2|36,32,2|36,33,2|36,34,2|36,35,2|36,36,2|36,37,2|36,38,2|36,39,2|36,40,2|36,41,2|36,42,2|36,43,2|36,44,2|36,45,2|36,46,2|36,47,2|36,48,2|36,49,2|36,50,2|37,1,6|37,2,6|37,3,6|37,4,6|37,5,6|37,6,1|37,7,2|37,8,2|37,9,2|37,10,2|37,11,2|37,12,1|37,13,1|37,14,1|37,15,1|37,16,1|37,17,1|37,18,1|37,19,1|37,20,1|37,21,1|37,22,1|37,23,1|37,24,1|37,25,1|37,26,1|37,27,1|37,28,1|37,29,1|37,30,2|37,31,2|37,32,2|37,33,2|37,34,2|37,35,2|37,36,2|37,37,2|37,38,2|37,39,2|37,40,2|37,41,2|37,42,2|37,43,2|37,44,2|37,45,2|37,46,2|37,47,2|37,48,2|37,49,2|37,50,2|38,1,6|38,2,6|38,3,2|38,4,2|38,5,1|38,6,2|38,7,2|38,8,2|38,9,2|38,10,2|38,11,2|38,12,1|38,13,1|38,14,1|38,15,1|38,16,1|38,17,1|38,18,1|38,19,1|38,20,2|38,21,1|38,22,1|38,23,1|38,24,1|38,25,1|38,26,1|38,27,1|38,28,1|38,29,1|38,30,2|38,31,2|38,32,2|38,33,2|38,34,2|38,35,2|38,36,2|38,37,2|38,38,2|38,39,2|38,40,2|38,41,2|38,42,2|38,43,2|38,44,2|38,45,2|38,46,2|38,47,2|38,48,2|38,49,2|38,50,2|39,1,12|39,2,2|39,3,2|39,4,2|39,5,1|39,6,2|39,7,2|39,8,2|39,9,2|39,10,2|39,11,2|39,12,1|39,13,1|39,14,1|39,15,1|39,16,1|39,17,1|39,18,2|39,19,2|39,20,2|39,21,2|39,22,1|39,23,1|39,24,1|39,25,1|39,26,1|39,27,1|39,28,1|39,29,1|39,30,2|39,31,2|39,32,2|39,33,2|39,34,2|39,35,2|39,36,2|39,37,2|39,38,2|39,39,2|39,40,2|39,41,2|39,42,2|39,43,2|39,44,2|39,45,2|39,46,2|39,47,2|39,48,2|39,49,2|39,50,2|40,1,12|40,2,2|40,3,2|40,4,2|40,5,1|40,6,1|40,7,2|40,8,2|40,9,2|40,10,2|40,11,2|40,12,1|40,13,1|40,14,1|40,15,1|40,16,1|40,17,2|40,18,2|40,19,2|40,20,2|40,21,2|40,22,1|40,23,1|40,24,1|40,25,1|40,26,1|40,27,1|40,28,1|40,29,1|40,30,2|40,31,2|40,32,2|40,33,2|40,34,2|40,35,2|40,36,2|40,37,2|40,38,2|40,39,2|40,40,2|40,41,2|40,42,2|40,43,2|40,44,2|40,45,2|40,46,2|40,47,2|40,48,2|40,49,2|40,50,2|41,1,12|41,2,2|41,3,2|41,4,1|41,5,1|41,6,1|41,7,2|41,8,2|41,9,2|41,10,2|41,11,2|41,12,1|41,13,1|41,14,1|41,15,1|41,16,1|41,17,2|41,18,2|41,19,2|41,20,2|41,21,2|41,22,1|41,23,1|41,24,1|41,25,1|41,26,1|41,27,1|41,28,1|41,29,2|41,30,2|41,31,2|41,32,2|41,33,2|41,34,2|41,35,2|41,36,2|41,37,2|41,38,2|41,39,2|41,40,2|41,41,2|41,42,2|41,43,2|41,44,2|41,45,2|41,46,2|41,47,2|41,48,2|41,49,2|41,50,2|42,1,6|42,2,6|42,3,2|42,4,1|42,5,1|42,6,1|42,7,1|42,8,2|42,9,2|42,10,2|42,11,2|42,12,1|42,13,1|42,14,1|42,15,1|42,16,1|42,17,2|42,18,2|42,19,2|42,20,2|42,21,1|42,22,1|42,23,1|42,24,1|42,25,1|42,26,1|42,27,1|42,28,2|42,29,2|42,30,2|42,31,2|42,32,2|42,33,2|42,34,2|42,35,2|42,36,2|42,37,2|42,38,2|42,39,2|42,40,2|42,41,2|42,42,2|42,43,2|42,44,2|42,45,2|42,46,2|42,47,2|42,48,2|42,49,2|42,50,2|43,1,6|43,2,6|43,3,6|43,4,6|43,5,1|43,6,6|43,7,6|43,8,2|43,9,2|43,10,2|43,11,2|43,12,1|43,13,1|43,14,1|43,15,1|43,16,1|43,17,2|43,18,2|43,19,2|43,20,2|43,21,1|43,22,1|43,23,1|43,24,1|43,25,1|43,26,1|43,27,2|43,28,2|43,29,2|43,30,2|43,31,2|43,32,2|43,33,2|43,34,2|43,35,2|43,36,2|43,37,2|43,38,2|43,39,2|43,40,2|43,41,2|43,42,2|43,43,2|43,44,2|43,45,2|43,46,2|43,47,2|43,48,2|43,49,2|43,50,2|44,1,6|44,2,6|44,3,6|44,4,6|44,5,6|44,6,1|44,7,1|44,8,1|44,9,2|44,10,2|44,11,2|44,12,1|44,13,1|44,14,1|44,15,1|44,16,1|44,17,2|44,18,2|44,19,2|44,20,2|44,21,1|44,22,1|44,23,1|44,24,1|44,25,1|44,26,1|44,27,2|44,28,2|44,29,2|44,30,2|44,31,2|44,32,2|44,33,2|44,34,2|44,35,2|44,36,2|44,37,2|44,38,2|44,39,2|44,40,2|44,41,2|44,42,2|44,43,2|44,44,2|44,45,2|44,46,2|44,47,2|44,48,2|44,49,2|44,50,2|45,1,6|45,2,6|45,3,6|45,4,6|45,5,6|45,6,1|45,7,1|45,8,1|45,9,2|45,10,2|45,11,2|45,12,1|45,13,1|45,14,1|45,15,1|45,16,1|45,17,2|45,18,2|45,19,2|45,20,2|45,21,1|45,22,1|45,23,1|45,24,1|45,25,1|45,26,2|45,27,2|45,28,2|45,29,2|45,30,2|45,31,2|45,32,2|45,33,2|45,34,2|45,35,2|45,36,2|45,37,2|45,38,2|45,39,2|45,40,2|45,41,2|45,42,2|45,43,2|45,44,2|45,45,2|45,46,2|45,47,2|45,48,2|45,49,2|45,50,2|46,1,6|46,2,6|46,3,6|46,4,6|46,5,6|46,6,1|46,7,1|46,8,1|46,9,2|46,10,2|46,11,2|46,12,1|46,13,1|46,14,1|46,15,1|46,16,2|46,17,2|46,18,2|46,19,2|46,20,2|46,21,1|46,22,1|46,23,1|46,24,1|46,25,2|46,26,2|46,27,2|46,28,2|46,29,2|46,30,2|46,31,2|46,32,2|46,33,2|46,34,2|46,35,2|46,36,2|46,37,2|46,38,2|46,39,2|46,40,2|46,41,2|46,42,2|46,43,2|46,44,2|46,45,2|46,46,2|46,47,2|46,48,2|46,49,2|46,50,2|47,1,6|47,2,6|47,3,6|47,4,6|47,5,6|47,6,1|47,7,1|47,8,1|47,9,2|47,10,2|47,11,2|47,12,1|47,13,1|47,14,1|47,15,1|47,16,2|47,17,2|47,18,2|47,19,2|47,20,2|47,21,2|47,22,1|47,23,1|47,24,1|47,25,1|47,26,2|47,27,2|47,28,2|47,29,2|47,30,2|47,31,2|47,32,2|47,33,2|47,34,2|47,35,2|47,36,2|47,37,2|47,38,2|47,39,2|47,40,2|47,41,2|47,42,2|47,43,2|47,44,2|47,45,2|47,46,2|47,47,2|47,48,2|47,49,2|47,50,2|48,1,6|48,2,6|48,3,6|48,4,6|48,5,1|48,6,1|48,7,1|48,8,1|48,9,2|48,10,2|48,11,2|48,12,2|48,13,1|48,14,1|48,15,2|48,16,2|48,17,2|48,18,2|48,19,2|48,20,2|48,21,2|48,22,1|48,23,6|48,24,6|48,25,6|48,26,2|48,27,2|48,28,2|48,29,2|48,30,2|48,31,2|48,32,2|48,33,2|48,34,2|48,35,2|48,36,2|48,37,2|48,38,2|48,39,2|48,40,2|48,41,2|48,42,2|48,43,2|48,44,2|48,45,2|48,46,2|48,47,2|48,48,2|48,49,2|48,50,2|49,1,6|49,2,6|49,3,6|49,4,6|49,5,1|49,6,1|49,7,1|49,8,1|49,9,2|49,10,2|49,11,2|49,12,2|49,13,2|49,14,2|49,15,2|49,16,2|49,17,2|49,18,2|49,19,2|49,20,2|49,21,2|49,22,1|49,23,6|49,24,1|49,25,1|49,26,1|49,27,2|49,28,2|49,29,2|49,30,2|49,31,2|49,32,2|49,33,2|49,34,2|49,35,2|49,36,2|49,37,2|49,38,2|49,39,2|49,40,2|49,41,2|49,42,2|49,43,2|49,44,2|49,45,2|49,46,2|49,47,2|49,48,2|49,49,2|49,50,2|50,1,6|50,2,6|50,3,6|50,4,6|50,5,1|50,6,1|50,7,1|50,8,2|50,9,2|50,10,2|50,11,2|50,12,2|50,13,2|50,14,2|50,15,2|50,16,2|50,17,2|50,18,2|50,19,2|50,20,2|50,21,1|50,22,1|50,23,1|50,24,1|50,25,1|50,26,1|50,27,1|50,28,2|50,29,2|50,30,2|50,31,2|50,32,2|50,33,2|50,34,2|50,35,2|50,36,2|50,37,2|50,38,2|50,39,2|50,40,2|50,41,2|50,42,1|50,43,1|50,44,1|50,45,2|50,46,2|50,47,2|50,48,2|50,49,2|50,50,2";
        var zoneArr     = mapData.split("|");
        for (z=0; z<zoneArr.length; z++) {
            thisZone    = zoneArr[z].split(",");
            thisX       = thisZone[0];
            thisY       = thisZone[1];
            thisZ       = thisZone[2];
            mapTerrain[thisX][thisY][1] = thisZ;
            mapTerrain[thisX][thisY][2] = false;
        }

        mapRedraw(loadTileDelta*3);  // On initial draw, fill out 3 times as much area as normal.
    }

    function mapRedraw(thisLoadTileDelta) {
        // We'll call this function every time the canvas is dragged to draw any tiles that haven't been drawn yet.  We could just draw them all, but that causes serious performance issues on mobile once the realmSize is over 100 or so.

        // Calculate start and end positions for our tile loading loops
        thisXMin        = parseInt(curPosX - thisLoadTileDelta);
        if (thisXMin < 1) {
            thisXMin    = 1;
        }
        thisXMax        = parseInt(thisXMin + (thisLoadTileDelta*2));
        if (thisXMax > realmSize) {
            thisXMax    = realmSize;
            thisXMin    = parseInt(thisXMax - (thisLoadTileDelta*2));
        }

        thisYMin        = parseInt(curPosY - thisLoadTileDelta);
        if (thisYMin < 1) {
            thisYMin    = 1;
        }
        thisYMax        = parseInt(thisYMin + (thisLoadTileDelta*2));
        if (thisYMax > realmSize) {
            thisYMax    = realmSize;
            thisYMin    = parseInt(thisYMax - (thisLoadTileDelta*2));
        }

        // Slap our canvas context into a variable for easier access
        var thisCanvas = document.getElementById("mapCanvas");
        var canvasContext = thisCanvas.getContext("2d");
        for (x=thisXMin; x<=thisXMax; x++) {
            for (y=thisYMin; y<=thisYMax; y++) {
                // Check to see if we've drawn this tile yet.  If not, draw it.
                if (mapTerrain[x][y][2] == false) {
                    mapTerrain[x][y][2] = true;  // Mark the tile as drawn
                    xLoc                = (x - 1) * tileSize;  // Determine positioning in pixels
                    yLoc                = (y - 1) * tileSize;
                    canvasContext.drawImage(terrainImgArr[mapTerrain[x][y][1]], xLoc, yLoc, tileSize, tileSize);
                }
            }
        }
    }

    // Now we use jQuery to make the canvas draggable, essentially moving our "viewing window" (the containerDiv) around the map
    $("#mapCanvas").draggable({
        stop: function() {
            // If the user continues to scroll they can move off the map and end up in whitespace, which is never good.  So we set some limits here, and snap the user back if they tried to go too far in any direction.

            divLeft = parseInt($("#mapCanvas").css("left"));
            divTop  = parseInt($("#mapCanvas").css("top"));

            if (divLeft < minDragXY) {
                $("#mapCanvas").animate({left: minDragXY + "px"}, 150)
                divLeft = minDragXY;
            } else if (divLeft > 0) {
                $("#mapCanvas").animate({left: "0px"}, 150)
                divLeft = 0;
            }

            if (divTop < minDragXY) {
                $("#mapCanvas").animate({top: minDragXY + "px"}, 150)
                divTop  = minDragXY;
            } else if (divTop > 0) {
                $("#mapCanvas").animate({top: "0px"}, 150)
                divTop  = 0;
            }

            // After our containment checks are done, we update the curPos variables then call the map redraw function again.  That function will key off of the new curPos and load any tiles necessary.
            curPosX = (Math.abs(divLeft) + (containerSize/2)) / tileSize;
            curPosY = (Math.abs(divTop) + (containerSize/2)) / tileSize;
            mapRedraw(loadTileDelta);
        }
    });

    mapLoad();  // Kick off the whole process here.  This would ultimately end up in an onload handler...
</script>

```

# Answer
> 1 votes
What you are looking for is the HTML5 canvas element. From w3schools:

> The HTML `<canvas>` element is used to draw graphics on a web page.

---
Tags: tilemap, html, jquery
---


# Question
Title: is it possible to use dynamic types in c# generic methods?
for example i need something like this:

```
 SQLITE._instance.ds.GetItems<armour>();

```

armour is a class. but i need to get type of object to send to it in order to avoid rewriting this function.

for example it need:

```
SQLITE._instance.ds.GetItems<"classType">();

```

or

```
 SQLITE._instance.ds.GetItems<obj.getType()>();

```

to send the type to generic function. but i always receive that you send a variable not a type to generic function.

what should i really do?

# Answer
> 1 votes
If you have a small fixed set of types you need to work with, known in advance, you can get around this with a wrapper function that checks the type and selects the appropriate generic method to call:

```
public IEnumerable GetItemsOfType(System.Type type) {
    if(type == typeof(Armour))
        return SQLITE._instance.ds.GetItems<Armour>();
    if(type == typeof(Weapon))
        return SQLITE._instance.ds.GetItems<Weapon>();
    // ...

    Assert("Called GetItemsOfType with an unsupported type: " + type.AssemblyQualifiedName);
}

```

You can save all the ifs by storing a dictionary of delegates and looking up from that using the type as a key:

```
public delegate IEnumerable ItemGetter();
Dictionary<System.Type, ItemGetter> typedItemGetters;

//...later initialized like so:
typedItemGetters = new Dictionary<System.Type, ItemGetter>{
    {typeof(Armour), SQLITE._instance.ds.GetItems<Armour>},
    {typeof(Weapon), SQLITE._instance.ds.GetItems<Weapon>},
    //...
};

// And used like so:
public IEnumerable GetItemsOfType(System.Type type) {
    return typedItemGetters[type]();
}

```

---
Tags: c#
---