1
General / Double Click without events - Help!
« on: March 01, 2017, 03:39:40 am »
Hello dear SFML'ers. I have a problem that I hope you can help me with. I am using the joystick module from sfml to read gamepad inputs from a PLRF25C Rangefinder. Everything works great, the program sees the button and changes states when pressed. The issue I am running into is because I am using SFML inside the .dll I am writing for a Plugin for VRSG, I can not use events. I need to be able to detect a double and a multiple click inside the double click.
Link for PLRF: http://www.vectronix.us/XooWebKit/bin/download.php/203a_b21acf3fdd/PLRF25C%20(web).pdf
For example:
If I hold the button, the lcd inside the PLRF displays the current heading(Deg Magnetic).
When the button is let go, the PLRF displays the range for a couple of seconds.
If the button is pressed again within a second or two it needs to enter a new state, where each sequential button press will show other data (Range,Vertical Distance, Horizontal Distance, Heading, Inclination angle) and just cycle those data values.
Button Held: Show Heading
Button Release from first click: Show Range
Click again within a sec: Show Vertical Distance
click again: show Horizontal Distance
click again: Show Vertical Distance
click again: show inclination angle
click again and just repeat the cycle.
I have included my code to see if anyone can help me or point me in the right direction. I have holding and releasing of the button to display heading and range but not the double click stuff. Most of the code is probably not useful to you but I included it anyway.
Link for PLRF: http://www.vectronix.us/XooWebKit/bin/download.php/203a_b21acf3fdd/PLRF25C%20(web).pdf
For example:
If I hold the button, the lcd inside the PLRF displays the current heading(Deg Magnetic).
When the button is let go, the PLRF displays the range for a couple of seconds.
If the button is pressed again within a second or two it needs to enter a new state, where each sequential button press will show other data (Range,Vertical Distance, Horizontal Distance, Heading, Inclination angle) and just cycle those data values.
Button Held: Show Heading
Button Release from first click: Show Range
Click again within a sec: Show Vertical Distance
click again: show Horizontal Distance
click again: Show Vertical Distance
click again: show inclination angle
click again and just repeat the cycle.
I have included my code to see if anyone can help me or point me in the right direction. I have holding and releasing of the button to display heading and range but not the double click stuff. Most of the code is probably not useful to you but I included it anyway.
// HUD Plugin.cpp : Defines the initialization routines for the DLL.
//
#include <afxwin.h>
#include "stdafx.h" // Must be here, otherwise lots of errors
#include <afxdlgs.h>
#include <afxcmn.h>
#include <afxdllx.h>
#include <d3d11.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include "SFML\Window.hpp"
#include "VertexShader.h"
#include "PixelShader.h"
#include "Resource.h"
#include "Plugins.h"
#include "Vector.h"
#include "Coord.h"
#include "Geodesy.h"
#include "Dis.h"
#include "Swap.h"
static AFX_EXTENSION_MODULE NEAR extensionDLL = { NULL, NULL };
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p) = NULL; } }
static ID3D11Texture2D *pWhiteTexture;
static ID3D11ShaderResourceView *pWhiteTextureSRV;
static ID3D11Texture2D *pFontTexture;
static ID3D11ShaderResourceView *pFontTextureSRV;
static ID3D11SamplerState *pSampler;
static ID3D11VertexShader *pVertexShader;
static ID3D11PixelShader *pPixelShader;
static ID3D11InputLayout *pLayout;
static ID3D11Buffer *pVB;
static ID3D11Buffer *pIB;
#define VB_MAX 5000 // Max verts in our buffer before we reset
#define IB_MAX 2000 // Max indices in the buffer before we reset
static int vertsInBuffer; // Position in vertex buffer to insert next primitive's verts
static int indicesInBuffer; // Position in vertex buffer to insert next primitive's indices
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// Extension DLL one-time initialization.
if (!AfxInitExtensionModule(extensionDLL, hInstance))
return 0;
// Other initialization could be done here, as long as
// it doesn't result in direct or indirect calls to AfxGetApp.
// This extension DLL needs to add doc templates to the
// app object, so it waits for the application to boot
// and call an initialization function (see below).
new CDynLinkLibrary(extensionDLL);
}
return 1; // ok
}
// Data queries for sending DesignatorPDUs
static ExtDataQueryInteger dqDisVersion(DATA_QUERY_DIS_VERSION);
static ExtDataQueryInteger dqDisExercise(DATA_QUERY_EXERCISE_ID);
static ExtDataQueryAttachEntityId dqEntityID;
static ExtDataQueryVrsgId VrsgID;
static CPtrList dataQueries;
static LaserPDU pdu;
void sendDesignatorPDU(float power);
const int maxRange = 6000; // Max range of PLRF device: 6000 meters
static ExtLaserRangeData laserData; // Laserdata object
static Viewport viewPortData; // Viewportdata object
double heading, pitch; // Global heading, pitch
double geoc_pos[3], llz_pos[3]; // Global Location Values
int button = 4; // Button on device 0 = PLRF
// 4 = Fire Button on SOFLAM
int joystick = 0; // Joystick number
int seconds = 60; // 60 ticks in one second (60FPS)
bool entityLased;
bool debug, btnWasPressed, dblClick, cycleData,
sendStartPDU, sendEndPDU, firstClick;
int keyPressTimer, notPressedTimer, DCTimer,
singleClickTimer, done, displayTimer;
int dataType;
// Math Defines
#define pi ((double)3.14159265358979)
#define pio2 ((double)0.5*pi)
#define twopi ((double)2.0*pi)
#define deg_to_rad (twopi/(double)360.0)
#define rad_to_deg ((double)360.0/twopi)
#define Mil_to_deg (6400.0 / 360.0)
struct pointData
{
double range;
double lat;
double lon;
double alt;
double inclination;
double horizontalDistance;
double verticalDistance;
double azimuth;
unsigned short site;
unsigned short host;
unsigned short entity;
};
pointData point1;
pointData point2;
// A simple vertex format for drawing primitives
struct HomoVertex
{
// Homogeneous space
float x; // -1.0 (left edge) to 1.0 (right edge)
float y; // -1.0 (bottom edge) to 1.0 (top edge)
float z; // use zero here
// Color (0xAABBGGRR format)
DWORD color;
// Texture coords
float tu;
float tv;
};
// Texture coordinate table to convert characters to UV pairs
struct TCoordTable
{
float llu;
float llv;
float uru;
float urv;
} tcoordTable[256];
// makeFontTexture - uses the GDI to render a font to a bitmap. the
// bitmap is turned into a texture. tcoordTable contains the texture
// coordinates for each character in the font.
static ID3D11Texture2D *createFontTexture(ID3D11Device *pDevice)
{
// Make a bitmap for the GDI to render to
int hdrLen = sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255;
BITMAPINFO *bmi = (BITMAPINFO *) new char[hdrLen];
memset(bmi, 0, hdrLen);
bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi->bmiHeader.biWidth = 256;
bmi->bmiHeader.biHeight = 256;
bmi->bmiHeader.biPlanes = 1;
bmi->bmiHeader.biCompression = BI_RGB;
bmi->bmiHeader.biBitCount = 8;
for (int i = 0; i < 256; i++)
{
bmi->bmiColors[i].rgbRed = i;
bmi->bmiColors[i].rgbGreen = i;
bmi->bmiColors[i].rgbBlue = i;
bmi->bmiColors[i].rgbReserved = 0;
}
// Create a DC and a bitmap for the font
HDC hDC = CreateCompatibleDC(NULL);
DWORD *pBitmapBits;
HBITMAP hbmBitmap = CreateDIBSection(hDC, bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0);
SetMapMode(hDC, MM_TEXT);
// Create a font. A 30 unit height should allow all printable chars to fit into a 256x256
int nHeight = MulDiv(30, 96, GetDeviceCaps(hDC, LOGPIXELSY));
HFONT hFont = CreateFont(nHeight, 0, 0, 0, FW_HEAVY, FALSE,
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
VARIABLE_PITCH, "Lucida Console");
SelectObject(hDC, hbmBitmap);
SelectObject(hDC, hFont);
SetTextColor(hDC, RGB(255, 255, 255));
SetBkColor(hDC, RGB(0, 0, 0));
SetTextAlign(hDC, TA_TOP | TA_LEFT);
// Output all the chars and save the tcoords
int x = 0;
int y = 0;
SIZE size;
for (char c = 32; c < 127; c++)
{
// See if char will fit on current line or if we need to wrap
GetTextExtentPoint32(hDC, &c, 1, &size);
if (x + size.cx + 1 > 256)
{
x = 0;
y += size.cy + 1;
}
// Output the char
ExtTextOut(hDC, x, y, ETO_OPAQUE, NULL, &c, 1, NULL);
// Save tcoords of this char
tcoordTable[c - 32].llu = (float)x / 256.0f;
tcoordTable[c - 32].llv = 1.0f - ((float)(y + size.cy) / 256.0f);
tcoordTable[c - 32].uru = (float)(x + size.cx) / 256.0f;
tcoordTable[c - 32].urv = 1.0f - ((float)y / 256.0f);
x += size.cx + 1;
}
// Create an array of data to initialize the texture from.
// Populate the texels of the texture with the image
// the GDI rendered to. Treat black pixels as transparent
// and others as pure white.
DWORD *pImageData = new DWORD[256 * 256];
DWORD *p = pImageData;
DWORD color;
BYTE *pColor = (BYTE *)pBitmapBits;
for (int y = 0; y < 256; y++)
{
for (int x = 0; x < 256; x++)
{
if (*pColor++)
color = 0xffffffff;
else
color = 0x00ffffff;
*p++ = color;
}
}
// Cleanup GDI stuff
DeleteObject(hbmBitmap);
DeleteDC(hDC);
DeleteObject(hFont);
delete[] bmi;
D3D11_TEXTURE2D_DESC tdesc;
memset(&tdesc, 0, sizeof(tdesc));
tdesc.Width = 256;
tdesc.Height = 256;
tdesc.MipLevels = 1;
tdesc.ArraySize = 1;
tdesc.SampleDesc.Count = 1;
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
tdesc.Usage = D3D11_USAGE_DEFAULT;
tdesc.CPUAccessFlags = 0;
tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = pImageData;
initData.SysMemPitch = 4 * 256;
ID3D11Texture2D *pTexture;
pDevice->CreateTexture2D(&tdesc, &initData, &pTexture);
delete[] pImageData;
return pTexture;
}
static bool copyToBuffer(const void *data, int elementSize, int count, int maxCount, int &index,
ID3D11Buffer *pBuffer, ID3D11DeviceContext *pContext)
{
D3D11_MAPPED_SUBRESOURCE mapData;
D3D11_MAP mapType;
if (index + count < maxCount)
{
// Append to active buffer
mapType = D3D11_MAP_WRITE_NO_OVERWRITE;
}
else
{
// Buffer full, must start over
mapType = D3D11_MAP_WRITE_DISCARD;
index = 0;
}
if (pContext->Map(pBuffer, 0, mapType, 0, &mapData) != S_OK)
return false;
CopyMemory((BYTE*)mapData.pData + index*elementSize, data, count*elementSize);
pContext->Unmap(pBuffer, 0);
return true;
}
// Drawing non-indexed primitives
static void drawPrimitive(
const HomoVertex *verts, int numVerts,
D3D11_PRIMITIVE_TOPOLOGY topo,
ID3D11DeviceContext *pContext)
{
// Copy verts and indicies into their respective buffers
copyToBuffer(verts, sizeof(HomoVertex), numVerts, VB_MAX, vertsInBuffer, pVB, pContext);
// Now we can draw
pContext->IASetPrimitiveTopology(topo);
pContext->Draw(numVerts, vertsInBuffer);
vertsInBuffer += numVerts;
}
// Drawing indexed primitives
static void drawPrimitive(
const HomoVertex *verts, int numVerts,
const WORD *indices, int numIndices,
D3D11_PRIMITIVE_TOPOLOGY topo,
ID3D11DeviceContext *pContext)
{
// Copy verts and indicies into their respective buffers
copyToBuffer(verts, sizeof(HomoVertex), numVerts, VB_MAX, vertsInBuffer, pVB, pContext);
copyToBuffer(indices, sizeof(WORD), numIndices, IB_MAX, indicesInBuffer, pIB, pContext);
// Now we can draw
pContext->IASetPrimitiveTopology(topo);
pContext->DrawIndexed(numIndices, indicesInBuffer, vertsInBuffer);
// Update the buffer indices
vertsInBuffer += numVerts;
indicesInBuffer += numIndices;
}
// This function get the 4 texture coordinates needed to pull out a given
// character from the font texture.
static void getTextureCoords(char c,
float &u0, float &v0, float &u1, float &v1,
float &u2, float &v2, float &u3, float &v3)
{
c -= 32;
if (c < 0)
{
u0 = 0.0f;
v0 = 0.0f;
u1 = 0.0f;
v1 = 0.0f;
u2 = 0.0f;
v2 = 0.0f;
u3 = 0.0f;
v3 = 0.0f;
}
else
{
u0 = tcoordTable[c].llu;
v0 = tcoordTable[c].llv;
u1 = tcoordTable[c].uru;
v1 = tcoordTable[c].llv;
u2 = tcoordTable[c].uru;
v2 = tcoordTable[c].urv;
u3 = tcoordTable[c].llu;
v3 = tcoordTable[c].urv;
}
}
// This function draws a string of text characters as a triangle list of textured quads.
// It uses getTextureCoords to get the texture coords from the font texture for each
// quad.
static void drawText(const char *msg, float x, float y, float thetaRadians, float width, float height, DWORD color,
ID3D11DeviceContext *pContext)
{
// Bind the font texture
pContext->PSSetShaderResources(0, 1, &pFontTextureSRV);
static HomoVertex p[80]; // Draw up to 20 chars (80/4) in a single API call
static WORD indicies[120]; // Need 6 indices for each of the 20 chars (two quads)
int len = (int)strlen(msg);
int t = 0;
int v = 0;
float dx = width*cosf(thetaRadians);
float dy = -width*sinf(thetaRadians);
float hdx = -height*0.5f*sinf(thetaRadians);
float hdy = -height*0.5f*cosf(thetaRadians);
// For each character, make a quad
for (int i = 0; i < len; i++)
{
// Get tcoords of current char
getTextureCoords(msg[i],
p[v + 0].tu, p[v + 0].tv,
p[v + 1].tu, p[v + 1].tv,
p[v + 2].tu, p[v + 2].tv,
p[v + 3].tu, p[v + 3].tv);
// Lower left
p[v + 0].x = x + hdx + i*dx;
p[v + 0].y = y + hdy + i*dy;
p[v + 0].z = 0.0f;
p[v + 0].color = color;
// Lower right
p[v + 1].x = x + hdx + (i + 1.0f)*dx;
p[v + 1].y = y + hdy + (i + 1.0f)*dy;
p[v + 1].z = 0.0f;
p[v + 1].color = color;
// Upper right
p[v + 2].x = x - hdx + (i + 1.0f)*dx;
p[v + 2].y = y - hdy + (i + 1.0f)*dy;
p[v + 2].z = 0.0f;
p[v + 2].color = color;
// Upper left
p[v + 3].x = x - hdx + i*dx;
p[v + 3].y = y - hdy + i*dy;
p[v + 3].z = 0.0f;;
p[v + 3].color = color;
// Make the indicies. Note indices are in counter-clockwise order
indicies[t++] = v + 0;
indicies[t++] = v + 1;
indicies[t++] = v + 2;
indicies[t++] = v + 0;
indicies[t++] = v + 2;
indicies[t++] = v + 3;
v += 4;
// See if we need to flush
if (v == ARRAYSIZE(p))
{
drawPrimitive(p, v, indicies, t, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
v = 0;
t = 0;
}
}
// Draw anything remaining
if (v)
{
drawPrimitive(p, v, indicies, t, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
}
}
static void createDeviceObjects(ID3D11DeviceContext *pContext)
{
// Create all the objects we need under the new D3D Device
// Need a handle to the device
ID3D11Device *pDevice = NULL;
pContext->GetDevice(&pDevice);
// Create the vertex layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
pDevice->CreateInputLayout(layout, ARRAYSIZE(layout), g_VertexShader, sizeof(g_VertexShader), &pLayout);
// Create the shaders
pDevice->CreateVertexShader(g_VertexShader, sizeof(g_VertexShader), NULL, &pVertexShader);
pDevice->CreatePixelShader(g_PixelShader, sizeof(g_PixelShader), NULL, &pPixelShader);
// Create the font texture
pFontTexture = createFontTexture(pDevice);
// Create the shader resource view for the font texture
pDevice->CreateShaderResourceView(pFontTexture, NULL, &pFontTextureSRV);
// Create a sampler state
D3D11_SAMPLER_DESC sampDesc;
ZeroMemory(&sampDesc, sizeof(sampDesc));
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
sampDesc.MinLOD = 0;
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
pDevice->CreateSamplerState(&sampDesc, &pSampler);
// Create the vertex buffer
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.ByteWidth = sizeof(HomoVertex) * VB_MAX;
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
pDevice->CreateBuffer(&bd, NULL, &pVB);
// Create an index buffer
bd.ByteWidth = sizeof(WORD) * IB_MAX;
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
pDevice->CreateBuffer(&bd, NULL, &pIB);
// Initialize indexes into buffers
vertsInBuffer = 0;
indicesInBuffer = 0;
// Create a plain white texture for things we dont want textured
D3D11_TEXTURE2D_DESC tdesc;
memset(&tdesc, 0, sizeof(tdesc));
tdesc.Width = 1;
tdesc.Height = 1;
tdesc.MipLevels = 1;
tdesc.ArraySize = 1;
tdesc.SampleDesc.Count = 1;
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
tdesc.Usage = D3D11_USAGE_DEFAULT;
tdesc.CPUAccessFlags = 0;
tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
D3D11_SUBRESOURCE_DATA initData;
DWORD white = 0xffffffff;
initData.pSysMem = &white;
initData.SysMemPitch = 4 * 256;
pDevice->CreateTexture2D(&tdesc, &initData, &pWhiteTexture);
pDevice->CreateShaderResourceView(pWhiteTexture, NULL, &pWhiteTextureSRV);
}
struct Viewport;
__declspec(dllexport) void __cdecl extPostViewportUserDraw(ID3D11DeviceContext *pContext, int vpId, Viewport *vp)
{
// First time in or after device reset, create our resources
if (pFontTexture == NULL)
createDeviceObjects(pContext);
// Remove the depth buffer
ID3D11RenderTargetView *pBackBufferView;
ID3D11DepthStencilView *pDepthStencilView = NULL;
pContext->OMGetRenderTargets(1, &pBackBufferView, &pDepthStencilView);
pContext->OMSetRenderTargets(1, &pBackBufferView, NULL);
SAFE_RELEASE(pDepthStencilView);
// Setup some required render states
UINT stride = sizeof(HomoVertex);
UINT offset = 0;
pContext->IASetVertexBuffers(0, 1, &pVB, &stride, &offset);
pContext->IASetIndexBuffer(pIB, DXGI_FORMAT_R16_UINT, 0);
pContext->IASetInputLayout(pLayout);
pContext->VSSetShader(pVertexShader, NULL, 0);
pContext->PSSetShader(pPixelShader, NULL, 0);
pContext->PSSetSamplers(0, 1, &pSampler);
// You are drawing in 3D. There is an coordinate system aligned with the ownship.
// It is using the DIS/CIGI convention of X forward, Y right, Z down. Imagine
// the canvans 'renderPlaneDist' meters in front of the airplane. The Y and Z axes
// position the objects horizontally and vertically on this canvas.
// Bind the white texture, since we dont want texture on lines. Color can be
// given per-vertex on non-textured primitives, using the DWORD color member of
// HomoVertex. Colors are encoded in AAGGBBRR format. Note that drawing text
// binds the font texture, so you need to call this again after drawing text.
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// Draw crosshairs. Since this a list of independant lines, no verts are
// repeated, and we can use the simpler non-indexed form of drawPrimtive().
// For drawing a strip of connected lines, you would instead use
// D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP.
// x,y,z(always 0),color,(tu,tv) textured cords
HomoVertex verts[] = {
// First Segment on Vertical (From Center) (2 Verts) Black
-.025f, .18f, 0.0f, 0xff000000, 0.0f, 0.0f,
.025f, .18f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Second Segment on Vertical (2 Verts)
-.025f, .36f, 0.0f, 0xff000000, 0.0f, 0.0f,
.025f, .36f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Third Segment on Vertical (2 Verts)
-.025f, .54f, 0.0f, 0xff000000, 0.0f, 0.0f,
.025f, .54f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Fourth Segment on Vertical (2 Verts)
-.025f, .72f, 0.0f, 0xff000000, 0.0f, 0.0f,
.025f, .72f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Fifth Segment on Vertical (2 Verts)
-.025f, .90f, 0.0f, 0xff000000, 0.0f, 0.0f,
.025f, .90f, 0.0f, 0xff000000, 0.0f, 0.0f,
// First Segment on Left (From Center) (2 Verts) Black
-.18f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
-.18f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Second Segment on left (2 Verts)
-.36f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
-.36f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Third Segment on left (2 Verts)
-.54f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
-.54f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Forth Segment on left (2 Verts)
-.72f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
-.72f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Fifth Segment on left (2 Verts)
-.90f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
-.90f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// First Segment on Right (From Center) (2 Verts) Black
.18f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
.18f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Second Segment on Right (2 Verts)
.36f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
.36f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Third Segment on Right (2 Verts)
.54f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
.54f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Forth Segment on Right (2 Verts)
.72f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
.72f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Fifth Segment on Right (2 Verts)
.90f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
.90f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Center Crosshair (4 Verts) Black
// Horizontal Line
-0.025f, 0.0f, 0.0f, 0xff000000, 0.0f, 0.0f,
0.025f, 0.0f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Vertical Line
0.0f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
0.0f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
};
// Draw Crosshairs
drawPrimitive(verts, 34, D3D11_PRIMITIVE_TOPOLOGY_LINELIST, pContext);
// Draw text on Screen then Reset to Null Texture after each Text draw
// Draw text on left side
// Draw 30-50 degree markings
drawText("30", -.57f, -0.075f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("50", -.93f, -0.075f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// Draw text on right side
drawText("30", .51f, -0.075f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("50", .87f, -0.075f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// Draw text on vertical side
drawText("30", -.1f, 0.54f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("50", -.1f, 0.9f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// **************************************************************************************************
// Draw a circle. There are many shared verts, so we do this as an indexed
// triangle list for efficiency.
for (int j = 1; j < 6; j++) // Draw Circles on left side
{
double offset = .09;
double answer = ((.18 * j) - offset);
const int numVerts = 20;
double centerX = -(answer);
double centerY = 0.0f;
const float radius = 0.005f;
const float PI = 3.14159265f;
HomoVertex circVerts[numVerts + 1]; // add an extra vert for the center
WORD indicies[numVerts * 3]; // need 3 indices per triangle
// verts around the circumference
for (int i = 0; i < numVerts; i++)
{
float theta = (2.0f * PI) * (float)i / (float)numVerts;
circVerts[i].x = centerX + radius*cosf(theta);
circVerts[i].y = centerY + radius*sinf(theta);
circVerts[i].z = 0.0f;
circVerts[i].color = 0xff000000; // black
circVerts[i].tu = 0.0f;
circVerts[i].tv = 0.0;
}
// and one at the center
circVerts[numVerts].x = centerX;
circVerts[numVerts].y = centerY;
circVerts[numVerts].z = 0.0f;
circVerts[numVerts].color = 0xff000000; // black
circVerts[numVerts].tu = 0.0f;
circVerts[numVerts].tv = 0.0;
// make the triangle indices
for (int i = 0; i < numVerts; i++)
{
indicies[i * 3 + 0] = numVerts; // the center
indicies[i * 3 + 1] = i;
indicies[i * 3 + 2] = (i + 1) % numVerts;
}
// Now we can draw it
drawPrimitive(circVerts, numVerts + 1, indicies, numVerts * 3, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
}
// ********************************************************************************************************************** //
for (int j = 1; j < 6; j++) // Draw Circles on Right side
{
float offset = .09;
float answer = ((.18 * j) - offset);
const int numVerts = 20;
float centerX = (answer);
float centerY = 0.0f;
const float radius = 0.005f;
const float PI = 3.14159265f;
HomoVertex circVerts[numVerts + 1]; // add an extra vert for the center
WORD indicies[numVerts * 3]; // need 3 indices per triangle
// verts around the circumference
for (int i = 0; i < numVerts; i++)
{
float theta = (2.0f * PI) * (float)i / (float)numVerts;
circVerts[i].x = centerX + radius*cosf(theta);
circVerts[i].y = centerY + radius*sinf(theta);
circVerts[i].z = 0.0f;
circVerts[i].color = 0xff000000; // black
circVerts[i].tu = 0.0f;
circVerts[i].tv = 0.0;
}
// and one at the center
circVerts[numVerts].x = centerX;
circVerts[numVerts].y = centerY;
circVerts[numVerts].z = 0.0f;
circVerts[numVerts].color = 0xff000000; // black
circVerts[numVerts].tu = 0.0f;
circVerts[numVerts].tv = 0.0;
// make the triangle indices
for (int i = 0; i < numVerts; i++)
{
indicies[i * 3 + 0] = numVerts; // the center
indicies[i * 3 + 1] = i;
indicies[i * 3 + 2] = (i + 1) % numVerts;
}
// Now we can draw it
drawPrimitive(circVerts, numVerts + 1, indicies, numVerts * 3, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
}
// ********************************************************************************************************************** //
for (int j = 1; j < 6; j++) // Draw Circles on Vertical side
{
float offset = .09;
float answer = ((.18 * j) - offset);
const int numVerts = 20;
float centerX = 0.0f;
float centerY = answer;
const float radius = 0.005f;
const float PI = 3.14159265f;
HomoVertex circVerts[numVerts + 1]; // add an extra vert for the center
WORD indicies[numVerts * 3]; // need 3 indices per triangle
// verts around the circumference
for (int i = 0; i < numVerts; i++)
{
float theta = (2.0f * PI) * (float)i / (float)numVerts;
circVerts[i].x = centerX + radius*cosf(theta);
circVerts[i].y = centerY + radius*sinf(theta);
circVerts[i].z = 0.0f;
circVerts[i].color = 0xff000000; // black
circVerts[i].tu = 0.0f;
circVerts[i].tv = 0.0;
}
// and one at the center
circVerts[numVerts].x = centerX;
circVerts[numVerts].y = centerY;
circVerts[numVerts].z = 0.0f;
circVerts[numVerts].color = 0xff000000; // black
circVerts[numVerts].tu = 0.0f;
circVerts[numVerts].tv = 0.0;
// make the triangle indices
for (int i = 0; i < numVerts; i++)
{
indicies[i * 3 + 0] = numVerts; // the center
indicies[i * 3 + 1] = i;
indicies[i * 3 + 2] = (i + 1) % numVerts;
}
// Now we can draw it
drawPrimitive(circVerts, numVerts + 1, indicies, numVerts * 3, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
}
// Lat in geocentric
geoc_pos[0] = viewPortData.posGcc[0];
// Lon in geocentric
geoc_pos[1] = viewPortData.posGcc[1];
// Height in geocentric
geoc_pos[2] = viewPortData.posGcc[2];
// Convert geocentric postion to lat/lon/height
coord_gcc_to_llz(geoc_pos[0], geoc_pos[1], geoc_pos[2], DATUM_WGS84, &llz_pos[0], &llz_pos[1], &llz_pos[2]);
// Calculate Magnetic variance from lat/lon
double MagVar = MetaVR::getMagVar(llz_pos[0], llz_pos[1]);
// Add Variance to True Heading to get Magnetic Heading. East is negative
double MagHeading = heading - MagVar;
if (MagHeading > 360.0) // Degree Correction for Magnetic Heading being greater than 360
{
MagHeading = round(MagHeading - 360); // Round Magnetic Heading
}
if (MagHeading < 0.0) // Degree Correction for Magnetic Heading being less than 0
{
MagHeading = round(MagHeading + 360); // Round Magnetic Heading
}
// ********************************************************************************************************************** //
// Create Joystick Code Here
char headingText[15];
//// Height
//height = sin(point1.inclination) * point1.range;
//// Horizontal Distance
//hDist = tan(point1.inclination) * height;
//drawText("AZI", -.18f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "AZ"
//pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
//sprintf_s(headingText, "%3.0f", MagHeading);
//drawText(headingText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red magnetic heading
//pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
//drawText("o", 0.13f, -0.17f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "o"
//pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
//
//drawText("D", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
//pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
//
//char rangeText[6];
//sprintf_s(rangeText, "%4.0f", point1.range);
//drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
//pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
//drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
//pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// Holding Button
if (sf::Joystick::isButtonPressed(joystick, button) && firstClick == true)
{
// Single Click
drawText("AZI", -.18f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "AZ"
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(headingText, "%3.0f", MagHeading);
drawText(headingText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red magnetic heading
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("o", 0.13f, -0.17f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "o"
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
btnWasPressed = true;
done = false; // Get new data on button release
notPressedTimer = 0;
displayTimer = 0;
sendStartPDU = false;
sendEndPDU = false;
}
// Release of Button
if (!(sf::Joystick::isButtonPressed(joystick, button)) && btnWasPressed == true)
{
if (displayTimer < (3 * seconds))
{
//if (cycleData == true)
//{
// if (dataType == 1) // Distance
// {
// drawText("D", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// char rangeText[6];
// sprintf_s(rangeText, "%4.0f", point1.range);
// drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// }
// else if (dataType == 2) // Horizontal Distance
// {
// drawText("H", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// char rangeText[6];
// sprintf_s(rangeText, "%4.0f", point1.horizontalDistance);
// drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// }
// else if (dataType == 3) // Vertical Height Distance
// {
// drawText("V", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// char rangeText[6];
// sprintf_s(rangeText, "%4.0f", point1.verticalDistance);
// drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// }
// else if (dataType == 4) // Azimuth (Heading)
// {
// drawText("AZI", -.18f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "AZ"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// sprintf_s(headingText, "%3.0f", MagHeading);
// drawText(headingText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red magnetic heading
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// drawText("o", 0.13f, -0.17f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "o"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// }
// else if (dataType == 5) // inclination
// {
// drawText("INC", -.18f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "AZ"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// sprintf_s(headingText, "%3.0f", point1.inclination);
// drawText(headingText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red magnetic heading
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// drawText("o", 0.13f, -0.17f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "o"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// }
//}
//else
//{
drawText("D", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
if (done == false)
{
// Range
point1.range = laserData.range;
// Alt
point1.alt = laserData.alt;
// Lat
point1.lat = laserData.lat;
// Lon
point1.lon = laserData.lon;
// Entity Lased
if (laserData.bEntityIdValid == true)
{
point1.site = laserData.site;
point1.host = laserData.host;
point1.entity = laserData.entity;
entityLased = true;
}
else
{
point1.site = 0;
point1.host = 0;
point1.entity = 0;
entityLased = false;
}
// Inclination
point1.inclination = pitch;
// Vertical Distance
point1.verticalDistance = sin(point1.inclination) * point1.range;
// Horizontal Distance
point1.horizontalDistance = tan(point1.inclination) * point1.verticalDistance;
// Azimuth
point1.azimuth = MagHeading;
done = true;
}
if ((point1.range <= maxRange) && (point1.range != 0)) // Display Range if laser range is below maxRange
{
if (sendStartPDU == false)
{
sendDesignatorPDU(10.0f);
sendStartPDU = true;
}
char rangeText[6];
sprintf_s(rangeText, "%4.0f", point1.range);
drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
}
else // Draw ---- to indicate range > maxrange
{
drawText("----", 0.0f, -0.1f, 0.0f, 0.04f, 0.06f, 0xff0000ff, pContext); // Red "----"
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
}
}
if (displayTimer > (.1 * seconds))
{
if (sendEndPDU == false)
{
sendDesignatorPDU(0.0f);
sendEndPDU = true;
}
}
firstClick = false;
displayTimer += 1;
}
// Cycle Data
if (sf::Joystick::isButtonPressed(joystick, button) && btnWasPressed == true && dblClick == true)
{
dataType++;
cycleData = true;
if (dataType == 6) // start over
{
dataType = 1;
}
}
// Button not being pressed
if (!(sf::Joystick::isButtonPressed(joystick, button)))
{
notPressedTimer += 1;
if (notPressedTimer < (1 * seconds))
{
dblClick == true;
}
else
{
dblClick == false;
}
// No Click
if (notPressedTimer > (3 * seconds)) // reset all timers and states after 3 seconds since last button press
{
dataType = 1;
firstClick = true;
done = false;
dblClick = false;
btnWasPressed = false;
displayTimer = 0;
sendStartPDU = false;
sendEndPDU = false;
}
}
// ********************************************************************************************************************** //
// Debug Screen if "D" on keyboard is pressed
char debugText[15];
if ((sf::Keyboard::isKeyPressed(sf::Keyboard::F6)) && debug == false)
{
keyPressTimer += 1;
if (keyPressTimer > (.3 * seconds))
{
debug = true;
keyPressTimer = 0;
}
}
if ((sf::Keyboard::isKeyPressed(sf::Keyboard::F6)) && debug == true)
{
keyPressTimer += 1;
if (keyPressTimer > (.3 * seconds))
{
debug = false;
keyPressTimer = 0;
}
}
if (!(sf::Keyboard::isKeyPressed(sf::Keyboard::F6)))
{
keyPressTimer = 0;
}
if (debug == true)
{
if (sf::Joystick::isConnected(joystick))
{
drawText("Is Connected", .03f, 0.45f, 0.0f, 0.04f, 0.06f, 0xff0000ff, pContext); // Connected
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
}
else
{
drawText("Is not Connected", .05f, 0.5f, 0.0f, 0.04f, 0.06f, 0xff0000ff, pContext); // Not Connected
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
}
drawText("Heading", -.4f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Heading
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", heading);
drawText(debugText, 0.0f, -0.1, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("MagVar", -.4f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Magnetic Variation
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", MagVar);
drawText(debugText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("MagHeading", -.5f, -0.3f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Magnetic Heading
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", MagHeading);
drawText(debugText, 0.0f, -0.3, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("LAT", -.18f, -0.4f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Latitude
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", llz_pos[0]);
drawText(debugText, 0.0f, -0.4, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("LON", -.18f, -0.5f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Longitude
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", llz_pos[1]);
drawText(debugText, 0.0f, -0.5, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("ALT", -.18f, -0.6f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Altitude
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", llz_pos[2]);
drawText(debugText, 0.0f, -0.6, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("Geo X", -.28f, -0.7f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Geocentric X position
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", geoc_pos[0]);
drawText(debugText, 0.0f, -0.7, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("Geo Y", -.28f, -0.8f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Geocentric Y position
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", geoc_pos[1]);
drawText(debugText, 0.0f, -0.8, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("Geo Z", -.28f, -0.9f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Geocentric Z position
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", geoc_pos[2]);
drawText(debugText, 0.0f, -0.9, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
}
// ********************************************************************************************************************** //
}
__declspec(dllexport) void __cdecl extResetDevice()
{
// Device has been reset. Release the objects we created under the device.
// We will recreate them on the next call to extPostViewportUserDraw
SAFE_RELEASE(pWhiteTexture);
SAFE_RELEASE(pWhiteTextureSRV);
SAFE_RELEASE(pFontTexture);
SAFE_RELEASE(pFontTextureSRV);
SAFE_RELEASE(pSampler);
SAFE_RELEASE(pVertexShader);
SAFE_RELEASE(pPixelShader);
SAFE_RELEASE(pLayout);
SAFE_RELEASE(pVB);
SAFE_RELEASE(pIB);
}
__declspec(dllexport) void __cdecl extLaserRange(const ExtLaserRangeData *data)
{
laserData = *data; // copy ExtLaserRangeData *data to laserData object
}
__declspec(dllexport) BOOL __cdecl extInitialize(CWinApp *theApp)
{
// Enque some data queries to get some info we need to generate DIS PDUs.
// Done here in extInitialize, assuming they wont change on the fly and we only need to this once.
dataQueries.AddTail(&dqDisVersion);
dataQueries.AddTail(&dqDisExercise);
return TRUE;
}
__declspec(dllexport) void __cdecl extPreViewportUserDraw(ID3D11DeviceContext *pContext, int vpId, Viewport *vp)
{
// Heading Code (True Heading)
memcpy(&viewPortData, vp, sizeof(Viewport));
Matrix gccToView;
memcpy(gccToView.m, vp->gccToView, sizeof(vp->gccToView));
Matrix nedToGcc;
nedToGcc.makeNEDToGeo(vp->posGcc[0], vp->posGcc[1], vp->posGcc[2]);
Matrix nedToView = gccToView * nedToGcc;
double yaw, pitch, roll;
nedToView.getAngles(yaw, pitch, roll);
// Yaw euler angle is angle in radians. Convert from radians to degrees
heading = yaw * rad_to_deg;
// Degree Correction for (-180 - 0) range
if (heading < 0.0)
{
heading = heading + 360.0;
}
// End of heading code
}
_declspec(dllexport) void __cdecl extTick()
{
sf::Joystick::update();
static ExtDataQueryAttachEntityId dqEID;
dataQueries.AddTail(&dqEID);
dqEntityID.site = dqEID.site;
dqEntityID.host = dqEID.host;
dqEntityID.entity = dqEID.entity;
}
__declspec(dllexport) ExtDataQuery* __cdecl extDataQuery(void)
{
// Submit any pending queries to VRSG via return value. VRSG will
// call this in a loop until NULL is returned.
if (dataQueries.GetCount())
return (ExtDataQuery*)dataQueries.RemoveHead();
// None left to submit this frame.
return NULL;
}
void sendDesignatorPDU(float power)
{
memset(&pdu, 0, sizeof(pdu));
// Initialize header
pdu.header.family = 6;
pdu.header.kind = LaserPDUKind;
pdu.header.version = (BYTE)dqDisVersion.result;
pdu.header.exercise = (BYTE)dqDisExercise.result;
pdu.header.length = sizeof(pdu);
swapEndian(pdu.header.length);
// Who its from (Pull from VRSG)
pdu.entityID.simulator.site = dqEntityID.site;
pdu.entityID.simulator.host = dqEntityID.host;
pdu.entityID.entity = dqEntityID.entity;
pdu.drAlgo = 2;
swapEndian(pdu.entityID.simulator.site);
swapEndian(pdu.entityID.simulator.host);
swapEndian(pdu.entityID.entity);
// Laser params
pdu.codeName = 3;
swapEndian(pdu.codeName);
pdu.laserCode = 1118;
swapEndian(pdu.laserCode);
pdu.power = power;
swapEndian(pdu.power);
pdu.waveLength = 0.9f;
swapEndian(pdu.waveLength);
// Point lased
// If lased point is an entity, put entity info in pdu
if (entityLased == true)
{
pdu.lasedEntityID.simulator.site = point1.site;
pdu.lasedEntityID.simulator.host = point1.host;
pdu.lasedEntityID.entity = point1.entity;
}
swapEndian(pdu.lasedEntityID.simulator.site);
swapEndian(pdu.lasedEntityID.simulator.host);
swapEndian(pdu.lasedEntityID.entity = point1.entity);
coord_llz_to_gcc(DATUM_WGS84,
point1.lat,
point1.lon,
point1.alt,
&pdu.spot.x, &pdu.spot.y, &pdu.spot.z);
swapEndian(pdu.spot.x);
swapEndian(pdu.spot.y);
swapEndian(pdu.spot.z);
pdu.acceleration.x = 0;
pdu.acceleration.y = 0;
pdu.acceleration.z = 0;
swapEndian(pdu.acceleration.x);
swapEndian(pdu.acceleration.y);
swapEndian(pdu.acceleration.z);
static ExtDataQuerySendDisPdu dqSendPdu(sizeof(pdu), &pdu);
dataQueries.AddTail(&dqSendPdu);
}
//
#include <afxwin.h>
#include "stdafx.h" // Must be here, otherwise lots of errors
#include <afxdlgs.h>
#include <afxcmn.h>
#include <afxdllx.h>
#include <d3d11.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include "SFML\Window.hpp"
#include "VertexShader.h"
#include "PixelShader.h"
#include "Resource.h"
#include "Plugins.h"
#include "Vector.h"
#include "Coord.h"
#include "Geodesy.h"
#include "Dis.h"
#include "Swap.h"
static AFX_EXTENSION_MODULE NEAR extensionDLL = { NULL, NULL };
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p) = NULL; } }
static ID3D11Texture2D *pWhiteTexture;
static ID3D11ShaderResourceView *pWhiteTextureSRV;
static ID3D11Texture2D *pFontTexture;
static ID3D11ShaderResourceView *pFontTextureSRV;
static ID3D11SamplerState *pSampler;
static ID3D11VertexShader *pVertexShader;
static ID3D11PixelShader *pPixelShader;
static ID3D11InputLayout *pLayout;
static ID3D11Buffer *pVB;
static ID3D11Buffer *pIB;
#define VB_MAX 5000 // Max verts in our buffer before we reset
#define IB_MAX 2000 // Max indices in the buffer before we reset
static int vertsInBuffer; // Position in vertex buffer to insert next primitive's verts
static int indicesInBuffer; // Position in vertex buffer to insert next primitive's indices
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// Extension DLL one-time initialization.
if (!AfxInitExtensionModule(extensionDLL, hInstance))
return 0;
// Other initialization could be done here, as long as
// it doesn't result in direct or indirect calls to AfxGetApp.
// This extension DLL needs to add doc templates to the
// app object, so it waits for the application to boot
// and call an initialization function (see below).
new CDynLinkLibrary(extensionDLL);
}
return 1; // ok
}
// Data queries for sending DesignatorPDUs
static ExtDataQueryInteger dqDisVersion(DATA_QUERY_DIS_VERSION);
static ExtDataQueryInteger dqDisExercise(DATA_QUERY_EXERCISE_ID);
static ExtDataQueryAttachEntityId dqEntityID;
static ExtDataQueryVrsgId VrsgID;
static CPtrList dataQueries;
static LaserPDU pdu;
void sendDesignatorPDU(float power);
const int maxRange = 6000; // Max range of PLRF device: 6000 meters
static ExtLaserRangeData laserData; // Laserdata object
static Viewport viewPortData; // Viewportdata object
double heading, pitch; // Global heading, pitch
double geoc_pos[3], llz_pos[3]; // Global Location Values
int button = 4; // Button on device 0 = PLRF
// 4 = Fire Button on SOFLAM
int joystick = 0; // Joystick number
int seconds = 60; // 60 ticks in one second (60FPS)
bool entityLased;
bool debug, btnWasPressed, dblClick, cycleData,
sendStartPDU, sendEndPDU, firstClick;
int keyPressTimer, notPressedTimer, DCTimer,
singleClickTimer, done, displayTimer;
int dataType;
// Math Defines
#define pi ((double)3.14159265358979)
#define pio2 ((double)0.5*pi)
#define twopi ((double)2.0*pi)
#define deg_to_rad (twopi/(double)360.0)
#define rad_to_deg ((double)360.0/twopi)
#define Mil_to_deg (6400.0 / 360.0)
struct pointData
{
double range;
double lat;
double lon;
double alt;
double inclination;
double horizontalDistance;
double verticalDistance;
double azimuth;
unsigned short site;
unsigned short host;
unsigned short entity;
};
pointData point1;
pointData point2;
// A simple vertex format for drawing primitives
struct HomoVertex
{
// Homogeneous space
float x; // -1.0 (left edge) to 1.0 (right edge)
float y; // -1.0 (bottom edge) to 1.0 (top edge)
float z; // use zero here
// Color (0xAABBGGRR format)
DWORD color;
// Texture coords
float tu;
float tv;
};
// Texture coordinate table to convert characters to UV pairs
struct TCoordTable
{
float llu;
float llv;
float uru;
float urv;
} tcoordTable[256];
// makeFontTexture - uses the GDI to render a font to a bitmap. the
// bitmap is turned into a texture. tcoordTable contains the texture
// coordinates for each character in the font.
static ID3D11Texture2D *createFontTexture(ID3D11Device *pDevice)
{
// Make a bitmap for the GDI to render to
int hdrLen = sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255;
BITMAPINFO *bmi = (BITMAPINFO *) new char[hdrLen];
memset(bmi, 0, hdrLen);
bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi->bmiHeader.biWidth = 256;
bmi->bmiHeader.biHeight = 256;
bmi->bmiHeader.biPlanes = 1;
bmi->bmiHeader.biCompression = BI_RGB;
bmi->bmiHeader.biBitCount = 8;
for (int i = 0; i < 256; i++)
{
bmi->bmiColors[i].rgbRed = i;
bmi->bmiColors[i].rgbGreen = i;
bmi->bmiColors[i].rgbBlue = i;
bmi->bmiColors[i].rgbReserved = 0;
}
// Create a DC and a bitmap for the font
HDC hDC = CreateCompatibleDC(NULL);
DWORD *pBitmapBits;
HBITMAP hbmBitmap = CreateDIBSection(hDC, bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0);
SetMapMode(hDC, MM_TEXT);
// Create a font. A 30 unit height should allow all printable chars to fit into a 256x256
int nHeight = MulDiv(30, 96, GetDeviceCaps(hDC, LOGPIXELSY));
HFONT hFont = CreateFont(nHeight, 0, 0, 0, FW_HEAVY, FALSE,
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
VARIABLE_PITCH, "Lucida Console");
SelectObject(hDC, hbmBitmap);
SelectObject(hDC, hFont);
SetTextColor(hDC, RGB(255, 255, 255));
SetBkColor(hDC, RGB(0, 0, 0));
SetTextAlign(hDC, TA_TOP | TA_LEFT);
// Output all the chars and save the tcoords
int x = 0;
int y = 0;
SIZE size;
for (char c = 32; c < 127; c++)
{
// See if char will fit on current line or if we need to wrap
GetTextExtentPoint32(hDC, &c, 1, &size);
if (x + size.cx + 1 > 256)
{
x = 0;
y += size.cy + 1;
}
// Output the char
ExtTextOut(hDC, x, y, ETO_OPAQUE, NULL, &c, 1, NULL);
// Save tcoords of this char
tcoordTable[c - 32].llu = (float)x / 256.0f;
tcoordTable[c - 32].llv = 1.0f - ((float)(y + size.cy) / 256.0f);
tcoordTable[c - 32].uru = (float)(x + size.cx) / 256.0f;
tcoordTable[c - 32].urv = 1.0f - ((float)y / 256.0f);
x += size.cx + 1;
}
// Create an array of data to initialize the texture from.
// Populate the texels of the texture with the image
// the GDI rendered to. Treat black pixels as transparent
// and others as pure white.
DWORD *pImageData = new DWORD[256 * 256];
DWORD *p = pImageData;
DWORD color;
BYTE *pColor = (BYTE *)pBitmapBits;
for (int y = 0; y < 256; y++)
{
for (int x = 0; x < 256; x++)
{
if (*pColor++)
color = 0xffffffff;
else
color = 0x00ffffff;
*p++ = color;
}
}
// Cleanup GDI stuff
DeleteObject(hbmBitmap);
DeleteDC(hDC);
DeleteObject(hFont);
delete[] bmi;
D3D11_TEXTURE2D_DESC tdesc;
memset(&tdesc, 0, sizeof(tdesc));
tdesc.Width = 256;
tdesc.Height = 256;
tdesc.MipLevels = 1;
tdesc.ArraySize = 1;
tdesc.SampleDesc.Count = 1;
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
tdesc.Usage = D3D11_USAGE_DEFAULT;
tdesc.CPUAccessFlags = 0;
tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = pImageData;
initData.SysMemPitch = 4 * 256;
ID3D11Texture2D *pTexture;
pDevice->CreateTexture2D(&tdesc, &initData, &pTexture);
delete[] pImageData;
return pTexture;
}
static bool copyToBuffer(const void *data, int elementSize, int count, int maxCount, int &index,
ID3D11Buffer *pBuffer, ID3D11DeviceContext *pContext)
{
D3D11_MAPPED_SUBRESOURCE mapData;
D3D11_MAP mapType;
if (index + count < maxCount)
{
// Append to active buffer
mapType = D3D11_MAP_WRITE_NO_OVERWRITE;
}
else
{
// Buffer full, must start over
mapType = D3D11_MAP_WRITE_DISCARD;
index = 0;
}
if (pContext->Map(pBuffer, 0, mapType, 0, &mapData) != S_OK)
return false;
CopyMemory((BYTE*)mapData.pData + index*elementSize, data, count*elementSize);
pContext->Unmap(pBuffer, 0);
return true;
}
// Drawing non-indexed primitives
static void drawPrimitive(
const HomoVertex *verts, int numVerts,
D3D11_PRIMITIVE_TOPOLOGY topo,
ID3D11DeviceContext *pContext)
{
// Copy verts and indicies into their respective buffers
copyToBuffer(verts, sizeof(HomoVertex), numVerts, VB_MAX, vertsInBuffer, pVB, pContext);
// Now we can draw
pContext->IASetPrimitiveTopology(topo);
pContext->Draw(numVerts, vertsInBuffer);
vertsInBuffer += numVerts;
}
// Drawing indexed primitives
static void drawPrimitive(
const HomoVertex *verts, int numVerts,
const WORD *indices, int numIndices,
D3D11_PRIMITIVE_TOPOLOGY topo,
ID3D11DeviceContext *pContext)
{
// Copy verts and indicies into their respective buffers
copyToBuffer(verts, sizeof(HomoVertex), numVerts, VB_MAX, vertsInBuffer, pVB, pContext);
copyToBuffer(indices, sizeof(WORD), numIndices, IB_MAX, indicesInBuffer, pIB, pContext);
// Now we can draw
pContext->IASetPrimitiveTopology(topo);
pContext->DrawIndexed(numIndices, indicesInBuffer, vertsInBuffer);
// Update the buffer indices
vertsInBuffer += numVerts;
indicesInBuffer += numIndices;
}
// This function get the 4 texture coordinates needed to pull out a given
// character from the font texture.
static void getTextureCoords(char c,
float &u0, float &v0, float &u1, float &v1,
float &u2, float &v2, float &u3, float &v3)
{
c -= 32;
if (c < 0)
{
u0 = 0.0f;
v0 = 0.0f;
u1 = 0.0f;
v1 = 0.0f;
u2 = 0.0f;
v2 = 0.0f;
u3 = 0.0f;
v3 = 0.0f;
}
else
{
u0 = tcoordTable[c].llu;
v0 = tcoordTable[c].llv;
u1 = tcoordTable[c].uru;
v1 = tcoordTable[c].llv;
u2 = tcoordTable[c].uru;
v2 = tcoordTable[c].urv;
u3 = tcoordTable[c].llu;
v3 = tcoordTable[c].urv;
}
}
// This function draws a string of text characters as a triangle list of textured quads.
// It uses getTextureCoords to get the texture coords from the font texture for each
// quad.
static void drawText(const char *msg, float x, float y, float thetaRadians, float width, float height, DWORD color,
ID3D11DeviceContext *pContext)
{
// Bind the font texture
pContext->PSSetShaderResources(0, 1, &pFontTextureSRV);
static HomoVertex p[80]; // Draw up to 20 chars (80/4) in a single API call
static WORD indicies[120]; // Need 6 indices for each of the 20 chars (two quads)
int len = (int)strlen(msg);
int t = 0;
int v = 0;
float dx = width*cosf(thetaRadians);
float dy = -width*sinf(thetaRadians);
float hdx = -height*0.5f*sinf(thetaRadians);
float hdy = -height*0.5f*cosf(thetaRadians);
// For each character, make a quad
for (int i = 0; i < len; i++)
{
// Get tcoords of current char
getTextureCoords(msg[i],
p[v + 0].tu, p[v + 0].tv,
p[v + 1].tu, p[v + 1].tv,
p[v + 2].tu, p[v + 2].tv,
p[v + 3].tu, p[v + 3].tv);
// Lower left
p[v + 0].x = x + hdx + i*dx;
p[v + 0].y = y + hdy + i*dy;
p[v + 0].z = 0.0f;
p[v + 0].color = color;
// Lower right
p[v + 1].x = x + hdx + (i + 1.0f)*dx;
p[v + 1].y = y + hdy + (i + 1.0f)*dy;
p[v + 1].z = 0.0f;
p[v + 1].color = color;
// Upper right
p[v + 2].x = x - hdx + (i + 1.0f)*dx;
p[v + 2].y = y - hdy + (i + 1.0f)*dy;
p[v + 2].z = 0.0f;
p[v + 2].color = color;
// Upper left
p[v + 3].x = x - hdx + i*dx;
p[v + 3].y = y - hdy + i*dy;
p[v + 3].z = 0.0f;;
p[v + 3].color = color;
// Make the indicies. Note indices are in counter-clockwise order
indicies[t++] = v + 0;
indicies[t++] = v + 1;
indicies[t++] = v + 2;
indicies[t++] = v + 0;
indicies[t++] = v + 2;
indicies[t++] = v + 3;
v += 4;
// See if we need to flush
if (v == ARRAYSIZE(p))
{
drawPrimitive(p, v, indicies, t, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
v = 0;
t = 0;
}
}
// Draw anything remaining
if (v)
{
drawPrimitive(p, v, indicies, t, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
}
}
static void createDeviceObjects(ID3D11DeviceContext *pContext)
{
// Create all the objects we need under the new D3D Device
// Need a handle to the device
ID3D11Device *pDevice = NULL;
pContext->GetDevice(&pDevice);
// Create the vertex layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
pDevice->CreateInputLayout(layout, ARRAYSIZE(layout), g_VertexShader, sizeof(g_VertexShader), &pLayout);
// Create the shaders
pDevice->CreateVertexShader(g_VertexShader, sizeof(g_VertexShader), NULL, &pVertexShader);
pDevice->CreatePixelShader(g_PixelShader, sizeof(g_PixelShader), NULL, &pPixelShader);
// Create the font texture
pFontTexture = createFontTexture(pDevice);
// Create the shader resource view for the font texture
pDevice->CreateShaderResourceView(pFontTexture, NULL, &pFontTextureSRV);
// Create a sampler state
D3D11_SAMPLER_DESC sampDesc;
ZeroMemory(&sampDesc, sizeof(sampDesc));
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
sampDesc.MinLOD = 0;
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
pDevice->CreateSamplerState(&sampDesc, &pSampler);
// Create the vertex buffer
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.ByteWidth = sizeof(HomoVertex) * VB_MAX;
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
pDevice->CreateBuffer(&bd, NULL, &pVB);
// Create an index buffer
bd.ByteWidth = sizeof(WORD) * IB_MAX;
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
pDevice->CreateBuffer(&bd, NULL, &pIB);
// Initialize indexes into buffers
vertsInBuffer = 0;
indicesInBuffer = 0;
// Create a plain white texture for things we dont want textured
D3D11_TEXTURE2D_DESC tdesc;
memset(&tdesc, 0, sizeof(tdesc));
tdesc.Width = 1;
tdesc.Height = 1;
tdesc.MipLevels = 1;
tdesc.ArraySize = 1;
tdesc.SampleDesc.Count = 1;
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
tdesc.Usage = D3D11_USAGE_DEFAULT;
tdesc.CPUAccessFlags = 0;
tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
D3D11_SUBRESOURCE_DATA initData;
DWORD white = 0xffffffff;
initData.pSysMem = &white;
initData.SysMemPitch = 4 * 256;
pDevice->CreateTexture2D(&tdesc, &initData, &pWhiteTexture);
pDevice->CreateShaderResourceView(pWhiteTexture, NULL, &pWhiteTextureSRV);
}
struct Viewport;
__declspec(dllexport) void __cdecl extPostViewportUserDraw(ID3D11DeviceContext *pContext, int vpId, Viewport *vp)
{
// First time in or after device reset, create our resources
if (pFontTexture == NULL)
createDeviceObjects(pContext);
// Remove the depth buffer
ID3D11RenderTargetView *pBackBufferView;
ID3D11DepthStencilView *pDepthStencilView = NULL;
pContext->OMGetRenderTargets(1, &pBackBufferView, &pDepthStencilView);
pContext->OMSetRenderTargets(1, &pBackBufferView, NULL);
SAFE_RELEASE(pDepthStencilView);
// Setup some required render states
UINT stride = sizeof(HomoVertex);
UINT offset = 0;
pContext->IASetVertexBuffers(0, 1, &pVB, &stride, &offset);
pContext->IASetIndexBuffer(pIB, DXGI_FORMAT_R16_UINT, 0);
pContext->IASetInputLayout(pLayout);
pContext->VSSetShader(pVertexShader, NULL, 0);
pContext->PSSetShader(pPixelShader, NULL, 0);
pContext->PSSetSamplers(0, 1, &pSampler);
// You are drawing in 3D. There is an coordinate system aligned with the ownship.
// It is using the DIS/CIGI convention of X forward, Y right, Z down. Imagine
// the canvans 'renderPlaneDist' meters in front of the airplane. The Y and Z axes
// position the objects horizontally and vertically on this canvas.
// Bind the white texture, since we dont want texture on lines. Color can be
// given per-vertex on non-textured primitives, using the DWORD color member of
// HomoVertex. Colors are encoded in AAGGBBRR format. Note that drawing text
// binds the font texture, so you need to call this again after drawing text.
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// Draw crosshairs. Since this a list of independant lines, no verts are
// repeated, and we can use the simpler non-indexed form of drawPrimtive().
// For drawing a strip of connected lines, you would instead use
// D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP.
// x,y,z(always 0),color,(tu,tv) textured cords
HomoVertex verts[] = {
// First Segment on Vertical (From Center) (2 Verts) Black
-.025f, .18f, 0.0f, 0xff000000, 0.0f, 0.0f,
.025f, .18f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Second Segment on Vertical (2 Verts)
-.025f, .36f, 0.0f, 0xff000000, 0.0f, 0.0f,
.025f, .36f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Third Segment on Vertical (2 Verts)
-.025f, .54f, 0.0f, 0xff000000, 0.0f, 0.0f,
.025f, .54f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Fourth Segment on Vertical (2 Verts)
-.025f, .72f, 0.0f, 0xff000000, 0.0f, 0.0f,
.025f, .72f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Fifth Segment on Vertical (2 Verts)
-.025f, .90f, 0.0f, 0xff000000, 0.0f, 0.0f,
.025f, .90f, 0.0f, 0xff000000, 0.0f, 0.0f,
// First Segment on Left (From Center) (2 Verts) Black
-.18f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
-.18f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Second Segment on left (2 Verts)
-.36f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
-.36f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Third Segment on left (2 Verts)
-.54f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
-.54f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Forth Segment on left (2 Verts)
-.72f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
-.72f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Fifth Segment on left (2 Verts)
-.90f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
-.90f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// First Segment on Right (From Center) (2 Verts) Black
.18f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
.18f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Second Segment on Right (2 Verts)
.36f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
.36f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Third Segment on Right (2 Verts)
.54f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
.54f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Forth Segment on Right (2 Verts)
.72f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
.72f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Fifth Segment on Right (2 Verts)
.90f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
.90f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Center Crosshair (4 Verts) Black
// Horizontal Line
-0.025f, 0.0f, 0.0f, 0xff000000, 0.0f, 0.0f,
0.025f, 0.0f, 0.0f, 0xff000000, 0.0f, 0.0f,
// Vertical Line
0.0f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
0.0f, 0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
};
// Draw Crosshairs
drawPrimitive(verts, 34, D3D11_PRIMITIVE_TOPOLOGY_LINELIST, pContext);
// Draw text on Screen then Reset to Null Texture after each Text draw
// Draw text on left side
// Draw 30-50 degree markings
drawText("30", -.57f, -0.075f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("50", -.93f, -0.075f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// Draw text on right side
drawText("30", .51f, -0.075f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("50", .87f, -0.075f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// Draw text on vertical side
drawText("30", -.1f, 0.54f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("50", -.1f, 0.9f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// **************************************************************************************************
// Draw a circle. There are many shared verts, so we do this as an indexed
// triangle list for efficiency.
for (int j = 1; j < 6; j++) // Draw Circles on left side
{
double offset = .09;
double answer = ((.18 * j) - offset);
const int numVerts = 20;
double centerX = -(answer);
double centerY = 0.0f;
const float radius = 0.005f;
const float PI = 3.14159265f;
HomoVertex circVerts[numVerts + 1]; // add an extra vert for the center
WORD indicies[numVerts * 3]; // need 3 indices per triangle
// verts around the circumference
for (int i = 0; i < numVerts; i++)
{
float theta = (2.0f * PI) * (float)i / (float)numVerts;
circVerts[i].x = centerX + radius*cosf(theta);
circVerts[i].y = centerY + radius*sinf(theta);
circVerts[i].z = 0.0f;
circVerts[i].color = 0xff000000; // black
circVerts[i].tu = 0.0f;
circVerts[i].tv = 0.0;
}
// and one at the center
circVerts[numVerts].x = centerX;
circVerts[numVerts].y = centerY;
circVerts[numVerts].z = 0.0f;
circVerts[numVerts].color = 0xff000000; // black
circVerts[numVerts].tu = 0.0f;
circVerts[numVerts].tv = 0.0;
// make the triangle indices
for (int i = 0; i < numVerts; i++)
{
indicies[i * 3 + 0] = numVerts; // the center
indicies[i * 3 + 1] = i;
indicies[i * 3 + 2] = (i + 1) % numVerts;
}
// Now we can draw it
drawPrimitive(circVerts, numVerts + 1, indicies, numVerts * 3, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
}
// ********************************************************************************************************************** //
for (int j = 1; j < 6; j++) // Draw Circles on Right side
{
float offset = .09;
float answer = ((.18 * j) - offset);
const int numVerts = 20;
float centerX = (answer);
float centerY = 0.0f;
const float radius = 0.005f;
const float PI = 3.14159265f;
HomoVertex circVerts[numVerts + 1]; // add an extra vert for the center
WORD indicies[numVerts * 3]; // need 3 indices per triangle
// verts around the circumference
for (int i = 0; i < numVerts; i++)
{
float theta = (2.0f * PI) * (float)i / (float)numVerts;
circVerts[i].x = centerX + radius*cosf(theta);
circVerts[i].y = centerY + radius*sinf(theta);
circVerts[i].z = 0.0f;
circVerts[i].color = 0xff000000; // black
circVerts[i].tu = 0.0f;
circVerts[i].tv = 0.0;
}
// and one at the center
circVerts[numVerts].x = centerX;
circVerts[numVerts].y = centerY;
circVerts[numVerts].z = 0.0f;
circVerts[numVerts].color = 0xff000000; // black
circVerts[numVerts].tu = 0.0f;
circVerts[numVerts].tv = 0.0;
// make the triangle indices
for (int i = 0; i < numVerts; i++)
{
indicies[i * 3 + 0] = numVerts; // the center
indicies[i * 3 + 1] = i;
indicies[i * 3 + 2] = (i + 1) % numVerts;
}
// Now we can draw it
drawPrimitive(circVerts, numVerts + 1, indicies, numVerts * 3, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
}
// ********************************************************************************************************************** //
for (int j = 1; j < 6; j++) // Draw Circles on Vertical side
{
float offset = .09;
float answer = ((.18 * j) - offset);
const int numVerts = 20;
float centerX = 0.0f;
float centerY = answer;
const float radius = 0.005f;
const float PI = 3.14159265f;
HomoVertex circVerts[numVerts + 1]; // add an extra vert for the center
WORD indicies[numVerts * 3]; // need 3 indices per triangle
// verts around the circumference
for (int i = 0; i < numVerts; i++)
{
float theta = (2.0f * PI) * (float)i / (float)numVerts;
circVerts[i].x = centerX + radius*cosf(theta);
circVerts[i].y = centerY + radius*sinf(theta);
circVerts[i].z = 0.0f;
circVerts[i].color = 0xff000000; // black
circVerts[i].tu = 0.0f;
circVerts[i].tv = 0.0;
}
// and one at the center
circVerts[numVerts].x = centerX;
circVerts[numVerts].y = centerY;
circVerts[numVerts].z = 0.0f;
circVerts[numVerts].color = 0xff000000; // black
circVerts[numVerts].tu = 0.0f;
circVerts[numVerts].tv = 0.0;
// make the triangle indices
for (int i = 0; i < numVerts; i++)
{
indicies[i * 3 + 0] = numVerts; // the center
indicies[i * 3 + 1] = i;
indicies[i * 3 + 2] = (i + 1) % numVerts;
}
// Now we can draw it
drawPrimitive(circVerts, numVerts + 1, indicies, numVerts * 3, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
}
// Lat in geocentric
geoc_pos[0] = viewPortData.posGcc[0];
// Lon in geocentric
geoc_pos[1] = viewPortData.posGcc[1];
// Height in geocentric
geoc_pos[2] = viewPortData.posGcc[2];
// Convert geocentric postion to lat/lon/height
coord_gcc_to_llz(geoc_pos[0], geoc_pos[1], geoc_pos[2], DATUM_WGS84, &llz_pos[0], &llz_pos[1], &llz_pos[2]);
// Calculate Magnetic variance from lat/lon
double MagVar = MetaVR::getMagVar(llz_pos[0], llz_pos[1]);
// Add Variance to True Heading to get Magnetic Heading. East is negative
double MagHeading = heading - MagVar;
if (MagHeading > 360.0) // Degree Correction for Magnetic Heading being greater than 360
{
MagHeading = round(MagHeading - 360); // Round Magnetic Heading
}
if (MagHeading < 0.0) // Degree Correction for Magnetic Heading being less than 0
{
MagHeading = round(MagHeading + 360); // Round Magnetic Heading
}
// ********************************************************************************************************************** //
// Create Joystick Code Here
char headingText[15];
//// Height
//height = sin(point1.inclination) * point1.range;
//// Horizontal Distance
//hDist = tan(point1.inclination) * height;
//drawText("AZI", -.18f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "AZ"
//pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
//sprintf_s(headingText, "%3.0f", MagHeading);
//drawText(headingText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red magnetic heading
//pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
//drawText("o", 0.13f, -0.17f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "o"
//pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
//
//drawText("D", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
//pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
//
//char rangeText[6];
//sprintf_s(rangeText, "%4.0f", point1.range);
//drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
//pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
//drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
//pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// Holding Button
if (sf::Joystick::isButtonPressed(joystick, button) && firstClick == true)
{
// Single Click
drawText("AZI", -.18f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "AZ"
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(headingText, "%3.0f", MagHeading);
drawText(headingText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red magnetic heading
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("o", 0.13f, -0.17f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "o"
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
btnWasPressed = true;
done = false; // Get new data on button release
notPressedTimer = 0;
displayTimer = 0;
sendStartPDU = false;
sendEndPDU = false;
}
// Release of Button
if (!(sf::Joystick::isButtonPressed(joystick, button)) && btnWasPressed == true)
{
if (displayTimer < (3 * seconds))
{
//if (cycleData == true)
//{
// if (dataType == 1) // Distance
// {
// drawText("D", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// char rangeText[6];
// sprintf_s(rangeText, "%4.0f", point1.range);
// drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// }
// else if (dataType == 2) // Horizontal Distance
// {
// drawText("H", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// char rangeText[6];
// sprintf_s(rangeText, "%4.0f", point1.horizontalDistance);
// drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// }
// else if (dataType == 3) // Vertical Height Distance
// {
// drawText("V", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// char rangeText[6];
// sprintf_s(rangeText, "%4.0f", point1.verticalDistance);
// drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// }
// else if (dataType == 4) // Azimuth (Heading)
// {
// drawText("AZI", -.18f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "AZ"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// sprintf_s(headingText, "%3.0f", MagHeading);
// drawText(headingText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red magnetic heading
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// drawText("o", 0.13f, -0.17f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "o"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// }
// else if (dataType == 5) // inclination
// {
// drawText("INC", -.18f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "AZ"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// sprintf_s(headingText, "%3.0f", point1.inclination);
// drawText(headingText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red magnetic heading
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// drawText("o", 0.13f, -0.17f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "o"
// pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
// }
//}
//else
//{
drawText("D", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
if (done == false)
{
// Range
point1.range = laserData.range;
// Alt
point1.alt = laserData.alt;
// Lat
point1.lat = laserData.lat;
// Lon
point1.lon = laserData.lon;
// Entity Lased
if (laserData.bEntityIdValid == true)
{
point1.site = laserData.site;
point1.host = laserData.host;
point1.entity = laserData.entity;
entityLased = true;
}
else
{
point1.site = 0;
point1.host = 0;
point1.entity = 0;
entityLased = false;
}
// Inclination
point1.inclination = pitch;
// Vertical Distance
point1.verticalDistance = sin(point1.inclination) * point1.range;
// Horizontal Distance
point1.horizontalDistance = tan(point1.inclination) * point1.verticalDistance;
// Azimuth
point1.azimuth = MagHeading;
done = true;
}
if ((point1.range <= maxRange) && (point1.range != 0)) // Display Range if laser range is below maxRange
{
if (sendStartPDU == false)
{
sendDesignatorPDU(10.0f);
sendStartPDU = true;
}
char rangeText[6];
sprintf_s(rangeText, "%4.0f", point1.range);
drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
}
else // Draw ---- to indicate range > maxrange
{
drawText("----", 0.0f, -0.1f, 0.0f, 0.04f, 0.06f, 0xff0000ff, pContext); // Red "----"
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
}
}
if (displayTimer > (.1 * seconds))
{
if (sendEndPDU == false)
{
sendDesignatorPDU(0.0f);
sendEndPDU = true;
}
}
firstClick = false;
displayTimer += 1;
}
// Cycle Data
if (sf::Joystick::isButtonPressed(joystick, button) && btnWasPressed == true && dblClick == true)
{
dataType++;
cycleData = true;
if (dataType == 6) // start over
{
dataType = 1;
}
}
// Button not being pressed
if (!(sf::Joystick::isButtonPressed(joystick, button)))
{
notPressedTimer += 1;
if (notPressedTimer < (1 * seconds))
{
dblClick == true;
}
else
{
dblClick == false;
}
// No Click
if (notPressedTimer > (3 * seconds)) // reset all timers and states after 3 seconds since last button press
{
dataType = 1;
firstClick = true;
done = false;
dblClick = false;
btnWasPressed = false;
displayTimer = 0;
sendStartPDU = false;
sendEndPDU = false;
}
}
// ********************************************************************************************************************** //
// Debug Screen if "D" on keyboard is pressed
char debugText[15];
if ((sf::Keyboard::isKeyPressed(sf::Keyboard::F6)) && debug == false)
{
keyPressTimer += 1;
if (keyPressTimer > (.3 * seconds))
{
debug = true;
keyPressTimer = 0;
}
}
if ((sf::Keyboard::isKeyPressed(sf::Keyboard::F6)) && debug == true)
{
keyPressTimer += 1;
if (keyPressTimer > (.3 * seconds))
{
debug = false;
keyPressTimer = 0;
}
}
if (!(sf::Keyboard::isKeyPressed(sf::Keyboard::F6)))
{
keyPressTimer = 0;
}
if (debug == true)
{
if (sf::Joystick::isConnected(joystick))
{
drawText("Is Connected", .03f, 0.45f, 0.0f, 0.04f, 0.06f, 0xff0000ff, pContext); // Connected
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
}
else
{
drawText("Is not Connected", .05f, 0.5f, 0.0f, 0.04f, 0.06f, 0xff0000ff, pContext); // Not Connected
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
}
drawText("Heading", -.4f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Heading
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", heading);
drawText(debugText, 0.0f, -0.1, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("MagVar", -.4f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Magnetic Variation
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", MagVar);
drawText(debugText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("MagHeading", -.5f, -0.3f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Magnetic Heading
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", MagHeading);
drawText(debugText, 0.0f, -0.3, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("LAT", -.18f, -0.4f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Latitude
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", llz_pos[0]);
drawText(debugText, 0.0f, -0.4, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("LON", -.18f, -0.5f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Longitude
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", llz_pos[1]);
drawText(debugText, 0.0f, -0.5, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("ALT", -.18f, -0.6f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Altitude
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", llz_pos[2]);
drawText(debugText, 0.0f, -0.6, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("Geo X", -.28f, -0.7f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Geocentric X position
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", geoc_pos[0]);
drawText(debugText, 0.0f, -0.7, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("Geo Y", -.28f, -0.8f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Geocentric Y position
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", geoc_pos[1]);
drawText(debugText, 0.0f, -0.8, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
drawText("Geo Z", -.28f, -0.9f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Geocentric Z position
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
sprintf_s(debugText, "%3.3f", geoc_pos[2]);
drawText(debugText, 0.0f, -0.9, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
}
// ********************************************************************************************************************** //
}
__declspec(dllexport) void __cdecl extResetDevice()
{
// Device has been reset. Release the objects we created under the device.
// We will recreate them on the next call to extPostViewportUserDraw
SAFE_RELEASE(pWhiteTexture);
SAFE_RELEASE(pWhiteTextureSRV);
SAFE_RELEASE(pFontTexture);
SAFE_RELEASE(pFontTextureSRV);
SAFE_RELEASE(pSampler);
SAFE_RELEASE(pVertexShader);
SAFE_RELEASE(pPixelShader);
SAFE_RELEASE(pLayout);
SAFE_RELEASE(pVB);
SAFE_RELEASE(pIB);
}
__declspec(dllexport) void __cdecl extLaserRange(const ExtLaserRangeData *data)
{
laserData = *data; // copy ExtLaserRangeData *data to laserData object
}
__declspec(dllexport) BOOL __cdecl extInitialize(CWinApp *theApp)
{
// Enque some data queries to get some info we need to generate DIS PDUs.
// Done here in extInitialize, assuming they wont change on the fly and we only need to this once.
dataQueries.AddTail(&dqDisVersion);
dataQueries.AddTail(&dqDisExercise);
return TRUE;
}
__declspec(dllexport) void __cdecl extPreViewportUserDraw(ID3D11DeviceContext *pContext, int vpId, Viewport *vp)
{
// Heading Code (True Heading)
memcpy(&viewPortData, vp, sizeof(Viewport));
Matrix gccToView;
memcpy(gccToView.m, vp->gccToView, sizeof(vp->gccToView));
Matrix nedToGcc;
nedToGcc.makeNEDToGeo(vp->posGcc[0], vp->posGcc[1], vp->posGcc[2]);
Matrix nedToView = gccToView * nedToGcc;
double yaw, pitch, roll;
nedToView.getAngles(yaw, pitch, roll);
// Yaw euler angle is angle in radians. Convert from radians to degrees
heading = yaw * rad_to_deg;
// Degree Correction for (-180 - 0) range
if (heading < 0.0)
{
heading = heading + 360.0;
}
// End of heading code
}
_declspec(dllexport) void __cdecl extTick()
{
sf::Joystick::update();
static ExtDataQueryAttachEntityId dqEID;
dataQueries.AddTail(&dqEID);
dqEntityID.site = dqEID.site;
dqEntityID.host = dqEID.host;
dqEntityID.entity = dqEID.entity;
}
__declspec(dllexport) ExtDataQuery* __cdecl extDataQuery(void)
{
// Submit any pending queries to VRSG via return value. VRSG will
// call this in a loop until NULL is returned.
if (dataQueries.GetCount())
return (ExtDataQuery*)dataQueries.RemoveHead();
// None left to submit this frame.
return NULL;
}
void sendDesignatorPDU(float power)
{
memset(&pdu, 0, sizeof(pdu));
// Initialize header
pdu.header.family = 6;
pdu.header.kind = LaserPDUKind;
pdu.header.version = (BYTE)dqDisVersion.result;
pdu.header.exercise = (BYTE)dqDisExercise.result;
pdu.header.length = sizeof(pdu);
swapEndian(pdu.header.length);
// Who its from (Pull from VRSG)
pdu.entityID.simulator.site = dqEntityID.site;
pdu.entityID.simulator.host = dqEntityID.host;
pdu.entityID.entity = dqEntityID.entity;
pdu.drAlgo = 2;
swapEndian(pdu.entityID.simulator.site);
swapEndian(pdu.entityID.simulator.host);
swapEndian(pdu.entityID.entity);
// Laser params
pdu.codeName = 3;
swapEndian(pdu.codeName);
pdu.laserCode = 1118;
swapEndian(pdu.laserCode);
pdu.power = power;
swapEndian(pdu.power);
pdu.waveLength = 0.9f;
swapEndian(pdu.waveLength);
// Point lased
// If lased point is an entity, put entity info in pdu
if (entityLased == true)
{
pdu.lasedEntityID.simulator.site = point1.site;
pdu.lasedEntityID.simulator.host = point1.host;
pdu.lasedEntityID.entity = point1.entity;
}
swapEndian(pdu.lasedEntityID.simulator.site);
swapEndian(pdu.lasedEntityID.simulator.host);
swapEndian(pdu.lasedEntityID.entity = point1.entity);
coord_llz_to_gcc(DATUM_WGS84,
point1.lat,
point1.lon,
point1.alt,
&pdu.spot.x, &pdu.spot.y, &pdu.spot.z);
swapEndian(pdu.spot.x);
swapEndian(pdu.spot.y);
swapEndian(pdu.spot.z);
pdu.acceleration.x = 0;
pdu.acceleration.y = 0;
pdu.acceleration.z = 0;
swapEndian(pdu.acceleration.x);
swapEndian(pdu.acceleration.y);
swapEndian(pdu.acceleration.z);
static ExtDataQuerySendDisPdu dqSendPdu(sizeof(pdu), &pdu);
dataQueries.AddTail(&dqSendPdu);
}