light position debug pipeline, keyboard camera movement
This commit is contained in:
parent
ed2160a935
commit
4526aaa2c5
@ -79,7 +79,7 @@ fn lighting(position: vec3f, normal: vec3f) -> vec3f
|
|||||||
{
|
{
|
||||||
let d = 0.9;
|
let d = 0.9;
|
||||||
let eyePosition = vec3f(d, d / 2, d);
|
let eyePosition = vec3f(d, d / 2, d);
|
||||||
let lightPosition = vec3f(1, 1, 1);
|
let lightPosition = vec3f(100, 100, 100);
|
||||||
let lightVector = normalize(lightPosition - position);
|
let lightVector = normalize(lightPosition - position);
|
||||||
let ndotl = max(dot(lightVector, normal), 0.0);
|
let ndotl = max(dot(lightVector, normal), 0.0);
|
||||||
let intensity = (ndotl + 0.3) / 1.3;
|
let intensity = (ndotl + 0.3) / 1.3;
|
||||||
@ -95,5 +95,5 @@ fn fragmentMain(input: FragmentInput) -> @location(0) vec4f
|
|||||||
let intensity = lighting(input.positionWorld, normalize(input.normal));
|
let intensity = lighting(input.positionWorld, normalize(input.normal));
|
||||||
let color = textureSample(colorTexture, linearSampler, input.texture);
|
let color = textureSample(colorTexture, linearSampler, input.texture);
|
||||||
|
|
||||||
return vec4(color.xyz, 1.0);
|
return vec4(color.xyz * intensity, 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
143
index.js
143
index.js
@ -1,5 +1,6 @@
|
|||||||
import { getPath } from "./common.js";
|
import { getPath } from "./common.js";
|
||||||
import { loadGltf } from "./index2.js";
|
import { loadGltf } from "./index2.js";
|
||||||
|
import { loadLight } from "./light.js";
|
||||||
|
|
||||||
if (!navigator.gpu) {
|
if (!navigator.gpu) {
|
||||||
throw new Error("WebGPU not supported on this browser.");
|
throw new Error("WebGPU not supported on this browser.");
|
||||||
@ -441,18 +442,150 @@ function render()
|
|||||||
}
|
}
|
||||||
//requestAnimationFrame(render);
|
//requestAnimationFrame(render);
|
||||||
|
|
||||||
const gltfRenderer = await loadGltf(device, canvasFormat, memory2, module);
|
const matrixSize = 4 * 4 * 4;
|
||||||
|
const float4Size = 4 * 4;
|
||||||
|
const float3Size = 4 * 3;
|
||||||
|
const viewUniformBufferSize = (matrixSize * 2) + (float4Size * 1);
|
||||||
|
|
||||||
|
const viewUniformBuffer = device.createBuffer({
|
||||||
|
label: "view uniform buffer",
|
||||||
|
size: viewUniformBufferSize,
|
||||||
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
||||||
|
});
|
||||||
|
|
||||||
|
const cameraStateSize = (float3Size * 3) + (4 * 3) + (float3Size * 1);
|
||||||
|
|
||||||
|
const viewStateAddress = module.instance.exports.mem_alloc(viewUniformBufferSize);
|
||||||
|
const cameraStateAddress = module.instance.exports.mem_alloc(cameraStateSize);
|
||||||
|
|
||||||
|
module.instance.exports.camera_init(cameraStateAddress);
|
||||||
|
|
||||||
|
const gltfRenderer = await loadGltf(device, canvasFormat, viewUniformBuffer, memory2, module);
|
||||||
|
const lightRenderer = await loadLight(device, canvasFormat, viewUniformBuffer);
|
||||||
|
|
||||||
|
|
||||||
|
const KEY = {
|
||||||
|
A: 65,
|
||||||
|
B: 66,
|
||||||
|
C: 67,
|
||||||
|
D: 68,
|
||||||
|
E: 69,
|
||||||
|
F: 70,
|
||||||
|
G: 71,
|
||||||
|
H: 72,
|
||||||
|
I: 73,
|
||||||
|
J: 74,
|
||||||
|
K: 75,
|
||||||
|
L: 76,
|
||||||
|
M: 77,
|
||||||
|
N: 78,
|
||||||
|
O: 79,
|
||||||
|
P: 80,
|
||||||
|
Q: 81,
|
||||||
|
R: 82,
|
||||||
|
S: 83,
|
||||||
|
T: 84,
|
||||||
|
U: 85,
|
||||||
|
V: 86,
|
||||||
|
W: 87,
|
||||||
|
X: 88,
|
||||||
|
Y: 89,
|
||||||
|
Z: 90,
|
||||||
|
|
||||||
|
Left: 37,
|
||||||
|
Up: 38,
|
||||||
|
Right: 39,
|
||||||
|
Down: 40,
|
||||||
|
};
|
||||||
|
|
||||||
|
const keyCodes = new Set(Object.values(KEY));
|
||||||
|
const keyState = {};
|
||||||
|
for (const code of Object.values(KEY)) {
|
||||||
|
keyState[code] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleKeydown(e)
|
||||||
|
{
|
||||||
|
//console.log(e.keyCode);
|
||||||
|
if (keyCodes.has(e.keyCode)) {
|
||||||
|
keyState[e.keyCode] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleKeyup(e)
|
||||||
|
{
|
||||||
|
if (keyCodes.has(e.keyCode)) {
|
||||||
|
keyState[e.keyCode] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('keydown', handleKeydown, false);
|
||||||
|
window.addEventListener('keyup', handleKeyup, false);
|
||||||
|
|
||||||
|
function updateView()
|
||||||
|
{
|
||||||
|
const lu = keyState[KEY.W] === true;
|
||||||
|
const ll = keyState[KEY.A] === true;
|
||||||
|
const ld = keyState[KEY.S] === true;
|
||||||
|
const lr = keyState[KEY.D] === true;
|
||||||
|
|
||||||
|
const lal = keyState[KEY.Q] === true;
|
||||||
|
const lar = keyState[KEY.E] === true;
|
||||||
|
|
||||||
|
const ru = keyState[KEY.Up] === true;
|
||||||
|
const rl = keyState[KEY.Left] === true;
|
||||||
|
const rd = keyState[KEY.Down] === true;
|
||||||
|
const rr = keyState[KEY.Right] === true;
|
||||||
|
|
||||||
|
module.instance.exports.camera_move(cameraStateAddress,
|
||||||
|
lu, ll, ld, lr,
|
||||||
|
lal, lar,
|
||||||
|
ru, rl, rd, rr);
|
||||||
|
|
||||||
|
const aspect = canvas.width / canvas.height;
|
||||||
|
|
||||||
|
module.instance.exports.camera_view_projection(cameraStateAddress,
|
||||||
|
viewStateAddress,
|
||||||
|
aspect);
|
||||||
|
|
||||||
|
device.queue.writeBuffer(viewUniformBuffer, 0,
|
||||||
|
memory2.buffer, viewStateAddress,
|
||||||
|
viewUniformBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
function render2()
|
function render2()
|
||||||
{
|
{
|
||||||
recreateDepth();
|
recreateDepth();
|
||||||
const colorView = context.getCurrentTexture().createView();
|
const colorView = context.getCurrentTexture().createView();
|
||||||
|
|
||||||
const aspect = canvas.width / canvas.height;
|
updateView();
|
||||||
rotate.instance.exports.rotate(tick * 0.01, aspect, 0);
|
|
||||||
device.queue.writeBuffer(gltfRenderer.uniformBuffer, 0, uniformArray, 0, gltfRenderer.uniformBufferSize / 4);
|
{
|
||||||
|
const encoder = device.createCommandEncoder();
|
||||||
|
const renderPass = encoder.beginRenderPass({
|
||||||
|
colorAttachments: [{
|
||||||
|
view: colorView,
|
||||||
|
loadOp: "clear",
|
||||||
|
clearValue: { r: 0.2, g: 0.2, b: 0.4, a: 1 },
|
||||||
|
storeOp: "store",
|
||||||
|
}],
|
||||||
|
depthStencilAttachment: {
|
||||||
|
view: depthTexture.createView(),
|
||||||
|
depthClearValue: 1.0,
|
||||||
|
depthLoadOp: 'clear',
|
||||||
|
depthStoreOp: 'store',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
gltfRenderer.render(renderPass);
|
||||||
|
lightRenderer.render(renderPass);
|
||||||
|
|
||||||
|
renderPass.end();
|
||||||
|
|
||||||
|
const commandBuffer = encoder.finish();
|
||||||
|
device.queue.submit([commandBuffer]);
|
||||||
|
}
|
||||||
|
|
||||||
gltfRenderer.render(device, colorView, depthTexture);
|
|
||||||
requestAnimationFrame(render2);
|
requestAnimationFrame(render2);
|
||||||
}
|
}
|
||||||
requestAnimationFrame(render2);
|
requestAnimationFrame(render2);
|
||||||
|
|||||||
51
index2.js
51
index2.js
@ -1,7 +1,6 @@
|
|||||||
import { getPath } from "./common.js";
|
import { getPath } from "./common.js";
|
||||||
import { parseGltfChunks, vertexBufferLayouts, primitiveAccessors, splitGltf } from "./gltf.js";
|
import { parseGltfChunks, vertexBufferLayouts, primitiveAccessors, splitGltf } from "./gltf.js";
|
||||||
|
|
||||||
|
|
||||||
function loadGltfNode(module, handle, gltf, nodeIndex)
|
function loadGltfNode(module, handle, gltf, nodeIndex)
|
||||||
{
|
{
|
||||||
const node = gltf.json.nodes[nodeIndex];
|
const node = gltf.json.nodes[nodeIndex];
|
||||||
@ -37,7 +36,7 @@ function printMatrix(m, o)
|
|||||||
}
|
}
|
||||||
|
|
||||||
class GltfRenderer {
|
class GltfRenderer {
|
||||||
constructor(device, canvasFormat, shaderModule, gltf, texture)
|
constructor(device, canvasFormat, viewUniformBuffer, shaderModule, gltf, texture)
|
||||||
{
|
{
|
||||||
this.gltf = gltf;
|
this.gltf = gltf;
|
||||||
|
|
||||||
@ -153,13 +152,6 @@ class GltfRenderer {
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const matrixSize = 4 * 4 * 4;
|
const matrixSize = 4 * 4 * 4;
|
||||||
this.uniformBufferSize = matrixSize * 2;
|
|
||||||
this.uniformBuffer = device.createBuffer({
|
|
||||||
label: "gltf uniform 0",
|
|
||||||
size: this.uniformBufferSize,
|
|
||||||
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.nodeBufferSize = matrixSize * this.gltf.json.nodes.length;
|
this.nodeBufferSize = matrixSize * this.gltf.json.nodes.length;
|
||||||
this.nodeBuffer = device.createBuffer({
|
this.nodeBuffer = device.createBuffer({
|
||||||
label: "gltf node buffer",
|
label: "gltf node buffer",
|
||||||
@ -173,7 +165,7 @@ class GltfRenderer {
|
|||||||
layout: bindGroupLayouts[0],
|
layout: bindGroupLayouts[0],
|
||||||
entries: [{
|
entries: [{
|
||||||
binding: 0,
|
binding: 0,
|
||||||
resource: { buffer: this.uniformBuffer },
|
resource: { buffer: viewUniformBuffer },
|
||||||
}, {
|
}, {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
resource: { buffer: this.nodeBuffer },
|
resource: { buffer: this.nodeBuffer },
|
||||||
@ -235,33 +227,12 @@ class GltfRenderer {
|
|||||||
return lastKey;
|
return lastKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
render(device, colorView, depthTexture)
|
render(renderPass)
|
||||||
{
|
{
|
||||||
const encoder = device.createCommandEncoder();
|
|
||||||
const renderPass = encoder.beginRenderPass({
|
|
||||||
colorAttachments: [{
|
|
||||||
view: colorView,
|
|
||||||
loadOp: "clear",
|
|
||||||
clearValue: { r: 0.2, g: 0.2, b: 0.4, a: 1 },
|
|
||||||
storeOp: "store",
|
|
||||||
}],
|
|
||||||
depthStencilAttachment: {
|
|
||||||
view: depthTexture.createView(),
|
|
||||||
depthClearValue: 1.0,
|
|
||||||
depthLoadOp: 'clear',
|
|
||||||
depthStoreOp: 'store',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
var lastKey = undefined;
|
var lastKey = undefined;
|
||||||
for (let nodeIndex of this.gltf.json.scenes[0].nodes) {
|
for (let nodeIndex of this.gltf.json.scenes[0].nodes) {
|
||||||
lastKey = this.renderNode(renderPass, lastKey, nodeIndex);
|
lastKey = this.renderNode(renderPass, lastKey, nodeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPass.end();
|
|
||||||
|
|
||||||
const commandBuffer = encoder.finish();
|
|
||||||
device.queue.submit([commandBuffer]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,8 +304,14 @@ async function loadTextures(device, memory, module, gltf)
|
|||||||
return textures;
|
return textures;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadGltf(device, canvasFormat, memory, module)
|
async function loadGltf(device, canvasFormat, viewUniformBuffer, memory, module)
|
||||||
{
|
{
|
||||||
|
const code = await getPath("gltf.wgsl");
|
||||||
|
const shaderModule = device.createShaderModule({
|
||||||
|
label: "gltf module",
|
||||||
|
code: await code,
|
||||||
|
});
|
||||||
|
|
||||||
const gltf = await splitGltf("gltf/lamp.gltf", "gltf/lamp.bin");
|
const gltf = await splitGltf("gltf/lamp.gltf", "gltf/lamp.bin");
|
||||||
const nodesHandle = loadGltfNodes(module, gltf);
|
const nodesHandle = loadGltfNodes(module, gltf);
|
||||||
|
|
||||||
@ -348,13 +325,7 @@ async function loadGltf(device, canvasFormat, memory, module)
|
|||||||
|
|
||||||
const textures = await loadTextures(device, memory, module, gltf);
|
const textures = await loadTextures(device, memory, module, gltf);
|
||||||
|
|
||||||
const code = await getPath("gltf.wgsl");
|
const renderer = new GltfRenderer(device, canvasFormat, viewUniformBuffer, shaderModule, gltf, textures[2]);
|
||||||
const shaderModule = device.createShaderModule({
|
|
||||||
label: "gltf module",
|
|
||||||
code: await code,
|
|
||||||
});
|
|
||||||
|
|
||||||
const renderer = new GltfRenderer(device, canvasFormat, shaderModule, gltf, textures[0]);
|
|
||||||
console.log(renderer.nodeBuffer);
|
console.log(renderer.nodeBuffer);
|
||||||
device.queue.writeBuffer(renderer.nodeBuffer, 0,
|
device.queue.writeBuffer(renderer.nodeBuffer, 0,
|
||||||
memory.buffer, nodesHandle, (4 * 4 * 4) * gltf.json.nodes.length);
|
memory.buffer, nodesHandle, (4 * 4 * 4) * gltf.json.nodes.length);
|
||||||
|
|||||||
160
light.js
Normal file
160
light.js
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
import { getPath } from "./common.js";
|
||||||
|
|
||||||
|
function parseHeader(buffer)
|
||||||
|
{
|
||||||
|
const array = new Uint32Array(buffer);
|
||||||
|
/*
|
||||||
|
console.log("index count", icosphereU32[0]);
|
||||||
|
console.log("index buffer offset", icosphereU32[1]);
|
||||||
|
console.log("index buffer size", icosphereU32[2]);
|
||||||
|
console.log("vertex buffer offset", icosphereU32[3]);
|
||||||
|
console.log("vertex buffer size", icosphereU32[4]);
|
||||||
|
*/
|
||||||
|
|
||||||
|
return {
|
||||||
|
indexCount: array[0],
|
||||||
|
indexOffset: array[1],
|
||||||
|
indexSize: array[2],
|
||||||
|
vertexOffset: array[3],
|
||||||
|
vertexSize: array[4],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class LightRenderer {
|
||||||
|
constructor(device, canvasFormat, viewUniformBuffer,
|
||||||
|
shaderModule, binBuffer, label)
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// buffer
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const header = parseHeader(binBuffer);
|
||||||
|
this.header = header;
|
||||||
|
|
||||||
|
this.buffer = device.createBuffer({
|
||||||
|
label: `${label} renderer buffer`,
|
||||||
|
size: header.indexSize + header.vertexSize,
|
||||||
|
usage: GPUBufferUsage.INDEX | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
|
||||||
|
});
|
||||||
|
this.indexOffset = 0;
|
||||||
|
this.vertexOffset = header.indexSize;
|
||||||
|
|
||||||
|
device.queue.writeBuffer(this.buffer, this.indexOffset,
|
||||||
|
binBuffer, header.indexOffset, header.indexSize);
|
||||||
|
device.queue.writeBuffer(this.buffer, this.vertexOffset,
|
||||||
|
binBuffer, header.vertexOffset, header.vertexSize);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// pipeline
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const bindGroupLayouts = [
|
||||||
|
device.createBindGroupLayout({
|
||||||
|
label: `${label} view matrix bind group layout`,
|
||||||
|
entries: [{
|
||||||
|
binding: 0,
|
||||||
|
visibility: GPUShaderStage.VERTEX,
|
||||||
|
buffer: { type: "uniform" }
|
||||||
|
},/* {
|
||||||
|
binding: 1,
|
||||||
|
visibility: GPUShaderStage.VERTEX,
|
||||||
|
buffer: { type: "read-only-storage" }
|
||||||
|
}*/]
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
const pipelineLayout = device.createPipelineLayout({
|
||||||
|
label: `${label} pipeline layout`,
|
||||||
|
bindGroupLayouts: bindGroupLayouts,
|
||||||
|
});
|
||||||
|
|
||||||
|
const vertexBufferLayouts = [{
|
||||||
|
arrayStride: 36,
|
||||||
|
attributes: [{
|
||||||
|
format: "float32x3",
|
||||||
|
offset: 0,
|
||||||
|
shaderLocation: 0,
|
||||||
|
}, {
|
||||||
|
format: "float32x2",
|
||||||
|
offset: 12,
|
||||||
|
shaderLocation: 1,
|
||||||
|
}, {
|
||||||
|
format: "float16x4",
|
||||||
|
offset: 20,
|
||||||
|
shaderLocation: 2,
|
||||||
|
}, {
|
||||||
|
format: "float16x4",
|
||||||
|
offset: 28,
|
||||||
|
shaderLocation: 3,
|
||||||
|
}],
|
||||||
|
stepMode: "vertex",
|
||||||
|
}];
|
||||||
|
|
||||||
|
this.renderPipeline = device.createRenderPipeline({
|
||||||
|
label: `${label} pipeline`,
|
||||||
|
layout: pipelineLayout,
|
||||||
|
vertex: {
|
||||||
|
module: shaderModule,
|
||||||
|
entryPoint: "vertexMain",
|
||||||
|
buffers: vertexBufferLayouts,
|
||||||
|
},
|
||||||
|
fragment: {
|
||||||
|
module: shaderModule,
|
||||||
|
entryPoint: "fragmentMain",
|
||||||
|
targets: [{
|
||||||
|
format: canvasFormat,
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
primitive: {
|
||||||
|
topology: "triangle-list",
|
||||||
|
},
|
||||||
|
depthStencil: {
|
||||||
|
depthWriteEnabled: true,
|
||||||
|
depthCompare: "less",
|
||||||
|
format: "depth24plus",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// bind group
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
this.bindGroups = [
|
||||||
|
device.createBindGroup({
|
||||||
|
label: `${label} bind group`,
|
||||||
|
layout: bindGroupLayouts[0],
|
||||||
|
entries: [{
|
||||||
|
binding: 0,
|
||||||
|
resource: { buffer: viewUniformBuffer },
|
||||||
|
}],
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
render(renderPass)
|
||||||
|
{
|
||||||
|
renderPass.setPipeline(this.renderPipeline);
|
||||||
|
renderPass.setVertexBuffer(0, this.buffer, this.vertexOffset, this.header.vertexSize);
|
||||||
|
renderPass.setIndexBuffer(this.buffer, "uint16", this.indexOffset, this.header.indexSize);
|
||||||
|
renderPass.setBindGroup(0, this.bindGroups[0]);
|
||||||
|
renderPass.drawIndexed(this.header.indexCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadLight(device, canvasFormat, viewUniformBuffer)
|
||||||
|
{
|
||||||
|
const lightWgsl = getPath("light.wgsl");
|
||||||
|
const shaderModule = device.createShaderModule({
|
||||||
|
label: "light shader",
|
||||||
|
code: await lightWgsl,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await fetch("obj/icosphere.bin");
|
||||||
|
const binBuffer = await response.arrayBuffer();
|
||||||
|
|
||||||
|
const renderer = new LightRenderer(device, canvasFormat, viewUniformBuffer,
|
||||||
|
shaderModule, binBuffer, "light");
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { loadLight };
|
||||||
35
light.wgsl
Normal file
35
light.wgsl
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
struct Configuration {
|
||||||
|
matrix: mat4x4f,
|
||||||
|
matrixWorld: mat4x4f,
|
||||||
|
};
|
||||||
|
|
||||||
|
@group(0) @binding(0) var<uniform> config: Configuration;
|
||||||
|
|
||||||
|
struct VertexInput {
|
||||||
|
@location(0) position: vec3f,
|
||||||
|
@location(1) texture: vec2f,
|
||||||
|
@location(2) normal: vec4f,
|
||||||
|
@location(3) tangent: vec4f,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexOutput {
|
||||||
|
@builtin(position) position: vec4f,
|
||||||
|
@location(0) texture: vec2f,
|
||||||
|
};
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn vertexMain(input: VertexInput) -> VertexOutput
|
||||||
|
{
|
||||||
|
let position = vec4f(input.position, 1);
|
||||||
|
|
||||||
|
var output: VertexOutput;
|
||||||
|
output.position = config.matrix * position;
|
||||||
|
output.texture = input.texture;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
@fragment
|
||||||
|
fn fragmentMain(input: VertexOutput) -> @location(0) vec4f
|
||||||
|
{
|
||||||
|
return vec4(1, 0, 0, 1.0);
|
||||||
|
}
|
||||||
BIN
obj/icosphere.bin
Normal file
BIN
obj/icosphere.bin
Normal file
Binary file not shown.
269
obj/icosphere.obj
Normal file
269
obj/icosphere.obj
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
# Blender 5.2.0 LTS
|
||||||
|
# www.blender.org
|
||||||
|
o Icosphere
|
||||||
|
v 0.000000 -1.000000 0.000000
|
||||||
|
v 0.723607 -0.447220 0.525725
|
||||||
|
v -0.276388 -0.447220 0.850649
|
||||||
|
v -0.894426 -0.447216 0.000000
|
||||||
|
v -0.276388 -0.447220 -0.850649
|
||||||
|
v 0.723607 -0.447220 -0.525725
|
||||||
|
v 0.276388 0.447220 0.850649
|
||||||
|
v -0.723607 0.447220 0.525725
|
||||||
|
v -0.723607 0.447220 -0.525725
|
||||||
|
v 0.276388 0.447220 -0.850649
|
||||||
|
v 0.894426 0.447216 0.000000
|
||||||
|
v 0.000000 1.000000 0.000000
|
||||||
|
v -0.162456 -0.850654 0.499995
|
||||||
|
v 0.425323 -0.850654 0.309011
|
||||||
|
v 0.262869 -0.525738 0.809012
|
||||||
|
v 0.850648 -0.525736 0.000000
|
||||||
|
v 0.425323 -0.850654 -0.309011
|
||||||
|
v -0.525730 -0.850652 0.000000
|
||||||
|
v -0.688189 -0.525736 0.499997
|
||||||
|
v -0.162456 -0.850654 -0.499995
|
||||||
|
v -0.688189 -0.525736 -0.499997
|
||||||
|
v 0.262869 -0.525738 -0.809012
|
||||||
|
v 0.951058 0.000000 0.309013
|
||||||
|
v 0.951058 0.000000 -0.309013
|
||||||
|
v 0.000000 0.000000 1.000000
|
||||||
|
v 0.587786 0.000000 0.809017
|
||||||
|
v -0.951058 0.000000 0.309013
|
||||||
|
v -0.587786 0.000000 0.809017
|
||||||
|
v -0.587786 0.000000 -0.809017
|
||||||
|
v -0.951058 0.000000 -0.309013
|
||||||
|
v 0.587786 0.000000 -0.809017
|
||||||
|
v 0.000000 0.000000 -1.000000
|
||||||
|
v 0.688189 0.525736 0.499997
|
||||||
|
v -0.262869 0.525738 0.809012
|
||||||
|
v -0.850648 0.525736 0.000000
|
||||||
|
v -0.262869 0.525738 -0.809012
|
||||||
|
v 0.688189 0.525736 -0.499997
|
||||||
|
v 0.162456 0.850654 0.499995
|
||||||
|
v 0.525730 0.850652 0.000000
|
||||||
|
v -0.425323 0.850654 0.309011
|
||||||
|
v -0.425323 0.850654 -0.309011
|
||||||
|
v 0.162456 0.850654 -0.499995
|
||||||
|
vn 0.1024 -0.9435 0.3151
|
||||||
|
vn 0.7002 -0.6617 0.2680
|
||||||
|
vn -0.2680 -0.9435 0.1947
|
||||||
|
vn -0.2680 -0.9435 -0.1947
|
||||||
|
vn 0.1024 -0.9435 -0.3151
|
||||||
|
vn 0.9050 -0.3304 0.2680
|
||||||
|
vn 0.0247 -0.3304 0.9435
|
||||||
|
vn -0.8897 -0.3304 0.3151
|
||||||
|
vn -0.5746 -0.3304 -0.7488
|
||||||
|
vn 0.5346 -0.3304 -0.7779
|
||||||
|
vn 0.8026 -0.1256 0.5831
|
||||||
|
vn -0.3066 -0.1256 0.9435
|
||||||
|
vn -0.9921 -0.1256 -0.0000
|
||||||
|
vn -0.3066 -0.1256 -0.9435
|
||||||
|
vn 0.8026 -0.1256 -0.5831
|
||||||
|
vn 0.4089 0.6617 0.6284
|
||||||
|
vn -0.4713 0.6617 0.5831
|
||||||
|
vn -0.7002 0.6617 -0.2680
|
||||||
|
vn 0.0385 0.6617 -0.7488
|
||||||
|
vn 0.7240 0.6617 -0.1947
|
||||||
|
vn 0.2680 0.9435 -0.1947
|
||||||
|
vn 0.4911 0.7947 -0.3568
|
||||||
|
vn 0.4089 0.6617 -0.6284
|
||||||
|
vn -0.1024 0.9435 -0.3151
|
||||||
|
vn -0.1876 0.7947 -0.5773
|
||||||
|
vn -0.4713 0.6617 -0.5831
|
||||||
|
vn -0.3313 0.9435 -0.0000
|
||||||
|
vn -0.6071 0.7947 -0.0000
|
||||||
|
vn -0.7002 0.6617 0.2680
|
||||||
|
vn -0.1024 0.9435 0.3151
|
||||||
|
vn -0.1876 0.7947 0.5773
|
||||||
|
vn 0.0385 0.6617 0.7488
|
||||||
|
vn 0.2680 0.9435 0.1947
|
||||||
|
vn 0.4911 0.7947 0.3568
|
||||||
|
vn 0.7240 0.6617 0.1947
|
||||||
|
vn 0.8897 0.3304 -0.3151
|
||||||
|
vn 0.7947 0.1876 -0.5773
|
||||||
|
vn 0.5746 0.3304 -0.7488
|
||||||
|
vn -0.0247 0.3304 -0.9435
|
||||||
|
vn -0.3035 0.1876 -0.9342
|
||||||
|
vn -0.5346 0.3304 -0.7779
|
||||||
|
vn -0.9050 0.3304 -0.2680
|
||||||
|
vn -0.9822 0.1876 -0.0000
|
||||||
|
vn -0.9050 0.3304 0.2680
|
||||||
|
vn -0.5346 0.3304 0.7779
|
||||||
|
vn -0.3035 0.1876 0.9342
|
||||||
|
vn -0.0247 0.3304 0.9435
|
||||||
|
vn 0.5746 0.3304 0.7488
|
||||||
|
vn 0.7947 0.1876 0.5773
|
||||||
|
vn 0.8897 0.3304 0.3151
|
||||||
|
vn 0.3066 0.1256 -0.9435
|
||||||
|
vn 0.3035 -0.1876 -0.9342
|
||||||
|
vn 0.0247 -0.3304 -0.9435
|
||||||
|
vn -0.8026 0.1256 -0.5831
|
||||||
|
vn -0.7947 -0.1876 -0.5773
|
||||||
|
vn -0.8897 -0.3304 -0.3151
|
||||||
|
vn -0.8026 0.1256 0.5831
|
||||||
|
vn -0.7947 -0.1876 0.5773
|
||||||
|
vn -0.5746 -0.3304 0.7488
|
||||||
|
vn 0.3066 0.1256 0.9435
|
||||||
|
vn 0.3035 -0.1876 0.9342
|
||||||
|
vn 0.5346 -0.3304 0.7779
|
||||||
|
vn 0.9921 0.1256 -0.0000
|
||||||
|
vn 0.9822 -0.1876 -0.0000
|
||||||
|
vn 0.9050 -0.3304 -0.2680
|
||||||
|
vn 0.4713 -0.6617 -0.5831
|
||||||
|
vn 0.1876 -0.7947 -0.5773
|
||||||
|
vn -0.0385 -0.6617 -0.7488
|
||||||
|
vn -0.4089 -0.6617 -0.6284
|
||||||
|
vn -0.4911 -0.7947 -0.3568
|
||||||
|
vn -0.7240 -0.6617 -0.1947
|
||||||
|
vn -0.7240 -0.6617 0.1947
|
||||||
|
vn -0.4911 -0.7947 0.3568
|
||||||
|
vn -0.4089 -0.6617 0.6284
|
||||||
|
vn 0.7002 -0.6617 -0.2680
|
||||||
|
vn 0.6071 -0.7947 -0.0000
|
||||||
|
vn 0.3313 -0.9435 -0.0000
|
||||||
|
vn -0.0385 -0.6617 0.7488
|
||||||
|
vn 0.1876 -0.7947 0.5773
|
||||||
|
vn 0.4713 -0.6617 0.5831
|
||||||
|
vt 0.181819 0.000000
|
||||||
|
vt 0.227273 0.078731
|
||||||
|
vt 0.136365 0.078731
|
||||||
|
vt 0.272728 0.157461
|
||||||
|
vt 0.318182 0.078731
|
||||||
|
vt 0.363637 0.157461
|
||||||
|
vt 0.909091 0.000000
|
||||||
|
vt 0.954545 0.078731
|
||||||
|
vt 0.863636 0.078731
|
||||||
|
vt 0.727273 0.000000
|
||||||
|
vt 0.772727 0.078731
|
||||||
|
vt 0.681818 0.078731
|
||||||
|
vt 0.545455 0.000000
|
||||||
|
vt 0.590909 0.078731
|
||||||
|
vt 0.500000 0.078731
|
||||||
|
vt 0.318182 0.236191
|
||||||
|
vt 0.090910 0.157461
|
||||||
|
vt 0.181819 0.157461
|
||||||
|
vt 0.136365 0.236191
|
||||||
|
vt 0.818182 0.157461
|
||||||
|
vt 0.909091 0.157461
|
||||||
|
vt 0.863636 0.236191
|
||||||
|
vt 0.636364 0.157461
|
||||||
|
vt 0.727273 0.157461
|
||||||
|
vt 0.681818 0.236191
|
||||||
|
vt 0.454546 0.157461
|
||||||
|
vt 0.545455 0.157461
|
||||||
|
vt 0.500000 0.236191
|
||||||
|
vt 0.227273 0.236191
|
||||||
|
vt 0.045455 0.236191
|
||||||
|
vt 0.772727 0.236191
|
||||||
|
vt 0.590909 0.236191
|
||||||
|
vt 0.409092 0.236191
|
||||||
|
vt 0.181819 0.314921
|
||||||
|
vt 0.272728 0.314921
|
||||||
|
vt 0.227273 0.393651
|
||||||
|
vt 0.000000 0.314921
|
||||||
|
vt 0.090910 0.314921
|
||||||
|
vt 0.045455 0.393651
|
||||||
|
vt 0.727273 0.314921
|
||||||
|
vt 0.818182 0.314921
|
||||||
|
vt 0.772727 0.393651
|
||||||
|
vt 0.545455 0.314921
|
||||||
|
vt 0.636364 0.314921
|
||||||
|
vt 0.590909 0.393651
|
||||||
|
vt 0.363637 0.314921
|
||||||
|
vt 0.454546 0.314921
|
||||||
|
vt 0.409092 0.393651
|
||||||
|
vt 0.500000 0.393651
|
||||||
|
vt 0.454546 0.472382
|
||||||
|
vt 0.681818 0.393651
|
||||||
|
vt 0.636364 0.472382
|
||||||
|
vt 0.863636 0.393651
|
||||||
|
vt 0.818182 0.472382
|
||||||
|
vt 0.909091 0.314921
|
||||||
|
vt 0.136365 0.393651
|
||||||
|
vt 0.090910 0.472382
|
||||||
|
vt 0.318182 0.393651
|
||||||
|
vt 0.272728 0.472382
|
||||||
|
vt 0.954545 0.236191
|
||||||
|
vt 1.000000 0.157461
|
||||||
|
vt 0.409092 0.078731
|
||||||
|
vt 0.363637 0.000000
|
||||||
|
s 0
|
||||||
|
f 1/1/1 14/2/1 13/3/1
|
||||||
|
f 2/4/2 14/5/2 16/6/2
|
||||||
|
f 1/7/3 13/8/3 18/9/3
|
||||||
|
f 1/10/4 18/11/4 20/12/4
|
||||||
|
f 1/13/5 20/14/5 17/15/5
|
||||||
|
f 2/4/6 16/6/6 23/16/6
|
||||||
|
f 3/17/7 15/18/7 25/19/7
|
||||||
|
f 4/20/8 19/21/8 27/22/8
|
||||||
|
f 5/23/9 21/24/9 29/25/9
|
||||||
|
f 6/26/10 22/27/10 31/28/10
|
||||||
|
f 2/4/11 23/16/11 26/29/11
|
||||||
|
f 3/17/12 25/19/12 28/30/12
|
||||||
|
f 4/20/13 27/22/13 30/31/13
|
||||||
|
f 5/23/14 29/25/14 32/32/14
|
||||||
|
f 6/26/15 31/28/15 24/33/15
|
||||||
|
f 7/34/16 33/35/16 38/36/16
|
||||||
|
f 8/37/17 34/38/17 40/39/17
|
||||||
|
f 9/40/18 35/41/18 41/42/18
|
||||||
|
f 10/43/19 36/44/19 42/45/19
|
||||||
|
f 11/46/20 37/47/20 39/48/20
|
||||||
|
f 39/48/21 42/49/21 12/50/21
|
||||||
|
f 39/48/22 37/47/22 42/49/22
|
||||||
|
f 37/47/23 10/43/23 42/49/23
|
||||||
|
f 42/45/24 41/51/24 12/52/24
|
||||||
|
f 42/45/25 36/44/25 41/51/25
|
||||||
|
f 36/44/26 9/40/26 41/51/26
|
||||||
|
f 41/42/27 40/53/27 12/54/27
|
||||||
|
f 41/42/28 35/41/28 40/53/28
|
||||||
|
f 35/41/29 8/55/29 40/53/29
|
||||||
|
f 40/39/30 38/56/30 12/57/30
|
||||||
|
f 40/39/31 34/38/31 38/56/31
|
||||||
|
f 34/38/32 7/34/32 38/56/32
|
||||||
|
f 38/36/33 39/58/33 12/59/33
|
||||||
|
f 38/36/34 33/35/34 39/58/34
|
||||||
|
f 33/35/35 11/46/35 39/58/35
|
||||||
|
f 24/33/36 37/47/36 11/46/36
|
||||||
|
f 24/33/37 31/28/37 37/47/37
|
||||||
|
f 31/28/38 10/43/38 37/47/38
|
||||||
|
f 32/32/39 36/44/39 10/43/39
|
||||||
|
f 32/32/40 29/25/40 36/44/40
|
||||||
|
f 29/25/41 9/40/41 36/44/41
|
||||||
|
f 30/31/42 35/41/42 9/40/42
|
||||||
|
f 30/31/43 27/22/43 35/41/43
|
||||||
|
f 27/22/44 8/55/44 35/41/44
|
||||||
|
f 28/30/45 34/38/45 8/37/45
|
||||||
|
f 28/30/46 25/19/46 34/38/46
|
||||||
|
f 25/19/47 7/34/47 34/38/47
|
||||||
|
f 26/29/48 33/35/48 7/34/48
|
||||||
|
f 26/29/49 23/16/49 33/35/49
|
||||||
|
f 23/16/50 11/46/50 33/35/50
|
||||||
|
f 31/28/51 32/32/51 10/43/51
|
||||||
|
f 31/28/52 22/27/52 32/32/52
|
||||||
|
f 22/27/53 5/23/53 32/32/53
|
||||||
|
f 29/25/54 30/31/54 9/40/54
|
||||||
|
f 29/25/55 21/24/55 30/31/55
|
||||||
|
f 21/24/56 4/20/56 30/31/56
|
||||||
|
f 27/22/57 28/60/57 8/55/57
|
||||||
|
f 27/22/58 19/21/58 28/60/58
|
||||||
|
f 19/21/59 3/61/59 28/60/59
|
||||||
|
f 25/19/60 26/29/60 7/34/60
|
||||||
|
f 25/19/61 15/18/61 26/29/61
|
||||||
|
f 15/18/62 2/4/62 26/29/62
|
||||||
|
f 23/16/63 24/33/63 11/46/63
|
||||||
|
f 23/16/64 16/6/64 24/33/64
|
||||||
|
f 16/6/65 6/26/65 24/33/65
|
||||||
|
f 17/15/66 22/27/66 6/26/66
|
||||||
|
f 17/15/67 20/14/67 22/27/67
|
||||||
|
f 20/14/68 5/23/68 22/27/68
|
||||||
|
f 20/12/69 21/24/69 5/23/69
|
||||||
|
f 20/12/70 18/11/70 21/24/70
|
||||||
|
f 18/11/71 4/20/71 21/24/71
|
||||||
|
f 18/9/72 19/21/72 4/20/72
|
||||||
|
f 18/9/73 13/8/73 19/21/73
|
||||||
|
f 13/8/74 3/61/74 19/21/74
|
||||||
|
f 16/6/75 17/62/75 6/26/75
|
||||||
|
f 16/6/76 14/5/76 17/62/76
|
||||||
|
f 14/5/77 1/63/77 17/62/77
|
||||||
|
f 13/3/78 15/18/78 3/17/78
|
||||||
|
f 13/3/79 14/2/79 15/18/79
|
||||||
|
f 14/2/80 2/4/80 15/18/80
|
||||||
@ -5,9 +5,9 @@ CFLAGS = \
|
|||||||
-g \
|
-g \
|
||||||
-O3 \
|
-O3 \
|
||||||
-flto \
|
-flto \
|
||||||
|
-ffast-math \
|
||||||
-nostdlib \
|
-nostdlib \
|
||||||
-I$(MINIZ) \
|
-I$(MINIZ) \
|
||||||
-I.. \
|
|
||||||
-I. \
|
-I. \
|
||||||
-Werror \
|
-Werror \
|
||||||
-Wfatal-errors \
|
-Wfatal-errors \
|
||||||
@ -29,6 +29,9 @@ LDFLAGS = \
|
|||||||
-Wl,--export=node_init_translation \
|
-Wl,--export=node_init_translation \
|
||||||
-Wl,--export=png_build_crc_table \
|
-Wl,--export=png_build_crc_table \
|
||||||
-Wl,--export=png_decode \
|
-Wl,--export=png_decode \
|
||||||
|
-Wl,--export=camera_move \
|
||||||
|
-Wl,--export=camera_init \
|
||||||
|
-Wl,--export=camera_view_projection \
|
||||||
-Wl,--import-undefined \
|
-Wl,--import-undefined \
|
||||||
-Wl,--print-map \
|
-Wl,--print-map \
|
||||||
-Wl,--import-memory \
|
-Wl,--import-memory \
|
||||||
@ -45,7 +48,8 @@ PNG_OBJ = \
|
|||||||
stdlib.o \
|
stdlib.o \
|
||||||
$(MINIZ)/miniz_tinfl.o \
|
$(MINIZ)/miniz_tinfl.o \
|
||||||
memory.o \
|
memory.o \
|
||||||
node.o
|
node.o \
|
||||||
|
camera.o
|
||||||
|
|
||||||
module.wasm: $(PNG_OBJ)
|
module.wasm: $(PNG_OBJ)
|
||||||
clang++ $(CFLAGS) $(LDFLAGS) -o $@ $^
|
clang++ $(CFLAGS) $(LDFLAGS) -o $@ $^
|
||||||
|
|||||||
138
src/camera.cpp
Normal file
138
src/camera.cpp
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
#include "directxmath/DirectXMath.h"
|
||||||
|
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
struct CameraState {
|
||||||
|
XMFLOAT3 eye;
|
||||||
|
XMFLOAT3 look;
|
||||||
|
XMFLOAT3 up;
|
||||||
|
float fov;
|
||||||
|
float pitch;
|
||||||
|
float yaw;
|
||||||
|
|
||||||
|
XMFLOAT3 light_position;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ViewState {
|
||||||
|
XMFLOAT4X4 viewProj;
|
||||||
|
XMFLOAT4X4 lightViewProj;
|
||||||
|
XMFLOAT4 lightPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline XMMATRIX camera_view(CameraState const * state)
|
||||||
|
{
|
||||||
|
XMMATRIX view = XMMatrixLookToRH(XMLoadFloat3(&state->eye),
|
||||||
|
XMLoadFloat3(&state->look),
|
||||||
|
XMLoadFloat3(&state->up));
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline XMMATRIX camera_projection(CameraState const * state, float aspect)
|
||||||
|
{
|
||||||
|
float near_z = 0.01;
|
||||||
|
float far_z = 1000.0;
|
||||||
|
|
||||||
|
XMMATRIX projection = XMMatrixPerspectiveFovRH(state->fov,
|
||||||
|
aspect,
|
||||||
|
near_z,
|
||||||
|
far_z);
|
||||||
|
return projection;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" void log(float x);
|
||||||
|
|
||||||
|
static inline float min(float a, float b)
|
||||||
|
{
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float max(float a, float b)
|
||||||
|
{
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void camera_move(CameraState * state,
|
||||||
|
int lu, int ll, int ld, int lr,
|
||||||
|
int lal, int lar,
|
||||||
|
int ru, int rl, int rd, int rr)
|
||||||
|
{
|
||||||
|
const float linearSpeed = 0.1;
|
||||||
|
const float rotationalSpeed = 0.01;
|
||||||
|
XMFLOAT3 move = {0, 0, 0};
|
||||||
|
|
||||||
|
if (ll)
|
||||||
|
move.x -= 1.0;
|
||||||
|
if (lr)
|
||||||
|
move.x += 1.0;
|
||||||
|
if (lu)
|
||||||
|
move.z -= 1.0;
|
||||||
|
if (ld)
|
||||||
|
move.z += 1.0;
|
||||||
|
if (lal)
|
||||||
|
move.y += 1.0;
|
||||||
|
if (lar)
|
||||||
|
move.y -= 1.0;
|
||||||
|
//XMStoreFloat3(&move, XMVector3Normalize(XMLoadFloat3(&move)));
|
||||||
|
|
||||||
|
if (rl)
|
||||||
|
state->yaw += rotationalSpeed;
|
||||||
|
if (rr)
|
||||||
|
state->yaw -= rotationalSpeed;
|
||||||
|
if (ru)
|
||||||
|
state->pitch += rotationalSpeed;
|
||||||
|
if (rd)
|
||||||
|
state->pitch -= rotationalSpeed;
|
||||||
|
|
||||||
|
state->pitch = min(state->pitch, XM_PIDIV4);
|
||||||
|
state->pitch = max(state->pitch, -XM_PIDIV4);
|
||||||
|
|
||||||
|
float sinyaw;
|
||||||
|
float cosyaw;
|
||||||
|
XMScalarSinCos(&sinyaw, &cosyaw, state->yaw);
|
||||||
|
|
||||||
|
// eye
|
||||||
|
float x = move.x * -cosyaw - move.z * sinyaw;
|
||||||
|
float y = move.y;
|
||||||
|
float z = move.x * sinyaw - move.z * cosyaw;
|
||||||
|
state->eye.x += x * linearSpeed;
|
||||||
|
state->eye.y += y * linearSpeed;
|
||||||
|
state->eye.z += z * linearSpeed;
|
||||||
|
|
||||||
|
// look
|
||||||
|
float sinpitch;
|
||||||
|
float cospitch;
|
||||||
|
XMScalarSinCos(&sinpitch, &cospitch, state->pitch);
|
||||||
|
state->look.x = cospitch * sinyaw;
|
||||||
|
state->look.y = sinpitch;
|
||||||
|
state->look.z = cospitch * cosyaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
void camera_init(CameraState * camera_state)
|
||||||
|
{
|
||||||
|
camera_state->fov = XMConvertToRadians(45 * 1.5);
|
||||||
|
|
||||||
|
camera_state->yaw = XM_PI;
|
||||||
|
camera_state->pitch = 0.0f;
|
||||||
|
|
||||||
|
camera_state->up = {0, 1, 0};
|
||||||
|
camera_state->look = {0, 0, -1};
|
||||||
|
camera_state->eye = {0, 0, 5};
|
||||||
|
|
||||||
|
camera_state->light_position = {1, 1, 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
void camera_view_projection(CameraState const * camera_state,
|
||||||
|
ViewState * view_state,
|
||||||
|
float aspect)
|
||||||
|
{
|
||||||
|
XMMATRIX view = camera_view(camera_state);
|
||||||
|
XMMATRIX projection = camera_projection(camera_state, aspect);
|
||||||
|
|
||||||
|
XMMATRIX view_projection = view * projection;
|
||||||
|
|
||||||
|
XMMATRIX light_world = XMMatrixTranslationFromVector(XMLoadFloat3(&camera_state->light_position));
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&view_state->viewProj, view_projection);
|
||||||
|
XMStoreFloat4x4(&view_state->lightViewProj, light_world * view_projection);
|
||||||
|
XMStoreFloat4(&view_state->lightPosition, XMLoadFloat3(&camera_state->light_position));
|
||||||
|
}
|
||||||
13
src/camera.h
Normal file
13
src/camera.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
struct CameraState;
|
||||||
|
struct ViewState;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void camera_move(CameraState * camera_state,
|
||||||
|
int lu, int ll, int ld, int lr,
|
||||||
|
int lal, int lar,
|
||||||
|
int ru, int rl, int rd, int rr);
|
||||||
|
void camera_init(CameraState * camera_state);
|
||||||
|
void camera_view_projection(CameraState const * camera_state,
|
||||||
|
ViewState * view_state,
|
||||||
|
float aspect);
|
||||||
|
};
|
||||||
369
src/directxmath/DirectXCollision.h
Normal file
369
src/directxmath/DirectXCollision.h
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// DirectXCollision.h -- C++ Collision Math library
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
//
|
||||||
|
// https://go.microsoft.com/fwlink/?LinkID=615560
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DirectXMath.h"
|
||||||
|
|
||||||
|
namespace DirectX
|
||||||
|
{
|
||||||
|
|
||||||
|
enum ContainmentType
|
||||||
|
{
|
||||||
|
DISJOINT = 0,
|
||||||
|
INTERSECTS = 1,
|
||||||
|
CONTAINS = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PlaneIntersectionType
|
||||||
|
{
|
||||||
|
FRONT = 0,
|
||||||
|
INTERSECTING = 1,
|
||||||
|
BACK = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoundingBox;
|
||||||
|
struct BoundingOrientedBox;
|
||||||
|
struct BoundingFrustum;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4324 4820)
|
||||||
|
// C4324: alignment padding warnings
|
||||||
|
// C4820: Off by default noise
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Bounding sphere
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
struct BoundingSphere
|
||||||
|
{
|
||||||
|
XMFLOAT3 Center; // Center of the sphere.
|
||||||
|
float Radius; // Radius of the sphere.
|
||||||
|
|
||||||
|
// Creators
|
||||||
|
BoundingSphere() noexcept : Center(0, 0, 0), Radius(1.f) {}
|
||||||
|
|
||||||
|
BoundingSphere(const BoundingSphere&) = default;
|
||||||
|
BoundingSphere& operator=(const BoundingSphere&) = default;
|
||||||
|
|
||||||
|
BoundingSphere(BoundingSphere&&) = default;
|
||||||
|
BoundingSphere& operator=(BoundingSphere&&) = default;
|
||||||
|
|
||||||
|
constexpr BoundingSphere(_In_ const XMFLOAT3& center, _In_ float radius) noexcept
|
||||||
|
: Center(center), Radius(radius) {}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
void XM_CALLCONV Transform(_Out_ BoundingSphere& Out, _In_ FXMMATRIX M) const noexcept;
|
||||||
|
void XM_CALLCONV Transform(_Out_ BoundingSphere& Out, _In_ float Scale, _In_ FXMVECTOR Rotation, _In_ FXMVECTOR Translation) const noexcept;
|
||||||
|
// Transform the sphere
|
||||||
|
|
||||||
|
ContainmentType XM_CALLCONV Contains(_In_ FXMVECTOR Point) const noexcept;
|
||||||
|
ContainmentType XM_CALLCONV Contains(_In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingSphere& sh) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingBox& box) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingOrientedBox& box) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingFrustum& fr) const noexcept;
|
||||||
|
|
||||||
|
bool Intersects(_In_ const BoundingSphere& sh) const noexcept;
|
||||||
|
bool Intersects(_In_ const BoundingBox& box) const noexcept;
|
||||||
|
bool Intersects(_In_ const BoundingOrientedBox& box) const noexcept;
|
||||||
|
bool Intersects(_In_ const BoundingFrustum& fr) const noexcept;
|
||||||
|
|
||||||
|
bool XM_CALLCONV Intersects(_In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2) const noexcept;
|
||||||
|
// Triangle-sphere test
|
||||||
|
|
||||||
|
PlaneIntersectionType XM_CALLCONV Intersects(_In_ FXMVECTOR Plane) const noexcept;
|
||||||
|
// Plane-sphere test
|
||||||
|
|
||||||
|
bool XM_CALLCONV Intersects(_In_ FXMVECTOR Origin, _In_ FXMVECTOR Direction, _Out_ float& Dist) const noexcept;
|
||||||
|
// Ray-sphere test
|
||||||
|
|
||||||
|
ContainmentType XM_CALLCONV ContainedBy(_In_ FXMVECTOR Plane0, _In_ FXMVECTOR Plane1, _In_ FXMVECTOR Plane2,
|
||||||
|
_In_ GXMVECTOR Plane3, _In_ HXMVECTOR Plane4, _In_ HXMVECTOR Plane5) const noexcept;
|
||||||
|
// Test sphere against six planes (see BoundingFrustum::GetPlanes)
|
||||||
|
|
||||||
|
// Static methods
|
||||||
|
static void CreateMerged(_Out_ BoundingSphere& Out, _In_ const BoundingSphere& S1, _In_ const BoundingSphere& S2) noexcept;
|
||||||
|
|
||||||
|
static void CreateFromBoundingBox(_Out_ BoundingSphere& Out, _In_ const BoundingBox& box) noexcept;
|
||||||
|
static void CreateFromBoundingBox(_Out_ BoundingSphere& Out, _In_ const BoundingOrientedBox& box) noexcept;
|
||||||
|
|
||||||
|
static void CreateFromPoints(_Out_ BoundingSphere& Out, _In_ size_t Count,
|
||||||
|
_In_reads_bytes_(sizeof(XMFLOAT3) + Stride * (Count - 1)) const XMFLOAT3* pPoints, _In_ size_t Stride) noexcept;
|
||||||
|
|
||||||
|
static void CreateFromFrustum(_Out_ BoundingSphere& Out, _In_ const BoundingFrustum& fr) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Axis-aligned bounding box
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
struct BoundingBox
|
||||||
|
{
|
||||||
|
static constexpr size_t CORNER_COUNT = 8;
|
||||||
|
|
||||||
|
XMFLOAT3 Center; // Center of the box.
|
||||||
|
XMFLOAT3 Extents; // Distance from the center to each side.
|
||||||
|
|
||||||
|
// Creators
|
||||||
|
BoundingBox() noexcept : Center(0, 0, 0), Extents(1.f, 1.f, 1.f) {}
|
||||||
|
|
||||||
|
BoundingBox(const BoundingBox&) = default;
|
||||||
|
BoundingBox& operator=(const BoundingBox&) = default;
|
||||||
|
|
||||||
|
BoundingBox(BoundingBox&&) = default;
|
||||||
|
BoundingBox& operator=(BoundingBox&&) = default;
|
||||||
|
|
||||||
|
constexpr BoundingBox(_In_ const XMFLOAT3& center, _In_ const XMFLOAT3& extents) noexcept
|
||||||
|
: Center(center), Extents(extents) {}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
void XM_CALLCONV Transform(_Out_ BoundingBox& Out, _In_ FXMMATRIX M) const noexcept;
|
||||||
|
void XM_CALLCONV Transform(_Out_ BoundingBox& Out, _In_ float Scale, _In_ FXMVECTOR Rotation, _In_ FXMVECTOR Translation) const noexcept;
|
||||||
|
|
||||||
|
void GetCorners(_Out_writes_(8) XMFLOAT3* Corners) const noexcept;
|
||||||
|
// Gets the 8 corners of the box
|
||||||
|
|
||||||
|
ContainmentType XM_CALLCONV Contains(_In_ FXMVECTOR Point) const noexcept;
|
||||||
|
ContainmentType XM_CALLCONV Contains(_In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingSphere& sh) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingBox& box) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingOrientedBox& box) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingFrustum& fr) const noexcept;
|
||||||
|
|
||||||
|
bool Intersects(_In_ const BoundingSphere& sh) const noexcept;
|
||||||
|
bool Intersects(_In_ const BoundingBox& box) const noexcept;
|
||||||
|
bool Intersects(_In_ const BoundingOrientedBox& box) const noexcept;
|
||||||
|
bool Intersects(_In_ const BoundingFrustum& fr) const noexcept;
|
||||||
|
|
||||||
|
bool XM_CALLCONV Intersects(_In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2) const noexcept;
|
||||||
|
// Triangle-Box test
|
||||||
|
|
||||||
|
PlaneIntersectionType XM_CALLCONV Intersects(_In_ FXMVECTOR Plane) const noexcept;
|
||||||
|
// Plane-box test
|
||||||
|
|
||||||
|
bool XM_CALLCONV Intersects(_In_ FXMVECTOR Origin, _In_ FXMVECTOR Direction, _Out_ float& Dist) const noexcept;
|
||||||
|
// Ray-Box test
|
||||||
|
|
||||||
|
ContainmentType XM_CALLCONV ContainedBy(_In_ FXMVECTOR Plane0, _In_ FXMVECTOR Plane1, _In_ FXMVECTOR Plane2,
|
||||||
|
_In_ GXMVECTOR Plane3, _In_ HXMVECTOR Plane4, _In_ HXMVECTOR Plane5) const noexcept;
|
||||||
|
// Test box against six planes (see BoundingFrustum::GetPlanes)
|
||||||
|
|
||||||
|
// Static methods
|
||||||
|
static void CreateMerged(_Out_ BoundingBox& Out, _In_ const BoundingBox& b1, _In_ const BoundingBox& b2) noexcept;
|
||||||
|
|
||||||
|
static void CreateFromSphere(_Out_ BoundingBox& Out, _In_ const BoundingSphere& sh) noexcept;
|
||||||
|
|
||||||
|
static void XM_CALLCONV CreateFromPoints(_Out_ BoundingBox& Out, _In_ FXMVECTOR pt1, _In_ FXMVECTOR pt2) noexcept;
|
||||||
|
static void CreateFromPoints(_Out_ BoundingBox& Out, _In_ size_t Count,
|
||||||
|
_In_reads_bytes_(sizeof(XMFLOAT3) + Stride * (Count - 1)) const XMFLOAT3* pPoints, _In_ size_t Stride) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Oriented bounding box
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
struct BoundingOrientedBox
|
||||||
|
{
|
||||||
|
static constexpr size_t CORNER_COUNT = 8;
|
||||||
|
|
||||||
|
XMFLOAT3 Center; // Center of the box.
|
||||||
|
XMFLOAT3 Extents; // Distance from the center to each side.
|
||||||
|
XMFLOAT4 Orientation; // Unit quaternion representing rotation (box -> world).
|
||||||
|
|
||||||
|
// Creators
|
||||||
|
BoundingOrientedBox() noexcept : Center(0, 0, 0), Extents(1.f, 1.f, 1.f), Orientation(0, 0, 0, 1.f) {}
|
||||||
|
|
||||||
|
BoundingOrientedBox(const BoundingOrientedBox&) = default;
|
||||||
|
BoundingOrientedBox& operator=(const BoundingOrientedBox&) = default;
|
||||||
|
|
||||||
|
BoundingOrientedBox(BoundingOrientedBox&&) = default;
|
||||||
|
BoundingOrientedBox& operator=(BoundingOrientedBox&&) = default;
|
||||||
|
|
||||||
|
constexpr BoundingOrientedBox(_In_ const XMFLOAT3& center, _In_ const XMFLOAT3& extents, _In_ const XMFLOAT4& orientation) noexcept
|
||||||
|
: Center(center), Extents(extents), Orientation(orientation) {}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
void XM_CALLCONV Transform(_Out_ BoundingOrientedBox& Out, _In_ FXMMATRIX M) const noexcept;
|
||||||
|
void XM_CALLCONV Transform(_Out_ BoundingOrientedBox& Out, _In_ float Scale, _In_ FXMVECTOR Rotation, _In_ FXMVECTOR Translation) const noexcept;
|
||||||
|
|
||||||
|
void GetCorners(_Out_writes_(8) XMFLOAT3* Corners) const noexcept;
|
||||||
|
// Gets the 8 corners of the box
|
||||||
|
|
||||||
|
ContainmentType XM_CALLCONV Contains(_In_ FXMVECTOR Point) const noexcept;
|
||||||
|
ContainmentType XM_CALLCONV Contains(_In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingSphere& sh) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingBox& box) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingOrientedBox& box) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingFrustum& fr) const noexcept;
|
||||||
|
|
||||||
|
bool Intersects(_In_ const BoundingSphere& sh) const noexcept;
|
||||||
|
bool Intersects(_In_ const BoundingBox& box) const noexcept;
|
||||||
|
bool Intersects(_In_ const BoundingOrientedBox& box) const noexcept;
|
||||||
|
bool Intersects(_In_ const BoundingFrustum& fr) const noexcept;
|
||||||
|
|
||||||
|
bool XM_CALLCONV Intersects(_In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2) const noexcept;
|
||||||
|
// Triangle-OrientedBox test
|
||||||
|
|
||||||
|
PlaneIntersectionType XM_CALLCONV Intersects(_In_ FXMVECTOR Plane) const noexcept;
|
||||||
|
// Plane-OrientedBox test
|
||||||
|
|
||||||
|
bool XM_CALLCONV Intersects(_In_ FXMVECTOR Origin, _In_ FXMVECTOR Direction, _Out_ float& Dist) const noexcept;
|
||||||
|
// Ray-OrientedBox test
|
||||||
|
|
||||||
|
ContainmentType XM_CALLCONV ContainedBy(_In_ FXMVECTOR Plane0, _In_ FXMVECTOR Plane1, _In_ FXMVECTOR Plane2,
|
||||||
|
_In_ GXMVECTOR Plane3, _In_ HXMVECTOR Plane4, _In_ HXMVECTOR Plane5) const noexcept;
|
||||||
|
// Test OrientedBox against six planes (see BoundingFrustum::GetPlanes)
|
||||||
|
|
||||||
|
// Static methods
|
||||||
|
static void CreateFromBoundingBox(_Out_ BoundingOrientedBox& Out, _In_ const BoundingBox& box) noexcept;
|
||||||
|
|
||||||
|
static void CreateFromPoints(_Out_ BoundingOrientedBox& Out, _In_ size_t Count,
|
||||||
|
_In_reads_bytes_(sizeof(XMFLOAT3) + Stride * (Count - 1)) const XMFLOAT3* pPoints, _In_ size_t Stride) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Bounding frustum
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
struct BoundingFrustum
|
||||||
|
{
|
||||||
|
static constexpr size_t CORNER_COUNT = 8;
|
||||||
|
|
||||||
|
XMFLOAT3 Origin; // Origin of the frustum (and projection).
|
||||||
|
XMFLOAT4 Orientation; // Quaternion representing rotation.
|
||||||
|
|
||||||
|
float RightSlope; // Positive X (X/Z)
|
||||||
|
float LeftSlope; // Negative X
|
||||||
|
float TopSlope; // Positive Y (Y/Z)
|
||||||
|
float BottomSlope; // Negative Y
|
||||||
|
float Near, Far; // Z of the near plane and far plane.
|
||||||
|
|
||||||
|
// Creators
|
||||||
|
BoundingFrustum() noexcept :
|
||||||
|
Origin(0, 0, 0), Orientation(0, 0, 0, 1.f), RightSlope(1.f), LeftSlope(-1.f),
|
||||||
|
TopSlope(1.f), BottomSlope(-1.f), Near(0), Far(1.f) {}
|
||||||
|
|
||||||
|
BoundingFrustum(const BoundingFrustum&) = default;
|
||||||
|
BoundingFrustum& operator=(const BoundingFrustum&) = default;
|
||||||
|
|
||||||
|
BoundingFrustum(BoundingFrustum&&) = default;
|
||||||
|
BoundingFrustum& operator=(BoundingFrustum&&) = default;
|
||||||
|
|
||||||
|
constexpr BoundingFrustum(_In_ const XMFLOAT3& origin, _In_ const XMFLOAT4& orientation,
|
||||||
|
_In_ float rightSlope, _In_ float leftSlope, _In_ float topSlope, _In_ float bottomSlope,
|
||||||
|
_In_ float nearPlane, _In_ float farPlane) noexcept
|
||||||
|
: Origin(origin), Orientation(orientation),
|
||||||
|
RightSlope(rightSlope), LeftSlope(leftSlope), TopSlope(topSlope), BottomSlope(bottomSlope),
|
||||||
|
Near(nearPlane), Far(farPlane) {}
|
||||||
|
BoundingFrustum(_In_ CXMMATRIX Projection, bool rhcoords = false) noexcept;
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
void XM_CALLCONV Transform(_Out_ BoundingFrustum& Out, _In_ FXMMATRIX M) const noexcept;
|
||||||
|
void XM_CALLCONV Transform(_Out_ BoundingFrustum& Out, _In_ float Scale, _In_ FXMVECTOR Rotation, _In_ FXMVECTOR Translation) const noexcept;
|
||||||
|
|
||||||
|
void GetCorners(_Out_writes_(8) XMFLOAT3* Corners) const noexcept;
|
||||||
|
// Gets the 8 corners of the frustum
|
||||||
|
|
||||||
|
ContainmentType XM_CALLCONV Contains(_In_ FXMVECTOR Point) const noexcept;
|
||||||
|
ContainmentType XM_CALLCONV Contains(_In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingSphere& sp) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingBox& box) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingOrientedBox& box) const noexcept;
|
||||||
|
ContainmentType Contains(_In_ const BoundingFrustum& fr) const noexcept;
|
||||||
|
// Frustum-Frustum test
|
||||||
|
|
||||||
|
bool Intersects(_In_ const BoundingSphere& sh) const noexcept;
|
||||||
|
bool Intersects(_In_ const BoundingBox& box) const noexcept;
|
||||||
|
bool Intersects(_In_ const BoundingOrientedBox& box) const noexcept;
|
||||||
|
bool Intersects(_In_ const BoundingFrustum& fr) const noexcept;
|
||||||
|
|
||||||
|
bool XM_CALLCONV Intersects(_In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2) const noexcept;
|
||||||
|
// Triangle-Frustum test
|
||||||
|
|
||||||
|
PlaneIntersectionType XM_CALLCONV Intersects(_In_ FXMVECTOR Plane) const noexcept;
|
||||||
|
// Plane-Frustum test
|
||||||
|
|
||||||
|
bool XM_CALLCONV Intersects(_In_ FXMVECTOR rayOrigin, _In_ FXMVECTOR Direction, _Out_ float& Dist) const noexcept;
|
||||||
|
// Ray-Frustum test
|
||||||
|
|
||||||
|
ContainmentType XM_CALLCONV ContainedBy(_In_ FXMVECTOR Plane0, _In_ FXMVECTOR Plane1, _In_ FXMVECTOR Plane2,
|
||||||
|
_In_ GXMVECTOR Plane3, _In_ HXMVECTOR Plane4, _In_ HXMVECTOR Plane5) const noexcept;
|
||||||
|
// Test frustum against six planes (see BoundingFrustum::GetPlanes)
|
||||||
|
|
||||||
|
void GetPlanes(_Out_opt_ XMVECTOR* NearPlane, _Out_opt_ XMVECTOR* FarPlane, _Out_opt_ XMVECTOR* RightPlane,
|
||||||
|
_Out_opt_ XMVECTOR* LeftPlane, _Out_opt_ XMVECTOR* TopPlane, _Out_opt_ XMVECTOR* BottomPlane) const noexcept;
|
||||||
|
// Create 6 Planes representation of Frustum
|
||||||
|
|
||||||
|
// Static methods
|
||||||
|
static void XM_CALLCONV CreateFromMatrix(_Out_ BoundingFrustum& Out, _In_ FXMMATRIX Projection, bool rhcoords = false) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Triangle intersection testing routines.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
namespace TriangleTests
|
||||||
|
{
|
||||||
|
bool XM_CALLCONV Intersects(_In_ FXMVECTOR Origin, _In_ FXMVECTOR Direction, _In_ FXMVECTOR V0, _In_ GXMVECTOR V1, _In_ HXMVECTOR V2, _Out_ float& Dist) noexcept;
|
||||||
|
// Ray-Triangle
|
||||||
|
|
||||||
|
bool XM_CALLCONV Intersects(_In_ FXMVECTOR A0, _In_ FXMVECTOR A1, _In_ FXMVECTOR A2, _In_ GXMVECTOR B0, _In_ HXMVECTOR B1, _In_ HXMVECTOR B2) noexcept;
|
||||||
|
// Triangle-Triangle
|
||||||
|
|
||||||
|
PlaneIntersectionType XM_CALLCONV Intersects(_In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2, _In_ GXMVECTOR Plane) noexcept;
|
||||||
|
// Plane-Triangle
|
||||||
|
|
||||||
|
ContainmentType XM_CALLCONV ContainedBy(_In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2,
|
||||||
|
_In_ GXMVECTOR Plane0, _In_ HXMVECTOR Plane1, _In_ HXMVECTOR Plane2,
|
||||||
|
_In_ CXMVECTOR Plane3, _In_ CXMVECTOR Plane4, _In_ CXMVECTOR Plane5) noexcept;
|
||||||
|
// Test a triangle against six planes at once (see BoundingFrustum::GetPlanes)
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Implementation
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4068 4365 4616 6001)
|
||||||
|
// C4068/4616: ignore unknown pragmas
|
||||||
|
// C4365: Off by default noise
|
||||||
|
// C6001: False positives
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _PREFAST_
|
||||||
|
#pragma prefast(push)
|
||||||
|
#pragma prefast(disable : 25000, "FXMVECTOR is 16 bytes")
|
||||||
|
#pragma prefast(disable : 26495, "Union initialization confuses /analyze")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wfloat-equal"
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-warning-option"
|
||||||
|
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "DirectXCollision.inl"
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
#ifdef _PREFAST_
|
||||||
|
#pragma prefast(pop)
|
||||||
|
#endif
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace DirectX
|
||||||
4815
src/directxmath/DirectXCollision.inl
Normal file
4815
src/directxmath/DirectXCollision.inl
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,10 @@
|
|||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
// DirectXMathConvert.inl -- SIMD C++ Math library
|
// DirectXMathConvert.inl -- SIMD C++ Math library
|
||||||
//
|
//
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the MIT License.
|
// Licensed under the MIT License.
|
||||||
//
|
//
|
||||||
// http://go.microsoft.com/fwlink/?LinkID=615560
|
// https://go.microsoft.com/fwlink/?LinkID=615560
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@ -15,11 +15,13 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable:4701)
|
#pragma warning(disable:4701)
|
||||||
// C4701: false positives
|
// C4701: false positives
|
||||||
|
#endif
|
||||||
|
|
||||||
inline XMVECTOR XM_CALLCONV XMConvertVectorIntToFloat
|
inline XMVECTOR XM_CALLCONV XMConvertVectorIntToFloat
|
||||||
(
|
(
|
||||||
@ -32,14 +34,16 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorIntToFloat
|
|||||||
float fScale = 1.0f / static_cast<float>(1U << DivExponent);
|
float fScale = 1.0f / static_cast<float>(1U << DivExponent);
|
||||||
uint32_t ElementIndex = 0;
|
uint32_t ElementIndex = 0;
|
||||||
XMVECTOR Result;
|
XMVECTOR Result;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
auto iTemp = static_cast<int32_t>(VInt.vector4_u32[ElementIndex]);
|
auto iTemp = static_cast<int32_t>(VInt.vector4_u32[ElementIndex]);
|
||||||
Result.vector4_f32[ElementIndex] = static_cast<float>(iTemp)* fScale;
|
Result.vector4_f32[ElementIndex] = static_cast<float>(iTemp)* fScale;
|
||||||
} while (++ElementIndex < 4);
|
}
|
||||||
|
while (++ElementIndex < 4);
|
||||||
return Result;
|
return Result;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
float fScale = 1.0f / (float)(1U << DivExponent);
|
float fScale = 1.0f / static_cast<float>(1U << DivExponent);
|
||||||
float32x4_t vResult = vcvtq_f32_s32(VInt);
|
float32x4_t vResult = vcvtq_f32_s32(vreinterpretq_s32_f32(VInt));
|
||||||
return vmulq_n_f32(vResult, fScale);
|
return vmulq_n_f32(vResult, fScale);
|
||||||
#else // _XM_SSE_INTRINSICS_
|
#else // _XM_SSE_INTRINSICS_
|
||||||
// Convert to floats
|
// Convert to floats
|
||||||
@ -67,7 +71,8 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorFloatToInt
|
|||||||
auto fScale = static_cast<float>(1U << MulExponent);
|
auto fScale = static_cast<float>(1U << MulExponent);
|
||||||
uint32_t ElementIndex = 0;
|
uint32_t ElementIndex = 0;
|
||||||
XMVECTOR Result;
|
XMVECTOR Result;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
int32_t iResult;
|
int32_t iResult;
|
||||||
float fTemp = VFloat.vector4_f32[ElementIndex] * fScale;
|
float fTemp = VFloat.vector4_f32[ElementIndex] * fScale;
|
||||||
if (fTemp <= -(65536.0f * 32768.0f))
|
if (fTemp <= -(65536.0f * 32768.0f))
|
||||||
@ -78,23 +83,25 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorFloatToInt
|
|||||||
{
|
{
|
||||||
iResult = 0x7FFFFFFF;
|
iResult = 0x7FFFFFFF;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
iResult = static_cast<int32_t>(fTemp);
|
iResult = static_cast<int32_t>(fTemp);
|
||||||
}
|
}
|
||||||
Result.vector4_u32[ElementIndex] = static_cast<uint32_t>(iResult);
|
Result.vector4_u32[ElementIndex] = static_cast<uint32_t>(iResult);
|
||||||
} while (++ElementIndex < 4);
|
}
|
||||||
|
while (++ElementIndex < 4);
|
||||||
return Result;
|
return Result;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
float32x4_t vResult = vmulq_n_f32(VFloat, (float)(1U << MulExponent));
|
float32x4_t vResult = vmulq_n_f32(VFloat, static_cast<float>(1U << MulExponent));
|
||||||
// In case of positive overflow, detect it
|
// In case of positive overflow, detect it
|
||||||
uint32x4_t vOverflow = vcgtq_f32(vResult, g_XMMaxInt);
|
uint32x4_t vOverflow = vcgtq_f32(vResult, g_XMMaxInt);
|
||||||
// Float to int conversion
|
// Float to int conversion
|
||||||
int32x4_t vResulti = vcvtq_s32_f32(vResult);
|
int32x4_t vResulti = vcvtq_s32_f32(vResult);
|
||||||
// If there was positive overflow, set to 0x7FFFFFFF
|
// If there was positive overflow, set to 0x7FFFFFFF
|
||||||
vResult = vandq_u32(vOverflow, g_XMAbsMask);
|
vResult = vreinterpretq_f32_u32(vandq_u32(vOverflow, g_XMAbsMask));
|
||||||
vOverflow = vbicq_u32(vResulti, vOverflow);
|
vOverflow = vbicq_u32(vreinterpretq_u32_s32(vResulti), vOverflow);
|
||||||
vOverflow = vorrq_u32(vOverflow, vResult);
|
vOverflow = vorrq_u32(vOverflow, vreinterpretq_u32_f32(vResult));
|
||||||
return vOverflow;
|
return vreinterpretq_f32_u32(vOverflow);
|
||||||
#else // _XM_SSE_INTRINSICS_
|
#else // _XM_SSE_INTRINSICS_
|
||||||
XMVECTOR vResult = _mm_set_ps1(static_cast<float>(1U << MulExponent));
|
XMVECTOR vResult = _mm_set_ps1(static_cast<float>(1U << MulExponent));
|
||||||
vResult = _mm_mul_ps(vResult, VFloat);
|
vResult = _mm_mul_ps(vResult, VFloat);
|
||||||
@ -123,13 +130,15 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorUIntToFloat
|
|||||||
float fScale = 1.0f / static_cast<float>(1U << DivExponent);
|
float fScale = 1.0f / static_cast<float>(1U << DivExponent);
|
||||||
uint32_t ElementIndex = 0;
|
uint32_t ElementIndex = 0;
|
||||||
XMVECTOR Result;
|
XMVECTOR Result;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
Result.vector4_f32[ElementIndex] = static_cast<float>(VUInt.vector4_u32[ElementIndex])* fScale;
|
Result.vector4_f32[ElementIndex] = static_cast<float>(VUInt.vector4_u32[ElementIndex])* fScale;
|
||||||
} while (++ElementIndex < 4);
|
}
|
||||||
|
while (++ElementIndex < 4);
|
||||||
return Result;
|
return Result;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
float fScale = 1.0f / (float)(1U << DivExponent);
|
float fScale = 1.0f / static_cast<float>(1U << DivExponent);
|
||||||
float32x4_t vResult = vcvtq_f32_u32(VUInt);
|
float32x4_t vResult = vcvtq_f32_u32(vreinterpretq_u32_f32(VUInt));
|
||||||
return vmulq_n_f32(vResult, fScale);
|
return vmulq_n_f32(vResult, fScale);
|
||||||
#else // _XM_SSE_INTRINSICS_
|
#else // _XM_SSE_INTRINSICS_
|
||||||
// For the values that are higher than 0x7FFFFFFF, a fixup is needed
|
// For the values that are higher than 0x7FFFFFFF, a fixup is needed
|
||||||
@ -167,7 +176,8 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorFloatToUInt
|
|||||||
auto fScale = static_cast<float>(1U << MulExponent);
|
auto fScale = static_cast<float>(1U << MulExponent);
|
||||||
uint32_t ElementIndex = 0;
|
uint32_t ElementIndex = 0;
|
||||||
XMVECTOR Result;
|
XMVECTOR Result;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
uint32_t uResult;
|
uint32_t uResult;
|
||||||
float fTemp = VFloat.vector4_f32[ElementIndex] * fScale;
|
float fTemp = VFloat.vector4_f32[ElementIndex] * fScale;
|
||||||
if (fTemp <= 0.0f)
|
if (fTemp <= 0.0f)
|
||||||
@ -178,22 +188,24 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorFloatToUInt
|
|||||||
{
|
{
|
||||||
uResult = 0xFFFFFFFFU;
|
uResult = 0xFFFFFFFFU;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
uResult = static_cast<uint32_t>(fTemp);
|
uResult = static_cast<uint32_t>(fTemp);
|
||||||
}
|
}
|
||||||
Result.vector4_u32[ElementIndex] = uResult;
|
Result.vector4_u32[ElementIndex] = uResult;
|
||||||
} while (++ElementIndex < 4);
|
}
|
||||||
|
while (++ElementIndex < 4);
|
||||||
return Result;
|
return Result;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
float32x4_t vResult = vmulq_n_f32(VFloat, (float)(1U << MulExponent));
|
float32x4_t vResult = vmulq_n_f32(VFloat, static_cast<float>(1U << MulExponent));
|
||||||
// In case of overflow, detect it
|
// In case of overflow, detect it
|
||||||
uint32x4_t vOverflow = vcgtq_f32(vResult, g_XMMaxUInt);
|
uint32x4_t vOverflow = vcgtq_f32(vResult, g_XMMaxUInt);
|
||||||
// Float to int conversion
|
// Float to int conversion
|
||||||
uint32x4_t vResulti = vcvtq_u32_f32(vResult);
|
uint32x4_t vResulti = vcvtq_u32_f32(vResult);
|
||||||
// If there was overflow, set to 0xFFFFFFFFU
|
// If there was overflow, set to 0xFFFFFFFFU
|
||||||
vResult = vbicq_u32(vResulti, vOverflow);
|
vResult = vreinterpretq_f32_u32(vbicq_u32(vResulti, vOverflow));
|
||||||
vOverflow = vorrq_u32(vOverflow, vResult);
|
vOverflow = vorrq_u32(vOverflow, vreinterpretq_u32_f32(vResult));
|
||||||
return vOverflow;
|
return vreinterpretq_f32_u32(vOverflow);
|
||||||
#else // _XM_SSE_INTRINSICS_
|
#else // _XM_SSE_INTRINSICS_
|
||||||
XMVECTOR vResult = _mm_set_ps1(static_cast<float>(1U << MulExponent));
|
XMVECTOR vResult = _mm_set_ps1(static_cast<float>(1U << MulExponent));
|
||||||
vResult = _mm_mul_ps(vResult, VFloat);
|
vResult = _mm_mul_ps(vResult, VFloat);
|
||||||
@ -218,7 +230,9 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorFloatToUInt
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
@ -226,7 +240,7 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorFloatToUInt
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
_Use_decl_annotations_
|
_Use_decl_annotations_
|
||||||
inline XMVECTOR XM_CALLCONV XMLoadInt(const uint32_t* pSource) noexcept
|
inline XMVECTOR XM_CALLCONV XMLoadInt(const uint32_t* pSource) noexcept
|
||||||
{
|
{
|
||||||
@ -240,7 +254,7 @@ inline XMVECTOR XM_CALLCONV XMLoadInt(const uint32_t* pSource) noexcept
|
|||||||
return V;
|
return V;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
uint32x4_t zero = vdupq_n_u32(0);
|
uint32x4_t zero = vdupq_n_u32(0);
|
||||||
return vld1q_lane_u32(pSource, zero, 0);
|
return vreinterpretq_f32_u32(vld1q_lane_u32(pSource, zero, 0));
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
return _mm_load_ss(reinterpret_cast<const float*>(pSource));
|
return _mm_load_ss(reinterpret_cast<const float*>(pSource));
|
||||||
#endif
|
#endif
|
||||||
@ -281,7 +295,7 @@ inline XMVECTOR XM_CALLCONV XMLoadInt2(const uint32_t* pSource) noexcept
|
|||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
uint32x2_t x = vld1_u32(pSource);
|
uint32x2_t x = vld1_u32(pSource);
|
||||||
uint32x2_t zero = vdup_n_u32(0);
|
uint32x2_t zero = vdup_n_u32(0);
|
||||||
return vcombine_u32(x, zero);
|
return vreinterpretq_f32_u32(vcombine_u32(x, zero));
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
return _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(pSource)));
|
return _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(pSource)));
|
||||||
#endif
|
#endif
|
||||||
@ -301,13 +315,13 @@ inline XMVECTOR XM_CALLCONV XMLoadInt2A(const uint32_t* pSource) noexcept
|
|||||||
V.vector4_u32[3] = 0;
|
V.vector4_u32[3] = 0;
|
||||||
return V;
|
return V;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
uint32x2_t x = vld1_u32_ex(pSource, 64);
|
uint32x2_t x = vld1_u32_ex(pSource, 64);
|
||||||
#else
|
#else
|
||||||
uint32x2_t x = vld1_u32(pSource);
|
uint32x2_t x = vld1_u32(pSource);
|
||||||
#endif
|
#endif
|
||||||
uint32x2_t zero = vdup_n_u32(0);
|
uint32x2_t zero = vdup_n_u32(0);
|
||||||
return vcombine_u32(x, zero);
|
return vreinterpretq_f32_u32(vcombine_u32(x, zero));
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
return _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(pSource)));
|
return _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(pSource)));
|
||||||
#endif
|
#endif
|
||||||
@ -348,7 +362,7 @@ inline XMVECTOR XM_CALLCONV XMLoadFloat2A(const XMFLOAT2A* pSource) noexcept
|
|||||||
V.vector4_f32[3] = 0.f;
|
V.vector4_f32[3] = 0.f;
|
||||||
return V;
|
return V;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
float32x2_t x = vld1_f32_ex(reinterpret_cast<const float*>(pSource), 64);
|
float32x2_t x = vld1_f32_ex(reinterpret_cast<const float*>(pSource), 64);
|
||||||
#else
|
#else
|
||||||
float32x2_t x = vld1_f32(reinterpret_cast<const float*>(pSource));
|
float32x2_t x = vld1_f32(reinterpret_cast<const float*>(pSource));
|
||||||
@ -434,7 +448,7 @@ inline XMVECTOR XM_CALLCONV XMLoadInt3(const uint32_t* pSource) noexcept
|
|||||||
uint32x2_t x = vld1_u32(pSource);
|
uint32x2_t x = vld1_u32(pSource);
|
||||||
uint32x2_t zero = vdup_n_u32(0);
|
uint32x2_t zero = vdup_n_u32(0);
|
||||||
uint32x2_t y = vld1_lane_u32(pSource + 2, zero, 0);
|
uint32x2_t y = vld1_lane_u32(pSource + 2, zero, 0);
|
||||||
return vcombine_u32(x, y);
|
return vreinterpretq_f32_u32(vcombine_u32(x, y));
|
||||||
#elif defined(_XM_SSE4_INTRINSICS_)
|
#elif defined(_XM_SSE4_INTRINSICS_)
|
||||||
__m128 xy = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(pSource)));
|
__m128 xy = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(pSource)));
|
||||||
__m128 z = _mm_load_ss(reinterpret_cast<const float*>(pSource + 2));
|
__m128 z = _mm_load_ss(reinterpret_cast<const float*>(pSource + 2));
|
||||||
@ -461,12 +475,12 @@ inline XMVECTOR XM_CALLCONV XMLoadInt3A(const uint32_t* pSource) noexcept
|
|||||||
return V;
|
return V;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
// Reads an extra integer which is zero'd
|
// Reads an extra integer which is zero'd
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
uint32x4_t V = vld1q_u32_ex(pSource, 128);
|
uint32x4_t V = vld1q_u32_ex(pSource, 128);
|
||||||
#else
|
#else
|
||||||
uint32x4_t V = vld1q_u32(pSource);
|
uint32x4_t V = vld1q_u32(pSource);
|
||||||
#endif
|
#endif
|
||||||
return vsetq_lane_u32(0, V, 3);
|
return vreinterpretq_f32_u32(vsetq_lane_u32(0, V, 3));
|
||||||
#elif defined(_XM_SSE4_INTRINSICS_)
|
#elif defined(_XM_SSE4_INTRINSICS_)
|
||||||
__m128 xy = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(pSource)));
|
__m128 xy = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(pSource)));
|
||||||
__m128 z = _mm_load_ss(reinterpret_cast<const float*>(pSource + 2));
|
__m128 z = _mm_load_ss(reinterpret_cast<const float*>(pSource + 2));
|
||||||
@ -521,12 +535,16 @@ inline XMVECTOR XM_CALLCONV XMLoadFloat3A(const XMFLOAT3A* pSource) noexcept
|
|||||||
return V;
|
return V;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
// Reads an extra float which is zero'd
|
// Reads an extra float which is zero'd
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
float32x4_t V = vld1q_f32_ex(reinterpret_cast<const float*>(pSource), 128);
|
float32x4_t V = vld1q_f32_ex(reinterpret_cast<const float*>(pSource), 128);
|
||||||
#else
|
#else
|
||||||
float32x4_t V = vld1q_f32(reinterpret_cast<const float*>(pSource));
|
float32x4_t V = vld1q_f32(reinterpret_cast<const float*>(pSource));
|
||||||
#endif
|
#endif
|
||||||
return vsetq_lane_f32(0, V, 3);
|
return vsetq_lane_f32(0, V, 3);
|
||||||
|
#elif defined(_XM_SSE4_INTRINSICS_)
|
||||||
|
// Reads an extra float which is zero'd
|
||||||
|
__m128 V = _mm_load_ps(&pSource->x);
|
||||||
|
return _mm_blend_ps(_mm_setzero_ps(), V, 0x7);
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
// Reads an extra float which is zero'd
|
// Reads an extra float which is zero'd
|
||||||
__m128 V = _mm_load_ps(&pSource->x);
|
__m128 V = _mm_load_ps(&pSource->x);
|
||||||
@ -614,7 +632,7 @@ inline XMVECTOR XM_CALLCONV XMLoadInt4(const uint32_t* pSource) noexcept
|
|||||||
V.vector4_u32[3] = pSource[3];
|
V.vector4_u32[3] = pSource[3];
|
||||||
return V;
|
return V;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
return vld1q_u32(pSource);
|
return vreinterpretq_f32_u32(vld1q_u32(pSource));
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
__m128i V = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pSource));
|
__m128i V = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pSource));
|
||||||
return _mm_castsi128_ps(V);
|
return _mm_castsi128_ps(V);
|
||||||
@ -635,10 +653,10 @@ inline XMVECTOR XM_CALLCONV XMLoadInt4A(const uint32_t* pSource) noexcept
|
|||||||
V.vector4_u32[3] = pSource[3];
|
V.vector4_u32[3] = pSource[3];
|
||||||
return V;
|
return V;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
return vld1q_u32_ex(pSource, 128);
|
return vld1q_u32_ex(pSource, 128);
|
||||||
#else
|
#else
|
||||||
return vld1q_u32(pSource);
|
return vreinterpretq_f32_u32(vld1q_u32(pSource));
|
||||||
#endif
|
#endif
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
__m128i V = _mm_load_si128(reinterpret_cast<const __m128i*>(pSource));
|
__m128i V = _mm_load_si128(reinterpret_cast<const __m128i*>(pSource));
|
||||||
@ -679,7 +697,7 @@ inline XMVECTOR XM_CALLCONV XMLoadFloat4A(const XMFLOAT4A* pSource) noexcept
|
|||||||
V.vector4_f32[3] = pSource->w;
|
V.vector4_f32[3] = pSource->w;
|
||||||
return V;
|
return V;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
return vld1q_f32_ex(reinterpret_cast<const float*>(pSource), 128);
|
return vld1q_f32_ex(reinterpret_cast<const float*>(pSource), 128);
|
||||||
#else
|
#else
|
||||||
return vld1q_f32(reinterpret_cast<const float*>(pSource));
|
return vld1q_f32(reinterpret_cast<const float*>(pSource));
|
||||||
@ -780,8 +798,8 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat3x3(const XMFLOAT3X3* pSource) noexcept
|
|||||||
float32x4_t T = vextq_f32(v0, v1, 3);
|
float32x4_t T = vextq_f32(v0, v1, 3);
|
||||||
|
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vandq_u32(v0, g_XMMask3);
|
M.r[0] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(v0), g_XMMask3));
|
||||||
M.r[1] = vandq_u32(T, g_XMMask3);
|
M.r[1] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T), g_XMMask3));
|
||||||
M.r[2] = vcombine_f32(vget_high_f32(v1), v2);
|
M.r[2] = vcombine_f32(vget_high_f32(v1), v2);
|
||||||
M.r[3] = g_XMIdentityR3;
|
M.r[3] = g_XMIdentityR3;
|
||||||
return M;
|
return M;
|
||||||
@ -846,9 +864,9 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat4x3(const XMFLOAT4X3* pSource) noexcept
|
|||||||
float32x4_t T3 = vextq_f32(v2, v2, 1);
|
float32x4_t T3 = vextq_f32(v2, v2, 1);
|
||||||
|
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vandq_u32(v0, g_XMMask3);
|
M.r[0] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(v0), g_XMMask3));
|
||||||
M.r[1] = vandq_u32(T1, g_XMMask3);
|
M.r[1] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T1), g_XMMask3));
|
||||||
M.r[2] = vandq_u32(T2, g_XMMask3);
|
M.r[2] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T2), g_XMMask3));
|
||||||
M.r[3] = vsetq_lane_f32(1.f, T3, 3);
|
M.r[3] = vsetq_lane_f32(1.f, T3, 3);
|
||||||
return M;
|
return M;
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
@ -867,11 +885,18 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat4x3(const XMFLOAT4X3* pSource) noexcept
|
|||||||
// vTemp2 = x2,y2,z2,z2
|
// vTemp2 = x2,y2,z2,z2
|
||||||
vTemp2 = XM_PERMUTE_PS(vTemp2, _MM_SHUFFLE(1, 1, 0, 2));
|
vTemp2 = XM_PERMUTE_PS(vTemp2, _MM_SHUFFLE(1, 1, 0, 2));
|
||||||
// vTemp1 = x1,y1,z1,0
|
// vTemp1 = x1,y1,z1,0
|
||||||
vTemp1 = _mm_and_ps(vTemp1, g_XMMask3);
|
|
||||||
// vTemp2 = x2,y2,z2,0
|
// vTemp2 = x2,y2,z2,0
|
||||||
vTemp2 = _mm_and_ps(vTemp2, g_XMMask3);
|
|
||||||
// vTemp3 = x3,y3,z3,0
|
// vTemp3 = x3,y3,z3,0
|
||||||
|
#ifdef _XM_SSE4_INTRINSICS_
|
||||||
|
XMVECTOR zero = _mm_setzero_ps();
|
||||||
|
vTemp1 = _mm_blend_ps(zero, vTemp1, 0x7);
|
||||||
|
vTemp2 = _mm_blend_ps(zero, vTemp2, 0x7);
|
||||||
|
vTemp3 = _mm_blend_ps(zero, vTemp3, 0x7);
|
||||||
|
#else
|
||||||
|
vTemp1 = _mm_and_ps(vTemp1, g_XMMask3);
|
||||||
|
vTemp2 = _mm_and_ps(vTemp2, g_XMMask3);
|
||||||
vTemp3 = _mm_and_ps(vTemp3, g_XMMask3);
|
vTemp3 = _mm_and_ps(vTemp3, g_XMMask3);
|
||||||
|
#endif
|
||||||
// vTemp4i = x4,y4,z4,0
|
// vTemp4i = x4,y4,z4,0
|
||||||
__m128i vTemp4i = _mm_srli_si128(_mm_castps_si128(vTemp4), 32 / 8);
|
__m128i vTemp4i = _mm_srli_si128(_mm_castps_si128(vTemp4), 32 / 8);
|
||||||
// vTemp4i = x4,y4,z4,1.0f
|
// vTemp4i = x4,y4,z4,1.0f
|
||||||
@ -915,7 +940,7 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat4x3A(const XMFLOAT4X3A* pSource) noexcept
|
|||||||
return M;
|
return M;
|
||||||
|
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
float32x4_t v0 = vld1q_f32_ex(&pSource->m[0][0], 128);
|
float32x4_t v0 = vld1q_f32_ex(&pSource->m[0][0], 128);
|
||||||
float32x4_t v1 = vld1q_f32_ex(&pSource->m[1][1], 128);
|
float32x4_t v1 = vld1q_f32_ex(&pSource->m[1][1], 128);
|
||||||
float32x4_t v2 = vld1q_f32_ex(&pSource->m[2][2], 128);
|
float32x4_t v2 = vld1q_f32_ex(&pSource->m[2][2], 128);
|
||||||
@ -930,9 +955,9 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat4x3A(const XMFLOAT4X3A* pSource) noexcept
|
|||||||
float32x4_t T3 = vextq_f32(v2, v2, 1);
|
float32x4_t T3 = vextq_f32(v2, v2, 1);
|
||||||
|
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vandq_u32(v0, g_XMMask3);
|
M.r[0] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(v0), g_XMMask3));
|
||||||
M.r[1] = vandq_u32(T1, g_XMMask3);
|
M.r[1] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T1), g_XMMask3));
|
||||||
M.r[2] = vandq_u32(T2, g_XMMask3);
|
M.r[2] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T2), g_XMMask3));
|
||||||
M.r[3] = vsetq_lane_f32(1.f, T3, 3);
|
M.r[3] = vsetq_lane_f32(1.f, T3, 3);
|
||||||
return M;
|
return M;
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
@ -951,11 +976,18 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat4x3A(const XMFLOAT4X3A* pSource) noexcept
|
|||||||
// vTemp2 = x2,y2,z2,z2
|
// vTemp2 = x2,y2,z2,z2
|
||||||
vTemp2 = XM_PERMUTE_PS(vTemp2, _MM_SHUFFLE(1, 1, 0, 2));
|
vTemp2 = XM_PERMUTE_PS(vTemp2, _MM_SHUFFLE(1, 1, 0, 2));
|
||||||
// vTemp1 = x1,y1,z1,0
|
// vTemp1 = x1,y1,z1,0
|
||||||
vTemp1 = _mm_and_ps(vTemp1, g_XMMask3);
|
|
||||||
// vTemp2 = x2,y2,z2,0
|
// vTemp2 = x2,y2,z2,0
|
||||||
vTemp2 = _mm_and_ps(vTemp2, g_XMMask3);
|
|
||||||
// vTemp3 = x3,y3,z3,0
|
// vTemp3 = x3,y3,z3,0
|
||||||
|
#ifdef _XM_SSE4_INTRINSICS_
|
||||||
|
XMVECTOR zero = _mm_setzero_ps();
|
||||||
|
vTemp1 = _mm_blend_ps(zero, vTemp1, 0x7);
|
||||||
|
vTemp2 = _mm_blend_ps(zero, vTemp2, 0x7);
|
||||||
|
vTemp3 = _mm_blend_ps(zero, vTemp3, 0x7);
|
||||||
|
#else
|
||||||
|
vTemp1 = _mm_and_ps(vTemp1, g_XMMask3);
|
||||||
|
vTemp2 = _mm_and_ps(vTemp2, g_XMMask3);
|
||||||
vTemp3 = _mm_and_ps(vTemp3, g_XMMask3);
|
vTemp3 = _mm_and_ps(vTemp3, g_XMMask3);
|
||||||
|
#endif
|
||||||
// vTemp4i = x4,y4,z4,0
|
// vTemp4i = x4,y4,z4,0
|
||||||
__m128i vTemp4i = _mm_srli_si128(_mm_castps_si128(vTemp4), 32 / 8);
|
__m128i vTemp4i = _mm_srli_si128(_mm_castps_si128(vTemp4), 32 / 8);
|
||||||
// vTemp4i = x4,y4,z4,1.0f
|
// vTemp4i = x4,y4,z4,1.0f
|
||||||
@ -1012,9 +1044,9 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat3x4(const XMFLOAT3X4* pSource) noexcept
|
|||||||
float32x4_t T3 = vcombine_f32(vTemp0.val[3], rh);
|
float32x4_t T3 = vcombine_f32(vTemp0.val[3], rh);
|
||||||
|
|
||||||
XMMATRIX M = {};
|
XMMATRIX M = {};
|
||||||
M.r[0] = vandq_u32(T0, g_XMMask3);
|
M.r[0] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T0), g_XMMask3));
|
||||||
M.r[1] = vandq_u32(T1, g_XMMask3);
|
M.r[1] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T1), g_XMMask3));
|
||||||
M.r[2] = vandq_u32(T2, g_XMMask3);
|
M.r[2] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T2), g_XMMask3));
|
||||||
M.r[3] = vsetq_lane_f32(1.f, T3, 3);
|
M.r[3] = vsetq_lane_f32(1.f, T3, 3);
|
||||||
return M;
|
return M;
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
@ -1077,7 +1109,7 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat3x4A(const XMFLOAT3X4A* pSource) noexcept
|
|||||||
return M;
|
return M;
|
||||||
|
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
float32x2x4_t vTemp0 = vld4_f32_ex(&pSource->_11, 128);
|
float32x2x4_t vTemp0 = vld4_f32_ex(&pSource->_11, 128);
|
||||||
float32x4_t vTemp1 = vld1q_f32_ex(&pSource->_31, 128);
|
float32x4_t vTemp1 = vld1q_f32_ex(&pSource->_31, 128);
|
||||||
#else
|
#else
|
||||||
@ -1096,9 +1128,9 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat3x4A(const XMFLOAT3X4A* pSource) noexcept
|
|||||||
float32x4_t T3 = vcombine_f32(vTemp0.val[3], rh);
|
float32x4_t T3 = vcombine_f32(vTemp0.val[3], rh);
|
||||||
|
|
||||||
XMMATRIX M = {};
|
XMMATRIX M = {};
|
||||||
M.r[0] = vandq_u32(T0, g_XMMask3);
|
M.r[0] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T0), g_XMMask3));
|
||||||
M.r[1] = vandq_u32(T1, g_XMMask3);
|
M.r[1] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T1), g_XMMask3));
|
||||||
M.r[2] = vandq_u32(T2, g_XMMask3);
|
M.r[2] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T2), g_XMMask3));
|
||||||
M.r[3] = vsetq_lane_f32(1.f, T3, 3);
|
M.r[3] = vsetq_lane_f32(1.f, T3, 3);
|
||||||
return M;
|
return M;
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
@ -1208,7 +1240,7 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat4x4A(const XMFLOAT4X4A* pSource) noexcept
|
|||||||
|
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
M.r[0] = vld1q_f32_ex(reinterpret_cast<const float*>(&pSource->_11), 128);
|
M.r[0] = vld1q_f32_ex(reinterpret_cast<const float*>(&pSource->_11), 128);
|
||||||
M.r[1] = vld1q_f32_ex(reinterpret_cast<const float*>(&pSource->_21), 128);
|
M.r[1] = vld1q_f32_ex(reinterpret_cast<const float*>(&pSource->_21), 128);
|
||||||
M.r[2] = vld1q_f32_ex(reinterpret_cast<const float*>(&pSource->_31), 128);
|
M.r[2] = vld1q_f32_ex(reinterpret_cast<const float*>(&pSource->_31), 128);
|
||||||
@ -1283,7 +1315,7 @@ inline void XM_CALLCONV XMStoreInt2
|
|||||||
pDestination[0] = V.vector4_u32[0];
|
pDestination[0] = V.vector4_u32[0];
|
||||||
pDestination[1] = V.vector4_u32[1];
|
pDestination[1] = V.vector4_u32[1];
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
uint32x2_t VL = vget_low_u32(V);
|
uint32x2_t VL = vget_low_u32(vreinterpretq_u32_f32(V));
|
||||||
vst1_u32(pDestination, VL);
|
vst1_u32(pDestination, VL);
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
_mm_store_sd(reinterpret_cast<double*>(pDestination), _mm_castps_pd(V));
|
_mm_store_sd(reinterpret_cast<double*>(pDestination), _mm_castps_pd(V));
|
||||||
@ -1304,8 +1336,8 @@ inline void XM_CALLCONV XMStoreInt2A
|
|||||||
pDestination[0] = V.vector4_u32[0];
|
pDestination[0] = V.vector4_u32[0];
|
||||||
pDestination[1] = V.vector4_u32[1];
|
pDestination[1] = V.vector4_u32[1];
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
uint32x2_t VL = vget_low_u32(V);
|
uint32x2_t VL = vget_low_u32(vreinterpretq_u32_f32(V));
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
vst1_u32_ex(pDestination, VL, 64);
|
vst1_u32_ex(pDestination, VL, 64);
|
||||||
#else
|
#else
|
||||||
vst1_u32(pDestination, VL);
|
vst1_u32(pDestination, VL);
|
||||||
@ -1350,7 +1382,7 @@ inline void XM_CALLCONV XMStoreFloat2A
|
|||||||
pDestination->y = V.vector4_f32[1];
|
pDestination->y = V.vector4_f32[1];
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
float32x2_t VL = vget_low_f32(V);
|
float32x2_t VL = vget_low_f32(V);
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
vst1_f32_ex(reinterpret_cast<float*>(pDestination), VL, 64);
|
vst1_f32_ex(reinterpret_cast<float*>(pDestination), VL, 64);
|
||||||
#else
|
#else
|
||||||
vst1_f32(reinterpret_cast<float*>(pDestination), VL);
|
vst1_f32(reinterpret_cast<float*>(pDestination), VL);
|
||||||
@ -1373,9 +1405,9 @@ inline void XM_CALLCONV XMStoreSInt2
|
|||||||
pDestination->x = static_cast<int32_t>(V.vector4_f32[0]);
|
pDestination->x = static_cast<int32_t>(V.vector4_f32[0]);
|
||||||
pDestination->y = static_cast<int32_t>(V.vector4_f32[1]);
|
pDestination->y = static_cast<int32_t>(V.vector4_f32[1]);
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
int32x2_t v = vget_low_s32(V);
|
float32x2_t v = vget_low_f32(V);
|
||||||
v = vcvt_s32_f32(v);
|
int32x2_t iv = vcvt_s32_f32(v);
|
||||||
vst1_s32(reinterpret_cast<int32_t*>(pDestination), v);
|
vst1_s32(reinterpret_cast<int32_t*>(pDestination), iv);
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
// In case of positive overflow, detect it
|
// In case of positive overflow, detect it
|
||||||
XMVECTOR vOverflow = _mm_cmpgt_ps(V, g_XMMaxInt);
|
XMVECTOR vOverflow = _mm_cmpgt_ps(V, g_XMMaxInt);
|
||||||
@ -1443,7 +1475,7 @@ inline void XM_CALLCONV XMStoreInt3
|
|||||||
pDestination[1] = V.vector4_u32[1];
|
pDestination[1] = V.vector4_u32[1];
|
||||||
pDestination[2] = V.vector4_u32[2];
|
pDestination[2] = V.vector4_u32[2];
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
uint32x2_t VL = vget_low_u32(V);
|
uint32x2_t VL = vget_low_u32(vreinterpretq_u32_f32(V));
|
||||||
vst1_u32(pDestination, VL);
|
vst1_u32(pDestination, VL);
|
||||||
vst1q_lane_u32(pDestination + 2, *reinterpret_cast<const uint32x4_t*>(&V), 2);
|
vst1q_lane_u32(pDestination + 2, *reinterpret_cast<const uint32x4_t*>(&V), 2);
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
@ -1468,8 +1500,8 @@ inline void XM_CALLCONV XMStoreInt3A
|
|||||||
pDestination[1] = V.vector4_u32[1];
|
pDestination[1] = V.vector4_u32[1];
|
||||||
pDestination[2] = V.vector4_u32[2];
|
pDestination[2] = V.vector4_u32[2];
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
uint32x2_t VL = vget_low_u32(V);
|
uint32x2_t VL = vget_low_u32(vreinterpretq_u32_f32(V));
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
vst1_u32_ex(pDestination, VL, 64);
|
vst1_u32_ex(pDestination, VL, 64);
|
||||||
#else
|
#else
|
||||||
vst1_u32(pDestination, VL);
|
vst1_u32(pDestination, VL);
|
||||||
@ -1526,7 +1558,7 @@ inline void XM_CALLCONV XMStoreFloat3A
|
|||||||
pDestination->z = V.vector4_f32[2];
|
pDestination->z = V.vector4_f32[2];
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
float32x2_t VL = vget_low_f32(V);
|
float32x2_t VL = vget_low_f32(V);
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
vst1_f32_ex(reinterpret_cast<float*>(pDestination), VL, 64);
|
vst1_f32_ex(reinterpret_cast<float*>(pDestination), VL, 64);
|
||||||
#else
|
#else
|
||||||
vst1_f32(reinterpret_cast<float*>(pDestination), VL);
|
vst1_f32(reinterpret_cast<float*>(pDestination), VL);
|
||||||
@ -1634,7 +1666,7 @@ inline void XM_CALLCONV XMStoreInt4
|
|||||||
pDestination[2] = V.vector4_u32[2];
|
pDestination[2] = V.vector4_u32[2];
|
||||||
pDestination[3] = V.vector4_u32[3];
|
pDestination[3] = V.vector4_u32[3];
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
vst1q_u32(pDestination, V);
|
vst1q_u32(pDestination, vreinterpretq_u32_f32(V));
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
_mm_storeu_si128(reinterpret_cast<__m128i*>(pDestination), _mm_castps_si128(V));
|
_mm_storeu_si128(reinterpret_cast<__m128i*>(pDestination), _mm_castps_si128(V));
|
||||||
#endif
|
#endif
|
||||||
@ -1656,10 +1688,10 @@ inline void XM_CALLCONV XMStoreInt4A
|
|||||||
pDestination[2] = V.vector4_u32[2];
|
pDestination[2] = V.vector4_u32[2];
|
||||||
pDestination[3] = V.vector4_u32[3];
|
pDestination[3] = V.vector4_u32[3];
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
vst1q_u32_ex(pDestination, V, 128);
|
vst1q_u32_ex(pDestination, V, 128);
|
||||||
#else
|
#else
|
||||||
vst1q_u32(pDestination, V);
|
vst1q_u32(pDestination, vreinterpretq_u32_f32(V));
|
||||||
#endif
|
#endif
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
_mm_store_si128(reinterpret_cast<__m128i*>(pDestination), _mm_castps_si128(V));
|
_mm_store_si128(reinterpret_cast<__m128i*>(pDestination), _mm_castps_si128(V));
|
||||||
@ -1703,7 +1735,7 @@ inline void XM_CALLCONV XMStoreFloat4A
|
|||||||
pDestination->z = V.vector4_f32[2];
|
pDestination->z = V.vector4_f32[2];
|
||||||
pDestination->w = V.vector4_f32[3];
|
pDestination->w = V.vector4_f32[3];
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
vst1q_f32_ex(reinterpret_cast<float*>(pDestination), V, 128);
|
vst1q_f32_ex(reinterpret_cast<float*>(pDestination), V, 128);
|
||||||
#else
|
#else
|
||||||
vst1q_f32(reinterpret_cast<float*>(pDestination), V);
|
vst1q_f32(reinterpret_cast<float*>(pDestination), V);
|
||||||
@ -1913,7 +1945,7 @@ inline void XM_CALLCONV XMStoreFloat4x3A
|
|||||||
pDestination->m[3][2] = M.r[3].vector4_f32[2];
|
pDestination->m[3][2] = M.r[3].vector4_f32[2];
|
||||||
|
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
float32x4_t T1 = vextq_f32(M.r[0], M.r[1], 1);
|
float32x4_t T1 = vextq_f32(M.r[0], M.r[1], 1);
|
||||||
float32x4_t T2 = vbslq_f32(g_XMMask3, M.r[0], T1);
|
float32x4_t T2 = vbslq_f32(g_XMMask3, M.r[0], T1);
|
||||||
vst1q_f32_ex(&pDestination->m[0][0], T2, 128);
|
vst1q_f32_ex(&pDestination->m[0][0], T2, 128);
|
||||||
@ -2057,7 +2089,7 @@ inline void XM_CALLCONV XMStoreFloat3x4A
|
|||||||
float32x4x2_t T0 = vzipq_f32(P0.val[0], P1.val[0]);
|
float32x4x2_t T0 = vzipq_f32(P0.val[0], P1.val[0]);
|
||||||
float32x4x2_t T1 = vzipq_f32(P0.val[1], P1.val[1]);
|
float32x4x2_t T1 = vzipq_f32(P0.val[1], P1.val[1]);
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
vst1q_f32_ex(&pDestination->m[0][0], T0.val[0], 128);
|
vst1q_f32_ex(&pDestination->m[0][0], T0.val[0], 128);
|
||||||
vst1q_f32_ex(&pDestination->m[1][0], T0.val[1], 128);
|
vst1q_f32_ex(&pDestination->m[1][0], T0.val[1], 128);
|
||||||
vst1q_f32_ex(&pDestination->m[2][0], T1.val[0], 128);
|
vst1q_f32_ex(&pDestination->m[2][0], T1.val[0], 128);
|
||||||
@ -2166,7 +2198,7 @@ inline void XM_CALLCONV XMStoreFloat4x4A
|
|||||||
pDestination->m[3][3] = M.r[3].vector4_f32[3];
|
pDestination->m[3][3] = M.r[3].vector4_f32[3];
|
||||||
|
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||||
vst1q_f32_ex(reinterpret_cast<float*>(&pDestination->_11), M.r[0], 128);
|
vst1q_f32_ex(reinterpret_cast<float*>(&pDestination->_11), M.r[0], 128);
|
||||||
vst1q_f32_ex(reinterpret_cast<float*>(&pDestination->_21), M.r[1], 128);
|
vst1q_f32_ex(reinterpret_cast<float*>(&pDestination->_21), M.r[1], 128);
|
||||||
vst1q_f32_ex(reinterpret_cast<float*>(&pDestination->_31), M.r[2], 128);
|
vst1q_f32_ex(reinterpret_cast<float*>(&pDestination->_31), M.r[2], 128);
|
||||||
@ -1,10 +1,10 @@
|
|||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
// DirectXMathMatrix.inl -- SIMD C++ Math library
|
// DirectXMathMatrix.inl -- SIMD C++ Math library
|
||||||
//
|
//
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the MIT License.
|
// Licensed under the MIT License.
|
||||||
//
|
//
|
||||||
// http://go.microsoft.com/fwlink/?LinkID=615560
|
// https://go.microsoft.com/fwlink/?LinkID=615560
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@ -15,13 +15,13 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Comparison operations
|
// Comparison operations
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
#if !defined(_XM_NO_INTRINSICS_) && defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER)
|
#if !defined(_XM_NO_INTRINSICS_) && defined(_MSC_VER) && !defined(__INTEL_COMPILER)
|
||||||
#pragma float_control(push)
|
#pragma float_control(push)
|
||||||
#pragma float_control(precise, on)
|
#pragma float_control(precise, on)
|
||||||
#endif
|
#endif
|
||||||
@ -32,8 +32,9 @@ inline bool XM_CALLCONV XMMatrixIsNaN(FXMMATRIX M) noexcept
|
|||||||
#if defined(_XM_NO_INTRINSICS_)
|
#if defined(_XM_NO_INTRINSICS_)
|
||||||
size_t i = 16;
|
size_t i = 16;
|
||||||
auto pWork = reinterpret_cast<const uint32_t*>(&M.m[0][0]);
|
auto pWork = reinterpret_cast<const uint32_t*>(&M.m[0][0]);
|
||||||
do {
|
do
|
||||||
// Fetch value into integer unit
|
{
|
||||||
|
// Fetch value into integer unit
|
||||||
uint32_t uTest = pWork[0];
|
uint32_t uTest = pWork[0];
|
||||||
// Remove sign
|
// Remove sign
|
||||||
uTest &= 0x7FFFFFFFU;
|
uTest &= 0x7FFFFFFFU;
|
||||||
@ -44,27 +45,30 @@ inline bool XM_CALLCONV XMMatrixIsNaN(FXMMATRIX M) noexcept
|
|||||||
break; // NaN found
|
break; // NaN found
|
||||||
}
|
}
|
||||||
++pWork; // Next entry
|
++pWork; // Next entry
|
||||||
} while (--i);
|
}
|
||||||
|
while (--i);
|
||||||
return (i != 0); // i == 0 if nothing matched
|
return (i != 0); // i == 0 if nothing matched
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
// Load in registers
|
// Load in registers
|
||||||
XMVECTOR vX = M.r[0];
|
float32x4_t vX = M.r[0];
|
||||||
XMVECTOR vY = M.r[1];
|
float32x4_t vY = M.r[1];
|
||||||
XMVECTOR vZ = M.r[2];
|
float32x4_t vZ = M.r[2];
|
||||||
XMVECTOR vW = M.r[3];
|
float32x4_t vW = M.r[3];
|
||||||
// Test themselves to check for NaN
|
// Test themselves to check for NaN
|
||||||
vX = vmvnq_u32(vceqq_f32(vX, vX));
|
uint32x4_t xmask = vmvnq_u32(vceqq_f32(vX, vX));
|
||||||
vY = vmvnq_u32(vceqq_f32(vY, vY));
|
uint32x4_t ymask = vmvnq_u32(vceqq_f32(vY, vY));
|
||||||
vZ = vmvnq_u32(vceqq_f32(vZ, vZ));
|
uint32x4_t zmask = vmvnq_u32(vceqq_f32(vZ, vZ));
|
||||||
vW = vmvnq_u32(vceqq_f32(vW, vW));
|
uint32x4_t wmask = vmvnq_u32(vceqq_f32(vW, vW));
|
||||||
// Or all the results
|
// Or all the results
|
||||||
vX = vorrq_u32(vX, vZ);
|
xmask = vorrq_u32(xmask, zmask);
|
||||||
vY = vorrq_u32(vY, vW);
|
ymask = vorrq_u32(ymask, wmask);
|
||||||
vX = vorrq_u32(vX, vY);
|
xmask = vorrq_u32(xmask, ymask);
|
||||||
// If any tested true, return true
|
// If any tested true, return true
|
||||||
uint8x8x2_t vTemp = vzip_u8(vget_low_u8(vX), vget_high_u8(vX));
|
uint8x8x2_t vTemp = vzip_u8(
|
||||||
uint16x4x2_t vTemp2 = vzip_u16(vTemp.val[0], vTemp.val[1]);
|
vget_low_u8(vreinterpretq_u8_u32(xmask)),
|
||||||
uint32_t r = vget_lane_u32(vTemp2.val[1], 1);
|
vget_high_u8(vreinterpretq_u8_u32(xmask)));
|
||||||
|
uint16x4x2_t vTemp2 = vzip_u16(vreinterpret_u16_u8(vTemp.val[0]), vreinterpret_u16_u8(vTemp.val[1]));
|
||||||
|
uint32_t r = vget_lane_u32(vreinterpret_u32_u16(vTemp2.val[1]), 1);
|
||||||
return (r != 0);
|
return (r != 0);
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
// Load in registers
|
// Load in registers
|
||||||
@ -87,7 +91,7 @@ inline bool XM_CALLCONV XMMatrixIsNaN(FXMMATRIX M) noexcept
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(_XM_NO_INTRINSICS_) && defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER)
|
#if !defined(_XM_NO_INTRINSICS_) && defined(_MSC_VER) && !defined(__INTEL_COMPILER)
|
||||||
#pragma float_control(pop)
|
#pragma float_control(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -99,8 +103,9 @@ inline bool XM_CALLCONV XMMatrixIsInfinite(FXMMATRIX M) noexcept
|
|||||||
#if defined(_XM_NO_INTRINSICS_)
|
#if defined(_XM_NO_INTRINSICS_)
|
||||||
size_t i = 16;
|
size_t i = 16;
|
||||||
auto pWork = reinterpret_cast<const uint32_t*>(&M.m[0][0]);
|
auto pWork = reinterpret_cast<const uint32_t*>(&M.m[0][0]);
|
||||||
do {
|
do
|
||||||
// Fetch value into integer unit
|
{
|
||||||
|
// Fetch value into integer unit
|
||||||
uint32_t uTest = pWork[0];
|
uint32_t uTest = pWork[0];
|
||||||
// Remove sign
|
// Remove sign
|
||||||
uTest &= 0x7FFFFFFFU;
|
uTest &= 0x7FFFFFFFU;
|
||||||
@ -110,27 +115,35 @@ inline bool XM_CALLCONV XMMatrixIsInfinite(FXMMATRIX M) noexcept
|
|||||||
break; // INF found
|
break; // INF found
|
||||||
}
|
}
|
||||||
++pWork; // Next entry
|
++pWork; // Next entry
|
||||||
} while (--i);
|
}
|
||||||
|
while (--i);
|
||||||
return (i != 0); // i == 0 if nothing matched
|
return (i != 0); // i == 0 if nothing matched
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
|
// Load in registers
|
||||||
|
float32x4_t vX = M.r[0];
|
||||||
|
float32x4_t vY = M.r[1];
|
||||||
|
float32x4_t vZ = M.r[2];
|
||||||
|
float32x4_t vW = M.r[3];
|
||||||
// Mask off the sign bits
|
// Mask off the sign bits
|
||||||
XMVECTOR vTemp1 = vandq_u32(M.r[0], g_XMAbsMask);
|
vX = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(vX), g_XMAbsMask));
|
||||||
XMVECTOR vTemp2 = vandq_u32(M.r[1], g_XMAbsMask);
|
vY = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(vY), g_XMAbsMask));
|
||||||
XMVECTOR vTemp3 = vandq_u32(M.r[2], g_XMAbsMask);
|
vZ = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(vZ), g_XMAbsMask));
|
||||||
XMVECTOR vTemp4 = vandq_u32(M.r[3], g_XMAbsMask);
|
vW = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(vW), g_XMAbsMask));
|
||||||
// Compare to infinity
|
// Compare to infinity
|
||||||
vTemp1 = vceqq_f32(vTemp1, g_XMInfinity);
|
uint32x4_t xmask = vceqq_f32(vX, g_XMInfinity);
|
||||||
vTemp2 = vceqq_f32(vTemp2, g_XMInfinity);
|
uint32x4_t ymask = vceqq_f32(vY, g_XMInfinity);
|
||||||
vTemp3 = vceqq_f32(vTemp3, g_XMInfinity);
|
uint32x4_t zmask = vceqq_f32(vZ, g_XMInfinity);
|
||||||
vTemp4 = vceqq_f32(vTemp4, g_XMInfinity);
|
uint32x4_t wmask = vceqq_f32(vW, g_XMInfinity);
|
||||||
// Or the answers together
|
// Or the answers together
|
||||||
vTemp1 = vorrq_u32(vTemp1, vTemp2);
|
xmask = vorrq_u32(xmask, zmask);
|
||||||
vTemp3 = vorrq_u32(vTemp3, vTemp4);
|
ymask = vorrq_u32(ymask, wmask);
|
||||||
vTemp1 = vorrq_u32(vTemp1, vTemp3);
|
xmask = vorrq_u32(xmask, ymask);
|
||||||
// If any are infinity, the signs are true.
|
// If any tested true, return true
|
||||||
uint8x8x2_t vTemp = vzip_u8(vget_low_u8(vTemp1), vget_high_u8(vTemp1));
|
uint8x8x2_t vTemp = vzip_u8(
|
||||||
uint16x4x2_t vTemp5 = vzip_u16(vTemp.val[0], vTemp.val[1]);
|
vget_low_u8(vreinterpretq_u8_u32(xmask)),
|
||||||
uint32_t r = vget_lane_u32(vTemp5.val[1], 1);
|
vget_high_u8(vreinterpretq_u8_u32(xmask)));
|
||||||
|
uint16x4x2_t vTemp2 = vzip_u16(vreinterpret_u16_u8(vTemp.val[0]), vreinterpret_u16_u8(vTemp.val[1]));
|
||||||
|
uint32_t r = vget_lane_u32(vreinterpret_u32_u16(vTemp2.val[1]), 1);
|
||||||
return (r != 0);
|
return (r != 0);
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
// Mask off the sign bits
|
// Mask off the sign bits
|
||||||
@ -187,16 +200,16 @@ inline bool XM_CALLCONV XMMatrixIsIdentity(FXMMATRIX M) noexcept
|
|||||||
uOne |= uZero;
|
uOne |= uZero;
|
||||||
return (uOne == 0);
|
return (uOne == 0);
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
XMVECTOR vTemp1 = vceqq_f32(M.r[0], g_XMIdentityR0);
|
uint32x4_t xmask = vceqq_f32(M.r[0], g_XMIdentityR0);
|
||||||
XMVECTOR vTemp2 = vceqq_f32(M.r[1], g_XMIdentityR1);
|
uint32x4_t ymask = vceqq_f32(M.r[1], g_XMIdentityR1);
|
||||||
XMVECTOR vTemp3 = vceqq_f32(M.r[2], g_XMIdentityR2);
|
uint32x4_t zmask = vceqq_f32(M.r[2], g_XMIdentityR2);
|
||||||
XMVECTOR vTemp4 = vceqq_f32(M.r[3], g_XMIdentityR3);
|
uint32x4_t wmask = vceqq_f32(M.r[3], g_XMIdentityR3);
|
||||||
vTemp1 = vandq_u32(vTemp1, vTemp2);
|
xmask = vandq_u32(xmask, zmask);
|
||||||
vTemp3 = vandq_u32(vTemp3, vTemp4);
|
ymask = vandq_u32(ymask, wmask);
|
||||||
vTemp1 = vandq_u32(vTemp1, vTemp3);
|
xmask = vandq_u32(xmask, ymask);
|
||||||
uint8x8x2_t vTemp = vzip_u8(vget_low_u8(vTemp1), vget_high_u8(vTemp1));
|
uint8x8x2_t vTemp = vzip_u8(vget_low_u8(vreinterpretq_u8_u32(xmask)), vget_high_u8(vreinterpretq_u8_u32(xmask)));
|
||||||
uint16x4x2_t vTemp5 = vzip_u16(vTemp.val[0], vTemp.val[1]);
|
uint16x4x2_t vTemp2 = vzip_u16(vreinterpret_u16_u8(vTemp.val[0]), vreinterpret_u16_u8(vTemp.val[1]));
|
||||||
uint32_t r = vget_lane_u32(vTemp5.val[1], 1);
|
uint32_t r = vget_lane_u32(vreinterpret_u32_u16(vTemp2.val[1]), 1);
|
||||||
return (r == 0xFFFFFFFFU);
|
return (r == 0xFFFFFFFFU);
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
XMVECTOR vTemp1 = _mm_cmpeq_ps(M.r[0], g_XMIdentityR0);
|
XMVECTOR vTemp1 = _mm_cmpeq_ps(M.r[0], g_XMIdentityR0);
|
||||||
@ -265,10 +278,10 @@ inline XMMATRIX XM_CALLCONV XMMatrixMultiply
|
|||||||
float32x2_t VL = vget_low_f32(M1.r[0]);
|
float32x2_t VL = vget_low_f32(M1.r[0]);
|
||||||
float32x2_t VH = vget_high_f32(M1.r[0]);
|
float32x2_t VH = vget_high_f32(M1.r[0]);
|
||||||
// Perform the operation on the first row
|
// Perform the operation on the first row
|
||||||
XMVECTOR vX = vmulq_lane_f32(M2.r[0], VL, 0);
|
float32x4_t vX = vmulq_lane_f32(M2.r[0], VL, 0);
|
||||||
XMVECTOR vY = vmulq_lane_f32(M2.r[1], VL, 1);
|
float32x4_t vY = vmulq_lane_f32(M2.r[1], VL, 1);
|
||||||
XMVECTOR vZ = vmlaq_lane_f32(vX, M2.r[2], VH, 0);
|
float32x4_t vZ = vmlaq_lane_f32(vX, M2.r[2], VH, 0);
|
||||||
XMVECTOR vW = vmlaq_lane_f32(vY, M2.r[3], VH, 1);
|
float32x4_t vW = vmlaq_lane_f32(vY, M2.r[3], VH, 1);
|
||||||
mResult.r[0] = vaddq_f32(vZ, vW);
|
mResult.r[0] = vaddq_f32(vZ, vW);
|
||||||
// Repeat for the other 3 rows
|
// Repeat for the other 3 rows
|
||||||
VL = vget_low_f32(M1.r[1]);
|
VL = vget_low_f32(M1.r[1]);
|
||||||
@ -478,10 +491,10 @@ inline XMMATRIX XM_CALLCONV XMMatrixMultiplyTranspose
|
|||||||
float32x2_t VL = vget_low_f32(M1.r[0]);
|
float32x2_t VL = vget_low_f32(M1.r[0]);
|
||||||
float32x2_t VH = vget_high_f32(M1.r[0]);
|
float32x2_t VH = vget_high_f32(M1.r[0]);
|
||||||
// Perform the operation on the first row
|
// Perform the operation on the first row
|
||||||
XMVECTOR vX = vmulq_lane_f32(M2.r[0], VL, 0);
|
float32x4_t vX = vmulq_lane_f32(M2.r[0], VL, 0);
|
||||||
XMVECTOR vY = vmulq_lane_f32(M2.r[1], VL, 1);
|
float32x4_t vY = vmulq_lane_f32(M2.r[1], VL, 1);
|
||||||
XMVECTOR vZ = vmlaq_lane_f32(vX, M2.r[2], VH, 0);
|
float32x4_t vZ = vmlaq_lane_f32(vX, M2.r[2], VH, 0);
|
||||||
XMVECTOR vW = vmlaq_lane_f32(vY, M2.r[3], VH, 1);
|
float32x4_t vW = vmlaq_lane_f32(vY, M2.r[3], VH, 1);
|
||||||
float32x4_t r0 = vaddq_f32(vZ, vW);
|
float32x4_t r0 = vaddq_f32(vZ, vW);
|
||||||
// Repeat for the other 3 rows
|
// Repeat for the other 3 rows
|
||||||
VL = vget_low_f32(M1.r[1]);
|
VL = vget_low_f32(M1.r[1]);
|
||||||
@ -1403,9 +1416,9 @@ inline XMMATRIX XM_CALLCONV XMMatrixScalingFromVector(FXMVECTOR Scale) noexcept
|
|||||||
|
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vandq_u32(Scale, g_XMMaskX);
|
M.r[0] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(Scale), g_XMMaskX));
|
||||||
M.r[1] = vandq_u32(Scale, g_XMMaskY);
|
M.r[1] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(Scale), g_XMMaskY));
|
||||||
M.r[2] = vandq_u32(Scale, g_XMMaskZ);
|
M.r[2] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(Scale), g_XMMaskZ));
|
||||||
M.r[3] = g_XMIdentityR3.v;
|
M.r[3] = g_XMIdentityR3.v;
|
||||||
return M;
|
return M;
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
@ -1455,12 +1468,12 @@ inline XMMATRIX XM_CALLCONV XMMatrixRotationX(float Angle) noexcept
|
|||||||
float fCosAngle;
|
float fCosAngle;
|
||||||
XMScalarSinCos(&fSinAngle, &fCosAngle, Angle);
|
XMScalarSinCos(&fSinAngle, &fCosAngle, Angle);
|
||||||
|
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
|
|
||||||
XMVECTOR T1 = vsetq_lane_f32(fCosAngle, Zero, 1);
|
float32x4_t T1 = vsetq_lane_f32(fCosAngle, Zero, 1);
|
||||||
T1 = vsetq_lane_f32(fSinAngle, T1, 2);
|
T1 = vsetq_lane_f32(fSinAngle, T1, 2);
|
||||||
|
|
||||||
XMVECTOR T2 = vsetq_lane_f32(-fSinAngle, Zero, 1);
|
float32x4_t T2 = vsetq_lane_f32(-fSinAngle, Zero, 1);
|
||||||
T2 = vsetq_lane_f32(fCosAngle, T2, 2);
|
T2 = vsetq_lane_f32(fCosAngle, T2, 2);
|
||||||
|
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
@ -1528,12 +1541,12 @@ inline XMMATRIX XM_CALLCONV XMMatrixRotationY(float Angle) noexcept
|
|||||||
float fCosAngle;
|
float fCosAngle;
|
||||||
XMScalarSinCos(&fSinAngle, &fCosAngle, Angle);
|
XMScalarSinCos(&fSinAngle, &fCosAngle, Angle);
|
||||||
|
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
|
|
||||||
XMVECTOR T0 = vsetq_lane_f32(fCosAngle, Zero, 0);
|
float32x4_t T0 = vsetq_lane_f32(fCosAngle, Zero, 0);
|
||||||
T0 = vsetq_lane_f32(-fSinAngle, T0, 2);
|
T0 = vsetq_lane_f32(-fSinAngle, T0, 2);
|
||||||
|
|
||||||
XMVECTOR T2 = vsetq_lane_f32(fSinAngle, Zero, 0);
|
float32x4_t T2 = vsetq_lane_f32(fSinAngle, Zero, 0);
|
||||||
T2 = vsetq_lane_f32(fCosAngle, T2, 2);
|
T2 = vsetq_lane_f32(fCosAngle, T2, 2);
|
||||||
|
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
@ -1601,12 +1614,12 @@ inline XMMATRIX XM_CALLCONV XMMatrixRotationZ(float Angle) noexcept
|
|||||||
float fCosAngle;
|
float fCosAngle;
|
||||||
XMScalarSinCos(&fSinAngle, &fCosAngle, Angle);
|
XMScalarSinCos(&fSinAngle, &fCosAngle, Angle);
|
||||||
|
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
|
|
||||||
XMVECTOR T0 = vsetq_lane_f32(fCosAngle, Zero, 0);
|
float32x4_t T0 = vsetq_lane_f32(fCosAngle, Zero, 0);
|
||||||
T0 = vsetq_lane_f32(fSinAngle, T0, 1);
|
T0 = vsetq_lane_f32(fSinAngle, T0, 1);
|
||||||
|
|
||||||
XMVECTOR T1 = vsetq_lane_f32(-fSinAngle, Zero, 0);
|
float32x4_t T1 = vsetq_lane_f32(-fSinAngle, Zero, 0);
|
||||||
T1 = vsetq_lane_f32(fCosAngle, T1, 1);
|
T1 = vsetq_lane_f32(fCosAngle, T1, 1);
|
||||||
|
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
@ -1646,8 +1659,41 @@ inline XMMATRIX XM_CALLCONV XMMatrixRotationRollPitchYaw
|
|||||||
float Roll
|
float Roll
|
||||||
) noexcept
|
) noexcept
|
||||||
{
|
{
|
||||||
|
#if defined(_XM_NO_INTRINSICS_)
|
||||||
|
float cp = cosf(Pitch);
|
||||||
|
float sp = sinf(Pitch);
|
||||||
|
|
||||||
|
float cy = cosf(Yaw);
|
||||||
|
float sy = sinf(Yaw);
|
||||||
|
|
||||||
|
float cr = cosf(Roll);
|
||||||
|
float sr = sinf(Roll);
|
||||||
|
|
||||||
|
XMMATRIX M;
|
||||||
|
M.m[0][0] = cr * cy + sr * sp * sy;
|
||||||
|
M.m[0][1] = sr * cp;
|
||||||
|
M.m[0][2] = sr * sp * cy - cr * sy;
|
||||||
|
M.m[0][3] = 0.0f;
|
||||||
|
|
||||||
|
M.m[1][0] = cr * sp * sy - sr * cy;
|
||||||
|
M.m[1][1] = cr * cp;
|
||||||
|
M.m[1][2] = sr * sy + cr * sp * cy;
|
||||||
|
M.m[1][3] = 0.0f;
|
||||||
|
|
||||||
|
M.m[2][0] = cp * sy;
|
||||||
|
M.m[2][1] = -sp;
|
||||||
|
M.m[2][2] = cp * cy;
|
||||||
|
M.m[2][3] = 0.0f;
|
||||||
|
|
||||||
|
M.m[3][0] = 0.0f;
|
||||||
|
M.m[3][1] = 0.0f;
|
||||||
|
M.m[3][2] = 0.0f;
|
||||||
|
M.m[3][3] = 1.0f;
|
||||||
|
return M;
|
||||||
|
#else
|
||||||
XMVECTOR Angles = XMVectorSet(Pitch, Yaw, Roll, 0.0f);
|
XMVECTOR Angles = XMVectorSet(Pitch, Yaw, Roll, 0.0f);
|
||||||
return XMMatrixRotationRollPitchYawFromVector(Angles);
|
return XMMatrixRotationRollPitchYawFromVector(Angles);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -1657,8 +1703,69 @@ inline XMMATRIX XM_CALLCONV XMMatrixRotationRollPitchYawFromVector
|
|||||||
FXMVECTOR Angles // <Pitch, Yaw, Roll, undefined>
|
FXMVECTOR Angles // <Pitch, Yaw, Roll, undefined>
|
||||||
) noexcept
|
) noexcept
|
||||||
{
|
{
|
||||||
XMVECTOR Q = XMQuaternionRotationRollPitchYawFromVector(Angles);
|
#if defined(_XM_NO_INTRINSICS_)
|
||||||
return XMMatrixRotationQuaternion(Q);
|
float cp = cosf(Angles.vector4_f32[0]);
|
||||||
|
float sp = sinf(Angles.vector4_f32[0]);
|
||||||
|
|
||||||
|
float cy = cosf(Angles.vector4_f32[1]);
|
||||||
|
float sy = sinf(Angles.vector4_f32[1]);
|
||||||
|
|
||||||
|
float cr = cosf(Angles.vector4_f32[2]);
|
||||||
|
float sr = sinf(Angles.vector4_f32[2]);
|
||||||
|
|
||||||
|
XMMATRIX M;
|
||||||
|
M.m[0][0] = cr * cy + sr * sp * sy;
|
||||||
|
M.m[0][1] = sr * cp;
|
||||||
|
M.m[0][2] = sr * sp * cy - cr * sy;
|
||||||
|
M.m[0][3] = 0.0f;
|
||||||
|
|
||||||
|
M.m[1][0] = cr * sp * sy - sr * cy;
|
||||||
|
M.m[1][1] = cr * cp;
|
||||||
|
M.m[1][2] = sr * sy + cr * sp * cy;
|
||||||
|
M.m[1][3] = 0.0f;
|
||||||
|
|
||||||
|
M.m[2][0] = cp * sy;
|
||||||
|
M.m[2][1] = -sp;
|
||||||
|
M.m[2][2] = cp * cy;
|
||||||
|
M.m[2][3] = 0.0f;
|
||||||
|
|
||||||
|
M.m[3][0] = 0.0f;
|
||||||
|
M.m[3][1] = 0.0f;
|
||||||
|
M.m[3][2] = 0.0f;
|
||||||
|
M.m[3][3] = 1.0f;
|
||||||
|
return M;
|
||||||
|
#else
|
||||||
|
static const XMVECTORF32 Sign = { { { 1.0f, -1.0f, -1.0f, 1.0f } } };
|
||||||
|
|
||||||
|
XMVECTOR SinAngles, CosAngles;
|
||||||
|
XMVectorSinCos(&SinAngles, &CosAngles, Angles);
|
||||||
|
|
||||||
|
XMVECTOR P0 = XMVectorPermute<XM_PERMUTE_1X, XM_PERMUTE_0Z, XM_PERMUTE_1Z, XM_PERMUTE_1X>(SinAngles, CosAngles);
|
||||||
|
XMVECTOR Y0 = XMVectorPermute<XM_PERMUTE_0Y, XM_PERMUTE_1X, XM_PERMUTE_1X, XM_PERMUTE_1Y>(SinAngles, CosAngles);
|
||||||
|
XMVECTOR P1 = XMVectorPermute<XM_PERMUTE_1Z, XM_PERMUTE_0Z, XM_PERMUTE_1Z, XM_PERMUTE_0Z>(SinAngles, CosAngles);
|
||||||
|
XMVECTOR Y1 = XMVectorPermute<XM_PERMUTE_1Y, XM_PERMUTE_1Y, XM_PERMUTE_0Y, XM_PERMUTE_0Y>(SinAngles, CosAngles);
|
||||||
|
XMVECTOR P2 = XMVectorPermute<XM_PERMUTE_0Z, XM_PERMUTE_1Z, XM_PERMUTE_0Z, XM_PERMUTE_1Z>(SinAngles, CosAngles);
|
||||||
|
XMVECTOR P3 = XMVectorPermute<XM_PERMUTE_0Y, XM_PERMUTE_0Y, XM_PERMUTE_1Y, XM_PERMUTE_1Y>(SinAngles, CosAngles);
|
||||||
|
XMVECTOR Y2 = XMVectorSplatX(SinAngles);
|
||||||
|
XMVECTOR NS = XMVectorNegate(SinAngles);
|
||||||
|
|
||||||
|
XMVECTOR Q0 = XMVectorMultiply(P0, Y0);
|
||||||
|
XMVECTOR Q1 = XMVectorMultiply(P1, Sign.v);
|
||||||
|
Q1 = XMVectorMultiply(Q1, Y1);
|
||||||
|
XMVECTOR Q2 = XMVectorMultiply(P2, Y2);
|
||||||
|
Q2 = XMVectorMultiplyAdd(Q2, P3, Q1);
|
||||||
|
|
||||||
|
XMVECTOR V0 = XMVectorPermute<XM_PERMUTE_1X, XM_PERMUTE_0Y, XM_PERMUTE_1Z, XM_PERMUTE_0W>(Q0, Q2);
|
||||||
|
XMVECTOR V1 = XMVectorPermute<XM_PERMUTE_1Y, XM_PERMUTE_0Z, XM_PERMUTE_1W, XM_PERMUTE_0W>(Q0, Q2);
|
||||||
|
XMVECTOR V2 = XMVectorPermute<XM_PERMUTE_0X, XM_PERMUTE_1X, XM_PERMUTE_0W, XM_PERMUTE_0W>(Q0, NS);
|
||||||
|
|
||||||
|
XMMATRIX M;
|
||||||
|
M.r[0] = XMVectorSelect(g_XMZero, V0, g_XMSelect1110.v);
|
||||||
|
M.r[1] = XMVectorSelect(g_XMZero, V1, g_XMSelect1110.v);
|
||||||
|
M.r[2] = XMVectorSelect(g_XMZero, V2, g_XMSelect1110.v);
|
||||||
|
M.r[3] = g_XMIdentityR3;
|
||||||
|
return M;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -1770,8 +1877,42 @@ inline XMMATRIX XM_CALLCONV XMMatrixRotationAxis
|
|||||||
|
|
||||||
inline XMMATRIX XM_CALLCONV XMMatrixRotationQuaternion(FXMVECTOR Quaternion) noexcept
|
inline XMMATRIX XM_CALLCONV XMMatrixRotationQuaternion(FXMVECTOR Quaternion) noexcept
|
||||||
{
|
{
|
||||||
#if defined(_XM_NO_INTRINSICS_) || defined(_XM_ARM_NEON_INTRINSICS_)
|
#if defined(_XM_NO_INTRINSICS_)
|
||||||
|
|
||||||
|
float qx = Quaternion.vector4_f32[0];
|
||||||
|
float qxx = qx * qx;
|
||||||
|
|
||||||
|
float qy = Quaternion.vector4_f32[1];
|
||||||
|
float qyy = qy * qy;
|
||||||
|
|
||||||
|
float qz = Quaternion.vector4_f32[2];
|
||||||
|
float qzz = qz * qz;
|
||||||
|
|
||||||
|
float qw = Quaternion.vector4_f32[3];
|
||||||
|
|
||||||
|
XMMATRIX M;
|
||||||
|
M.m[0][0] = 1.f - 2.f * qyy - 2.f * qzz;
|
||||||
|
M.m[0][1] = 2.f * qx * qy + 2.f * qz * qw;
|
||||||
|
M.m[0][2] = 2.f * qx * qz - 2.f * qy * qw;
|
||||||
|
M.m[0][3] = 0.f;
|
||||||
|
|
||||||
|
M.m[1][0] = 2.f * qx * qy - 2.f * qz * qw;
|
||||||
|
M.m[1][1] = 1.f - 2.f * qxx - 2.f * qzz;
|
||||||
|
M.m[1][2] = 2.f * qy * qz + 2.f * qx * qw;
|
||||||
|
M.m[1][3] = 0.f;
|
||||||
|
|
||||||
|
M.m[2][0] = 2.f * qx * qz + 2.f * qy * qw;
|
||||||
|
M.m[2][1] = 2.f * qy * qz - 2.f * qx * qw;
|
||||||
|
M.m[2][2] = 1.f - 2.f * qxx - 2.f * qyy;
|
||||||
|
M.m[2][3] = 0.f;
|
||||||
|
|
||||||
|
M.m[3][0] = 0.f;
|
||||||
|
M.m[3][1] = 0.f;
|
||||||
|
M.m[3][2] = 0.f;
|
||||||
|
M.m[3][3] = 1.0f;
|
||||||
|
return M;
|
||||||
|
|
||||||
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
static const XMVECTORF32 Constant1110 = { { { 1.0f, 1.0f, 1.0f, 0.0f } } };
|
static const XMVECTORF32 Constant1110 = { { { 1.0f, 1.0f, 1.0f, 0.0f } } };
|
||||||
|
|
||||||
XMVECTOR Q0 = XMVectorAdd(Quaternion, Quaternion);
|
XMVECTOR Q0 = XMVectorAdd(Quaternion, Quaternion);
|
||||||
@ -2166,7 +2307,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveLH
|
|||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
float TwoNearZ = NearZ + NearZ;
|
float TwoNearZ = NearZ + NearZ;
|
||||||
float fRange = FarZ / (FarZ - NearZ);
|
float fRange = FarZ / (FarZ - NearZ);
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vsetq_lane_f32(TwoNearZ / ViewWidth, Zero, 0);
|
M.r[0] = vsetq_lane_f32(TwoNearZ / ViewWidth, Zero, 0);
|
||||||
M.r[1] = vsetq_lane_f32(TwoNearZ / ViewHeight, Zero, 1);
|
M.r[1] = vsetq_lane_f32(TwoNearZ / ViewHeight, Zero, 1);
|
||||||
@ -2253,7 +2394,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveRH
|
|||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
float TwoNearZ = NearZ + NearZ;
|
float TwoNearZ = NearZ + NearZ;
|
||||||
float fRange = FarZ / (NearZ - FarZ);
|
float fRange = FarZ / (NearZ - FarZ);
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
|
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vsetq_lane_f32(TwoNearZ / ViewWidth, Zero, 0);
|
M.r[0] = vsetq_lane_f32(TwoNearZ / ViewWidth, Zero, 0);
|
||||||
@ -2351,7 +2492,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveFovLH
|
|||||||
float fRange = FarZ / (FarZ - NearZ);
|
float fRange = FarZ / (FarZ - NearZ);
|
||||||
float Height = CosFov / SinFov;
|
float Height = CosFov / SinFov;
|
||||||
float Width = Height / AspectRatio;
|
float Width = Height / AspectRatio;
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
|
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vsetq_lane_f32(Width, Zero, 0);
|
M.r[0] = vsetq_lane_f32(Width, Zero, 0);
|
||||||
@ -2378,10 +2519,10 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveFovLH
|
|||||||
XMVECTOR vTemp = _mm_setzero_ps();
|
XMVECTOR vTemp = _mm_setzero_ps();
|
||||||
// Copy x only
|
// Copy x only
|
||||||
vTemp = _mm_move_ss(vTemp, vValues);
|
vTemp = _mm_move_ss(vTemp, vValues);
|
||||||
// CosFov / SinFov,0,0,0
|
// Height / AspectRatio,0,0,0
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vTemp;
|
M.r[0] = vTemp;
|
||||||
// 0,Height / AspectRatio,0,0
|
// 0,Height,0,0
|
||||||
vTemp = vValues;
|
vTemp = vValues;
|
||||||
vTemp = _mm_and_ps(vTemp, g_XMMaskY);
|
vTemp = _mm_and_ps(vTemp, g_XMMaskY);
|
||||||
M.r[1] = vTemp;
|
M.r[1] = vTemp;
|
||||||
@ -2452,7 +2593,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveFovRH
|
|||||||
float fRange = FarZ / (NearZ - FarZ);
|
float fRange = FarZ / (NearZ - FarZ);
|
||||||
float Height = CosFov / SinFov;
|
float Height = CosFov / SinFov;
|
||||||
float Width = Height / AspectRatio;
|
float Width = Height / AspectRatio;
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
|
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vsetq_lane_f32(Width, Zero, 0);
|
M.r[0] = vsetq_lane_f32(Width, Zero, 0);
|
||||||
@ -2478,10 +2619,10 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveFovRH
|
|||||||
XMVECTOR vTemp = _mm_setzero_ps();
|
XMVECTOR vTemp = _mm_setzero_ps();
|
||||||
// Copy x only
|
// Copy x only
|
||||||
vTemp = _mm_move_ss(vTemp, vValues);
|
vTemp = _mm_move_ss(vTemp, vValues);
|
||||||
// CosFov / SinFov,0,0,0
|
// Height / AspectRatio,0,0,0
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vTemp;
|
M.r[0] = vTemp;
|
||||||
// 0,Height / AspectRatio,0,0
|
// 0,Height,0,0
|
||||||
vTemp = vValues;
|
vTemp = vValues;
|
||||||
vTemp = _mm_and_ps(vTemp, g_XMMaskY);
|
vTemp = _mm_and_ps(vTemp, g_XMMaskY);
|
||||||
M.r[1] = vTemp;
|
M.r[1] = vTemp;
|
||||||
@ -2549,7 +2690,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveOffCenterLH
|
|||||||
float ReciprocalWidth = 1.0f / (ViewRight - ViewLeft);
|
float ReciprocalWidth = 1.0f / (ViewRight - ViewLeft);
|
||||||
float ReciprocalHeight = 1.0f / (ViewTop - ViewBottom);
|
float ReciprocalHeight = 1.0f / (ViewTop - ViewBottom);
|
||||||
float fRange = FarZ / (FarZ - NearZ);
|
float fRange = FarZ / (FarZ - NearZ);
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
|
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vsetq_lane_f32(TwoNearZ * ReciprocalWidth, Zero, 0);
|
M.r[0] = vsetq_lane_f32(TwoNearZ * ReciprocalWidth, Zero, 0);
|
||||||
@ -2647,7 +2788,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveOffCenterRH
|
|||||||
float ReciprocalWidth = 1.0f / (ViewRight - ViewLeft);
|
float ReciprocalWidth = 1.0f / (ViewRight - ViewLeft);
|
||||||
float ReciprocalHeight = 1.0f / (ViewTop - ViewBottom);
|
float ReciprocalHeight = 1.0f / (ViewTop - ViewBottom);
|
||||||
float fRange = FarZ / (NearZ - FarZ);
|
float fRange = FarZ / (NearZ - FarZ);
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
|
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vsetq_lane_f32(TwoNearZ * ReciprocalWidth, Zero, 0);
|
M.r[0] = vsetq_lane_f32(TwoNearZ * ReciprocalWidth, Zero, 0);
|
||||||
@ -2737,7 +2878,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixOrthographicLH
|
|||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
float fRange = 1.0f / (FarZ - NearZ);
|
float fRange = 1.0f / (FarZ - NearZ);
|
||||||
|
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vsetq_lane_f32(2.0f / ViewWidth, Zero, 0);
|
M.r[0] = vsetq_lane_f32(2.0f / ViewWidth, Zero, 0);
|
||||||
M.r[1] = vsetq_lane_f32(2.0f / ViewHeight, Zero, 1);
|
M.r[1] = vsetq_lane_f32(2.0f / ViewHeight, Zero, 1);
|
||||||
@ -2821,7 +2962,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixOrthographicRH
|
|||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
float fRange = 1.0f / (NearZ - FarZ);
|
float fRange = 1.0f / (NearZ - FarZ);
|
||||||
|
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vsetq_lane_f32(2.0f / ViewWidth, Zero, 0);
|
M.r[0] = vsetq_lane_f32(2.0f / ViewWidth, Zero, 0);
|
||||||
M.r[1] = vsetq_lane_f32(2.0f / ViewHeight, Zero, 1);
|
M.r[1] = vsetq_lane_f32(2.0f / ViewHeight, Zero, 1);
|
||||||
@ -2910,7 +3051,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixOrthographicOffCenterLH
|
|||||||
float ReciprocalWidth = 1.0f / (ViewRight - ViewLeft);
|
float ReciprocalWidth = 1.0f / (ViewRight - ViewLeft);
|
||||||
float ReciprocalHeight = 1.0f / (ViewTop - ViewBottom);
|
float ReciprocalHeight = 1.0f / (ViewTop - ViewBottom);
|
||||||
float fRange = 1.0f / (FarZ - NearZ);
|
float fRange = 1.0f / (FarZ - NearZ);
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vsetq_lane_f32(ReciprocalWidth + ReciprocalWidth, Zero, 0);
|
M.r[0] = vsetq_lane_f32(ReciprocalWidth + ReciprocalWidth, Zero, 0);
|
||||||
M.r[1] = vsetq_lane_f32(ReciprocalHeight + ReciprocalHeight, Zero, 1);
|
M.r[1] = vsetq_lane_f32(ReciprocalHeight + ReciprocalHeight, Zero, 1);
|
||||||
@ -3010,7 +3151,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixOrthographicOffCenterRH
|
|||||||
float ReciprocalWidth = 1.0f / (ViewRight - ViewLeft);
|
float ReciprocalWidth = 1.0f / (ViewRight - ViewLeft);
|
||||||
float ReciprocalHeight = 1.0f / (ViewTop - ViewBottom);
|
float ReciprocalHeight = 1.0f / (ViewTop - ViewBottom);
|
||||||
float fRange = 1.0f / (NearZ - FarZ);
|
float fRange = 1.0f / (NearZ - FarZ);
|
||||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
const float32x4_t Zero = vdupq_n_f32(0);
|
||||||
XMMATRIX M;
|
XMMATRIX M;
|
||||||
M.r[0] = vsetq_lane_f32(ReciprocalWidth + ReciprocalWidth, Zero, 0);
|
M.r[0] = vsetq_lane_f32(ReciprocalWidth + ReciprocalWidth, Zero, 0);
|
||||||
M.r[1] = vsetq_lane_f32(ReciprocalHeight + ReciprocalHeight, Zero, 1);
|
M.r[1] = vsetq_lane_f32(ReciprocalHeight + ReciprocalHeight, Zero, 1);
|
||||||
@ -3072,7 +3213,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixOrthographicOffCenterRH
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
inline XMMATRIX::XMMATRIX
|
inline XMMATRIX::XMMATRIX
|
||||||
(
|
(
|
||||||
@ -3164,7 +3305,7 @@ inline XMMATRIX& XMMATRIX::operator/= (float S) noexcept
|
|||||||
r[3] = XMVectorDivide(r[3], vS);
|
r[3] = XMVectorDivide(r[3], vS);
|
||||||
return *this;
|
return *this;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
#if defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || __aarch64__
|
#if defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || __aarch64__
|
||||||
float32x4_t vS = vdupq_n_f32(S);
|
float32x4_t vS = vdupq_n_f32(S);
|
||||||
r[0] = vdivq_f32(r[0], vS);
|
r[0] = vdivq_f32(r[0], vS);
|
||||||
r[1] = vdivq_f32(r[1], vS);
|
r[1] = vdivq_f32(r[1], vS);
|
||||||
@ -3178,7 +3319,7 @@ inline XMMATRIX& XMMATRIX::operator/= (float S) noexcept
|
|||||||
R0 = vmul_f32(S0, R0);
|
R0 = vmul_f32(S0, R0);
|
||||||
S0 = vrecps_f32(R0, vS);
|
S0 = vrecps_f32(R0, vS);
|
||||||
R0 = vmul_f32(S0, R0);
|
R0 = vmul_f32(S0, R0);
|
||||||
float32x4_t Reciprocal = vcombine_u32(R0, R0);
|
float32x4_t Reciprocal = vcombine_f32(R0, R0);
|
||||||
r[0] = vmulq_f32(r[0], Reciprocal);
|
r[0] = vmulq_f32(r[0], Reciprocal);
|
||||||
r[1] = vmulq_f32(r[1], Reciprocal);
|
r[1] = vmulq_f32(r[1], Reciprocal);
|
||||||
r[2] = vmulq_f32(r[2], Reciprocal);
|
r[2] = vmulq_f32(r[2], Reciprocal);
|
||||||
@ -3251,7 +3392,7 @@ inline XMMATRIX XMMATRIX::operator/ (float S) const noexcept
|
|||||||
R.r[3] = XMVectorDivide(r[3], vS);
|
R.r[3] = XMVectorDivide(r[3], vS);
|
||||||
return R;
|
return R;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
#if defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || __aarch64__
|
#if defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || __aarch64__
|
||||||
float32x4_t vS = vdupq_n_f32(S);
|
float32x4_t vS = vdupq_n_f32(S);
|
||||||
XMMATRIX R;
|
XMMATRIX R;
|
||||||
R.r[0] = vdivq_f32(r[0], vS);
|
R.r[0] = vdivq_f32(r[0], vS);
|
||||||
@ -3266,7 +3407,7 @@ inline XMMATRIX XMMATRIX::operator/ (float S) const noexcept
|
|||||||
R0 = vmul_f32(S0, R0);
|
R0 = vmul_f32(S0, R0);
|
||||||
S0 = vrecps_f32(R0, vS);
|
S0 = vrecps_f32(R0, vS);
|
||||||
R0 = vmul_f32(S0, R0);
|
R0 = vmul_f32(S0, R0);
|
||||||
float32x4_t Reciprocal = vcombine_u32(R0, R0);
|
float32x4_t Reciprocal = vcombine_f32(R0, R0);
|
||||||
XMMATRIX R;
|
XMMATRIX R;
|
||||||
R.r[0] = vmulq_f32(r[0], Reciprocal);
|
R.r[0] = vmulq_f32(r[0], Reciprocal);
|
||||||
R.r[1] = vmulq_f32(r[1], Reciprocal);
|
R.r[1] = vmulq_f32(r[1], Reciprocal);
|
||||||
@ -3291,7 +3432,7 @@ inline XMMATRIX XM_CALLCONV operator*
|
|||||||
(
|
(
|
||||||
float S,
|
float S,
|
||||||
FXMMATRIX M
|
FXMMATRIX M
|
||||||
) noexcept
|
) noexcept
|
||||||
{
|
{
|
||||||
XMMATRIX R;
|
XMMATRIX R;
|
||||||
R.r[0] = XMVectorScale(M.r[0], S);
|
R.r[0] = XMVectorScale(M.r[0], S);
|
||||||
@ -3307,7 +3448,7 @@ inline XMMATRIX XM_CALLCONV operator*
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
_Use_decl_annotations_
|
_Use_decl_annotations_
|
||||||
inline XMFLOAT3X3::XMFLOAT3X3(const float* pArray) noexcept
|
inline XMFLOAT3X3::XMFLOAT3X3(const float* pArray) noexcept
|
||||||
{
|
{
|
||||||
@ -3327,7 +3468,7 @@ inline XMFLOAT3X3::XMFLOAT3X3(const float* pArray) noexcept
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
_Use_decl_annotations_
|
_Use_decl_annotations_
|
||||||
inline XMFLOAT4X3::XMFLOAT4X3(const float* pArray) noexcept
|
inline XMFLOAT4X3::XMFLOAT4X3(const float* pArray) noexcept
|
||||||
{
|
{
|
||||||
@ -3384,7 +3525,7 @@ inline XMFLOAT3X4::XMFLOAT3X4(const float* pArray) noexcept
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
_Use_decl_annotations_
|
_Use_decl_annotations_
|
||||||
inline XMFLOAT4X4::XMFLOAT4X4(const float* pArray) noexcept
|
inline XMFLOAT4X4::XMFLOAT4X4(const float* pArray) noexcept
|
||||||
{
|
{
|
||||||
@ -1,10 +1,10 @@
|
|||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
// DirectXMathMisc.inl -- SIMD C++ Math library
|
// DirectXMathMisc.inl -- SIMD C++ Math library
|
||||||
//
|
//
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the MIT License.
|
// Licensed under the MIT License.
|
||||||
//
|
//
|
||||||
// http://go.microsoft.com/fwlink/?LinkID=615560
|
// https://go.microsoft.com/fwlink/?LinkID=615560
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@ -15,11 +15,11 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Comparison operations
|
// Comparison operations
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
inline bool XM_CALLCONV XMQuaternionEqual
|
inline bool XM_CALLCONV XMQuaternionEqual
|
||||||
(
|
(
|
||||||
@ -120,12 +120,12 @@ inline XMVECTOR XM_CALLCONV XMQuaternionMultiply
|
|||||||
vResult = vmlaq_f32(vResult, Q2X, ControlWZYX);
|
vResult = vmlaq_f32(vResult, Q2X, ControlWZYX);
|
||||||
|
|
||||||
// Mul by Q1ZWXY
|
// Mul by Q1ZWXY
|
||||||
vTemp = vrev64q_u32(vTemp);
|
vTemp = vreinterpretq_f32_u32(vrev64q_u32(vreinterpretq_u32_f32(vTemp)));
|
||||||
Q2Y = vmulq_f32(Q2Y, vTemp);
|
Q2Y = vmulq_f32(Q2Y, vTemp);
|
||||||
vResult = vmlaq_f32(vResult, Q2Y, ControlZWXY);
|
vResult = vmlaq_f32(vResult, Q2Y, ControlZWXY);
|
||||||
|
|
||||||
// Mul by Q1YXWZ
|
// Mul by Q1YXWZ
|
||||||
vTemp = vrev64q_u32(vTemp);
|
vTemp = vreinterpretq_f32_u32(vrev64q_u32(vreinterpretq_u32_f32(vTemp)));
|
||||||
vTemp = vcombine_f32(vget_high_f32(vTemp), vget_low_f32(vTemp));
|
vTemp = vcombine_f32(vget_high_f32(vTemp), vget_low_f32(vTemp));
|
||||||
Q2Z = vmulq_f32(Q2Z, vTemp);
|
Q2Z = vmulq_f32(Q2Z, vTemp);
|
||||||
vResult = vmlaq_f32(vResult, Q2Z, ControlYXWZ);
|
vResult = vmlaq_f32(vResult, Q2Z, ControlYXWZ);
|
||||||
@ -228,8 +228,6 @@ inline XMVECTOR XM_CALLCONV XMQuaternionConjugate(FXMVECTOR Q) noexcept
|
|||||||
|
|
||||||
inline XMVECTOR XM_CALLCONV XMQuaternionInverse(FXMVECTOR Q) noexcept
|
inline XMVECTOR XM_CALLCONV XMQuaternionInverse(FXMVECTOR Q) noexcept
|
||||||
{
|
{
|
||||||
const XMVECTOR Zero = XMVectorZero();
|
|
||||||
|
|
||||||
XMVECTOR L = XMVector4LengthSq(Q);
|
XMVECTOR L = XMVector4LengthSq(Q);
|
||||||
XMVECTOR Conjugate = XMQuaternionConjugate(Q);
|
XMVECTOR Conjugate = XMQuaternionConjugate(Q);
|
||||||
|
|
||||||
@ -237,7 +235,7 @@ inline XMVECTOR XM_CALLCONV XMQuaternionInverse(FXMVECTOR Q) noexcept
|
|||||||
|
|
||||||
XMVECTOR Result = XMVectorDivide(Conjugate, L);
|
XMVECTOR Result = XMVectorDivide(Conjugate, L);
|
||||||
|
|
||||||
Result = XMVectorSelect(Result, Zero, Control);
|
Result = XMVectorSelect(Result, g_XMZero, Control);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -582,9 +580,30 @@ inline XMVECTOR XM_CALLCONV XMQuaternionRotationRollPitchYaw
|
|||||||
float Roll
|
float Roll
|
||||||
) noexcept
|
) noexcept
|
||||||
{
|
{
|
||||||
|
#if defined(_XM_NO_INTRINSICS_)
|
||||||
|
const float halfpitch = Pitch * 0.5f;
|
||||||
|
float cp = cosf(halfpitch);
|
||||||
|
float sp = sinf(halfpitch);
|
||||||
|
|
||||||
|
const float halfyaw = Yaw * 0.5f;
|
||||||
|
float cy = cosf(halfyaw);
|
||||||
|
float sy = sinf(halfyaw);
|
||||||
|
|
||||||
|
const float halfroll = Roll * 0.5f;
|
||||||
|
float cr = cosf(halfroll);
|
||||||
|
float sr = sinf(halfroll);
|
||||||
|
|
||||||
|
XMVECTORF32 vResult = { { {
|
||||||
|
cr * sp * cy + sr * cp * sy,
|
||||||
|
cr * cp * sy - sr * sp * cy,
|
||||||
|
sr * cp * cy - cr * sp * sy,
|
||||||
|
cr * cp * cy + sr * sp * sy
|
||||||
|
} } };
|
||||||
|
return vResult;
|
||||||
|
#else
|
||||||
XMVECTOR Angles = XMVectorSet(Pitch, Yaw, Roll, 0.0f);
|
XMVECTOR Angles = XMVectorSet(Pitch, Yaw, Roll, 0.0f);
|
||||||
XMVECTOR Q = XMQuaternionRotationRollPitchYawFromVector(Angles);
|
return XMQuaternionRotationRollPitchYawFromVector(Angles);
|
||||||
return Q;
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -594,6 +613,27 @@ inline XMVECTOR XM_CALLCONV XMQuaternionRotationRollPitchYawFromVector
|
|||||||
FXMVECTOR Angles // <Pitch, Yaw, Roll, 0>
|
FXMVECTOR Angles // <Pitch, Yaw, Roll, 0>
|
||||||
) noexcept
|
) noexcept
|
||||||
{
|
{
|
||||||
|
#if defined(_XM_NO_INTRINSICS_)
|
||||||
|
const float halfpitch = Angles.vector4_f32[0] * 0.5f;
|
||||||
|
float cp = cosf(halfpitch);
|
||||||
|
float sp = sinf(halfpitch);
|
||||||
|
|
||||||
|
const float halfyaw = Angles.vector4_f32[1] * 0.5f;
|
||||||
|
float cy = cosf(halfyaw);
|
||||||
|
float sy = sinf(halfyaw);
|
||||||
|
|
||||||
|
const float halfroll = Angles.vector4_f32[2] * 0.5f;
|
||||||
|
float cr = cosf(halfroll);
|
||||||
|
float sr = sinf(halfroll);
|
||||||
|
|
||||||
|
XMVECTORF32 vResult = { { {
|
||||||
|
cr * sp * cy + sr * cp * sy,
|
||||||
|
cr * cp * sy - sr * sp * cy,
|
||||||
|
sr * cp * cy - cr * sp * sy,
|
||||||
|
cr * cp * cy + sr * sp * sy
|
||||||
|
} } };
|
||||||
|
return vResult;
|
||||||
|
#else
|
||||||
static const XMVECTORF32 Sign = { { { 1.0f, -1.0f, -1.0f, 1.0f } } };
|
static const XMVECTORF32 Sign = { { { 1.0f, -1.0f, -1.0f, 1.0f } } };
|
||||||
|
|
||||||
XMVECTOR HalfAngles = XMVectorMultiply(Angles, g_XMOneHalf.v);
|
XMVECTOR HalfAngles = XMVectorMultiply(Angles, g_XMOneHalf.v);
|
||||||
@ -615,6 +655,7 @@ inline XMVECTOR XM_CALLCONV XMQuaternionRotationRollPitchYawFromVector
|
|||||||
XMVECTOR Q = XMVectorMultiplyAdd(Q1, R1, Q0);
|
XMVECTOR Q = XMVectorMultiplyAdd(Q1, R1, Q0);
|
||||||
|
|
||||||
return Q;
|
return Q;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -728,74 +769,74 @@ inline XMVECTOR XM_CALLCONV XMQuaternionRotationMatrix(FXMMATRIX M) noexcept
|
|||||||
static const XMVECTORU32 Select0110 = { { { XM_SELECT_0, XM_SELECT_1, XM_SELECT_1, XM_SELECT_0 } } };
|
static const XMVECTORU32 Select0110 = { { { XM_SELECT_0, XM_SELECT_1, XM_SELECT_1, XM_SELECT_0 } } };
|
||||||
static const XMVECTORU32 Select0010 = { { { XM_SELECT_0, XM_SELECT_0, XM_SELECT_1, XM_SELECT_0 } } };
|
static const XMVECTORU32 Select0010 = { { { XM_SELECT_0, XM_SELECT_0, XM_SELECT_1, XM_SELECT_0 } } };
|
||||||
|
|
||||||
XMVECTOR r0 = M.r[0];
|
float32x4_t r0 = M.r[0];
|
||||||
XMVECTOR r1 = M.r[1];
|
float32x4_t r1 = M.r[1];
|
||||||
XMVECTOR r2 = M.r[2];
|
float32x4_t r2 = M.r[2];
|
||||||
|
|
||||||
XMVECTOR r00 = vdupq_lane_f32(vget_low_f32(r0), 0);
|
float32x4_t r00 = vdupq_lane_f32(vget_low_f32(r0), 0);
|
||||||
XMVECTOR r11 = vdupq_lane_f32(vget_low_f32(r1), 1);
|
float32x4_t r11 = vdupq_lane_f32(vget_low_f32(r1), 1);
|
||||||
XMVECTOR r22 = vdupq_lane_f32(vget_high_f32(r2), 0);
|
float32x4_t r22 = vdupq_lane_f32(vget_high_f32(r2), 0);
|
||||||
|
|
||||||
// x^2 >= y^2 equivalent to r11 - r00 <= 0
|
// x^2 >= y^2 equivalent to r11 - r00 <= 0
|
||||||
XMVECTOR r11mr00 = vsubq_f32(r11, r00);
|
float32x4_t r11mr00 = vsubq_f32(r11, r00);
|
||||||
XMVECTOR x2gey2 = vcleq_f32(r11mr00, g_XMZero);
|
uint32x4_t x2gey2 = vcleq_f32(r11mr00, g_XMZero);
|
||||||
|
|
||||||
// z^2 >= w^2 equivalent to r11 + r00 <= 0
|
// z^2 >= w^2 equivalent to r11 + r00 <= 0
|
||||||
XMVECTOR r11pr00 = vaddq_f32(r11, r00);
|
float32x4_t r11pr00 = vaddq_f32(r11, r00);
|
||||||
XMVECTOR z2gew2 = vcleq_f32(r11pr00, g_XMZero);
|
uint32x4_t z2gew2 = vcleq_f32(r11pr00, g_XMZero);
|
||||||
|
|
||||||
// x^2 + y^2 >= z^2 + w^2 equivalent to r22 <= 0
|
// x^2 + y^2 >= z^2 + w^2 equivalent to r22 <= 0
|
||||||
XMVECTOR x2py2gez2pw2 = vcleq_f32(r22, g_XMZero);
|
uint32x4_t x2py2gez2pw2 = vcleq_f32(r22, g_XMZero);
|
||||||
|
|
||||||
// (4*x^2, 4*y^2, 4*z^2, 4*w^2)
|
// (4*x^2, 4*y^2, 4*z^2, 4*w^2)
|
||||||
XMVECTOR t0 = vmulq_f32(XMPMMP, r00);
|
float32x4_t t0 = vmulq_f32(XMPMMP, r00);
|
||||||
XMVECTOR x2y2z2w2 = vmlaq_f32(t0, XMMPMP, r11);
|
float32x4_t x2y2z2w2 = vmlaq_f32(t0, XMMPMP, r11);
|
||||||
x2y2z2w2 = vmlaq_f32(x2y2z2w2, XMMMPP, r22);
|
x2y2z2w2 = vmlaq_f32(x2y2z2w2, XMMMPP, r22);
|
||||||
x2y2z2w2 = vaddq_f32(x2y2z2w2, g_XMOne);
|
x2y2z2w2 = vaddq_f32(x2y2z2w2, g_XMOne);
|
||||||
|
|
||||||
// (r01, r02, r12, r11)
|
// (r01, r02, r12, r11)
|
||||||
t0 = vextq_f32(r0, r0, 1);
|
t0 = vextq_f32(r0, r0, 1);
|
||||||
XMVECTOR t1 = vextq_f32(r1, r1, 1);
|
float32x4_t t1 = vextq_f32(r1, r1, 1);
|
||||||
t0 = vcombine_f32(vget_low_f32(t0), vrev64_f32(vget_low_f32(t1)));
|
t0 = vcombine_f32(vget_low_f32(t0), vrev64_f32(vget_low_f32(t1)));
|
||||||
|
|
||||||
// (r10, r20, r21, r10)
|
// (r10, r20, r21, r10)
|
||||||
t1 = vextq_f32(r2, r2, 3);
|
t1 = vextq_f32(r2, r2, 3);
|
||||||
XMVECTOR r10 = vdupq_lane_f32(vget_low_f32(r1), 0);
|
float32x4_t r10 = vdupq_lane_f32(vget_low_f32(r1), 0);
|
||||||
t1 = vbslq_f32(Select0110, t1, r10);
|
t1 = vbslq_f32(Select0110, t1, r10);
|
||||||
|
|
||||||
// (4*x*y, 4*x*z, 4*y*z, unused)
|
// (4*x*y, 4*x*z, 4*y*z, unused)
|
||||||
XMVECTOR xyxzyz = vaddq_f32(t0, t1);
|
float32x4_t xyxzyz = vaddq_f32(t0, t1);
|
||||||
|
|
||||||
// (r21, r20, r10, r10)
|
// (r21, r20, r10, r10)
|
||||||
t0 = vcombine_f32(vrev64_f32(vget_low_f32(r2)), vget_low_f32(r10));
|
t0 = vcombine_f32(vrev64_f32(vget_low_f32(r2)), vget_low_f32(r10));
|
||||||
|
|
||||||
// (r12, r02, r01, r12)
|
// (r12, r02, r01, r12)
|
||||||
XMVECTOR t2 = vcombine_f32(vrev64_f32(vget_high_f32(r0)), vrev64_f32(vget_low_f32(r0)));
|
float32x4_t t2 = vcombine_f32(vrev64_f32(vget_high_f32(r0)), vrev64_f32(vget_low_f32(r0)));
|
||||||
XMVECTOR t3 = vdupq_lane_f32(vget_high_f32(r1), 0);
|
float32x4_t t3 = vdupq_lane_f32(vget_high_f32(r1), 0);
|
||||||
t1 = vbslq_f32(Select0110, t2, t3);
|
t1 = vbslq_f32(Select0110, t2, t3);
|
||||||
|
|
||||||
// (4*x*w, 4*y*w, 4*z*w, unused)
|
// (4*x*w, 4*y*w, 4*z*w, unused)
|
||||||
XMVECTOR xwywzw = vsubq_f32(t0, t1);
|
float32x4_t xwywzw = vsubq_f32(t0, t1);
|
||||||
xwywzw = vmulq_f32(XMMPMP, xwywzw);
|
xwywzw = vmulq_f32(XMMPMP, xwywzw);
|
||||||
|
|
||||||
// (4*x*x, 4*x*y, 4*x*z, 4*x*w)
|
// (4*x*x, 4*x*y, 4*x*z, 4*x*w)
|
||||||
t0 = vextq_f32(xyxzyz, xyxzyz, 3);
|
t0 = vextq_f32(xyxzyz, xyxzyz, 3);
|
||||||
t1 = vbslq_f32(Select0110, t0, x2y2z2w2);
|
t1 = vbslq_f32(Select0110, t0, x2y2z2w2);
|
||||||
t2 = vdupq_lane_f32(vget_low_f32(xwywzw), 0);
|
t2 = vdupq_lane_f32(vget_low_f32(xwywzw), 0);
|
||||||
XMVECTOR tensor0 = vbslq_f32(g_XMSelect1110, t1, t2);
|
float32x4_t tensor0 = vbslq_f32(g_XMSelect1110, t1, t2);
|
||||||
|
|
||||||
// (4*y*x, 4*y*y, 4*y*z, 4*y*w)
|
// (4*y*x, 4*y*y, 4*y*z, 4*y*w)
|
||||||
t0 = vbslq_f32(g_XMSelect1011, xyxzyz, x2y2z2w2);
|
t0 = vbslq_f32(g_XMSelect1011, xyxzyz, x2y2z2w2);
|
||||||
t1 = vdupq_lane_f32(vget_low_f32(xwywzw), 1);
|
t1 = vdupq_lane_f32(vget_low_f32(xwywzw), 1);
|
||||||
XMVECTOR tensor1 = vbslq_f32(g_XMSelect1110, t0, t1);
|
float32x4_t tensor1 = vbslq_f32(g_XMSelect1110, t0, t1);
|
||||||
|
|
||||||
// (4*z*x, 4*z*y, 4*z*z, 4*z*w)
|
// (4*z*x, 4*z*y, 4*z*z, 4*z*w)
|
||||||
t0 = vextq_f32(xyxzyz, xyxzyz, 1);
|
t0 = vextq_f32(xyxzyz, xyxzyz, 1);
|
||||||
t1 = vcombine_f32(vget_low_f32(t0), vrev64_f32(vget_high_f32(xwywzw)));
|
t1 = vcombine_f32(vget_low_f32(t0), vrev64_f32(vget_high_f32(xwywzw)));
|
||||||
XMVECTOR tensor2 = vbslq_f32(Select0010, x2y2z2w2, t1);
|
float32x4_t tensor2 = vbslq_f32(Select0010, x2y2z2w2, t1);
|
||||||
|
|
||||||
// (4*w*x, 4*w*y, 4*w*z, 4*w*w)
|
// (4*w*x, 4*w*y, 4*w*z, 4*w*w)
|
||||||
XMVECTOR tensor3 = vbslq_f32(g_XMSelect1110, xwywzw, x2y2z2w2);
|
float32x4_t tensor3 = vbslq_f32(g_XMSelect1110, xwywzw, x2y2z2w2);
|
||||||
|
|
||||||
// Select the row of the tensor-product matrix that has the largest
|
// Select the row of the tensor-product matrix that has the largest
|
||||||
// magnitude.
|
// magnitude.
|
||||||
@ -925,11 +966,11 @@ inline void XM_CALLCONV XMQuaternionToAxisAngle
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Comparison operations
|
// Comparison operations
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
inline bool XM_CALLCONV XMPlaneEqual
|
inline bool XM_CALLCONV XMPlaneEqual
|
||||||
(
|
(
|
||||||
@ -1176,7 +1217,7 @@ inline void XM_CALLCONV XMPlaneIntersectPlane
|
|||||||
inline XMVECTOR XM_CALLCONV XMPlaneTransform
|
inline XMVECTOR XM_CALLCONV XMPlaneTransform
|
||||||
(
|
(
|
||||||
FXMVECTOR P,
|
FXMVECTOR P,
|
||||||
FXMMATRIX M
|
FXMMATRIX ITM
|
||||||
) noexcept
|
) noexcept
|
||||||
{
|
{
|
||||||
XMVECTOR W = XMVectorSplatW(P);
|
XMVECTOR W = XMVectorSplatW(P);
|
||||||
@ -1184,10 +1225,10 @@ inline XMVECTOR XM_CALLCONV XMPlaneTransform
|
|||||||
XMVECTOR Y = XMVectorSplatY(P);
|
XMVECTOR Y = XMVectorSplatY(P);
|
||||||
XMVECTOR X = XMVectorSplatX(P);
|
XMVECTOR X = XMVectorSplatX(P);
|
||||||
|
|
||||||
XMVECTOR Result = XMVectorMultiply(W, M.r[3]);
|
XMVECTOR Result = XMVectorMultiply(W, ITM.r[3]);
|
||||||
Result = XMVectorMultiplyAdd(Z, M.r[2], Result);
|
Result = XMVectorMultiplyAdd(Z, ITM.r[2], Result);
|
||||||
Result = XMVectorMultiplyAdd(Y, M.r[1], Result);
|
Result = XMVectorMultiplyAdd(Y, ITM.r[1], Result);
|
||||||
Result = XMVectorMultiplyAdd(X, M.r[0], Result);
|
Result = XMVectorMultiplyAdd(X, ITM.r[0], Result);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1195,12 +1236,12 @@ inline XMVECTOR XM_CALLCONV XMPlaneTransform
|
|||||||
_Use_decl_annotations_
|
_Use_decl_annotations_
|
||||||
inline XMFLOAT4* XM_CALLCONV XMPlaneTransformStream
|
inline XMFLOAT4* XM_CALLCONV XMPlaneTransformStream
|
||||||
(
|
(
|
||||||
XMFLOAT4* pOutputStream,
|
XMFLOAT4* pOutputStream,
|
||||||
size_t OutputStride,
|
size_t OutputStride,
|
||||||
const XMFLOAT4* pInputStream,
|
const XMFLOAT4* pInputStream,
|
||||||
size_t InputStride,
|
size_t InputStride,
|
||||||
size_t PlaneCount,
|
size_t PlaneCount,
|
||||||
FXMMATRIX M
|
FXMMATRIX ITM
|
||||||
) noexcept
|
) noexcept
|
||||||
{
|
{
|
||||||
return XMVector4TransformStream(pOutputStream,
|
return XMVector4TransformStream(pOutputStream,
|
||||||
@ -1208,7 +1249,7 @@ inline XMFLOAT4* XM_CALLCONV XMPlaneTransformStream
|
|||||||
pInputStream,
|
pInputStream,
|
||||||
InputStride,
|
InputStride,
|
||||||
PlaneCount,
|
PlaneCount,
|
||||||
M);
|
ITM);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -1257,11 +1298,11 @@ inline XMVECTOR XM_CALLCONV XMPlaneFromPoints
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Comparison operations
|
// Comparison operations
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
inline bool XM_CALLCONV XMColorEqual
|
inline bool XM_CALLCONV XMColorEqual
|
||||||
(
|
(
|
||||||
@ -1358,8 +1399,8 @@ inline XMVECTOR XM_CALLCONV XMColorNegative(FXMVECTOR vColor) noexcept
|
|||||||
} } };
|
} } };
|
||||||
return vResult.v;
|
return vResult.v;
|
||||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||||
XMVECTOR vTemp = veorq_u32(vColor, g_XMNegate3);
|
uint32x4_t vTemp = veorq_u32(vreinterpretq_u32_f32(vColor), g_XMNegate3);
|
||||||
return vaddq_f32(vTemp, g_XMOne3);
|
return vaddq_f32(vreinterpretq_f32_u32(vTemp), g_XMOne3);
|
||||||
#elif defined(_XM_SSE_INTRINSICS_)
|
#elif defined(_XM_SSE_INTRINSICS_)
|
||||||
// Negate only x,y and z.
|
// Negate only x,y and z.
|
||||||
XMVECTOR vTemp = _mm_xor_ps(vColor, g_XMNegate3);
|
XMVECTOR vTemp = _mm_xor_ps(vColor, g_XMNegate3);
|
||||||
@ -1520,7 +1561,7 @@ inline XMVECTOR XM_CALLCONV XMColorRGBToHSL(FXMVECTOR rgb) noexcept
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace Internal
|
namespace MathInternal
|
||||||
{
|
{
|
||||||
|
|
||||||
inline XMVECTOR XM_CALLCONV XMColorHue2Clr(FXMVECTOR p, FXMVECTOR q, FXMVECTOR h) noexcept
|
inline XMVECTOR XM_CALLCONV XMColorHue2Clr(FXMVECTOR p, FXMVECTOR q, FXMVECTOR h) noexcept
|
||||||
@ -1558,7 +1599,7 @@ namespace Internal
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace MathInternal
|
||||||
|
|
||||||
inline XMVECTOR XM_CALLCONV XMColorHSLToRGB(FXMVECTOR hsl) noexcept
|
inline XMVECTOR XM_CALLCONV XMColorHSLToRGB(FXMVECTOR hsl) noexcept
|
||||||
{
|
{
|
||||||
@ -1588,9 +1629,9 @@ inline XMVECTOR XM_CALLCONV XMColorHSLToRGB(FXMVECTOR hsl) noexcept
|
|||||||
|
|
||||||
XMVECTOR p = XMVectorSubtract(XMVectorMultiply(g_XMTwo, l), q);
|
XMVECTOR p = XMVectorSubtract(XMVectorMultiply(g_XMTwo, l), q);
|
||||||
|
|
||||||
XMVECTOR r = DirectX::Internal::XMColorHue2Clr(p, q, XMVectorAdd(h, oneThird));
|
XMVECTOR r = DirectX::MathInternal::XMColorHue2Clr(p, q, XMVectorAdd(h, oneThird));
|
||||||
XMVECTOR g = DirectX::Internal::XMColorHue2Clr(p, q, h);
|
XMVECTOR g = DirectX::MathInternal::XMColorHue2Clr(p, q, h);
|
||||||
XMVECTOR b = DirectX::Internal::XMColorHue2Clr(p, q, XMVectorSubtract(h, oneThird));
|
XMVECTOR b = DirectX::MathInternal::XMColorHue2Clr(p, q, XMVectorSubtract(h, oneThird));
|
||||||
|
|
||||||
XMVECTOR rg = XMVectorSelect(g, r, g_XMSelect1000);
|
XMVECTOR rg = XMVectorSelect(g, r, g_XMSelect1000);
|
||||||
XMVECTOR ba = XMVectorSelect(hsl, b, g_XMSelect1110);
|
XMVECTOR ba = XMVectorSelect(hsl, b, g_XMSelect1110);
|
||||||
@ -1683,41 +1724,41 @@ inline XMVECTOR XM_CALLCONV XMColorHSVToRGB(FXMVECTOR hsv) noexcept
|
|||||||
switch (ii)
|
switch (ii)
|
||||||
{
|
{
|
||||||
case 0: // rgb = vtp
|
case 0: // rgb = vtp
|
||||||
{
|
{
|
||||||
XMVECTOR vt = XMVectorSelect(t, v, g_XMSelect1000);
|
XMVECTOR vt = XMVectorSelect(t, v, g_XMSelect1000);
|
||||||
_rgb = XMVectorSelect(p, vt, g_XMSelect1100);
|
_rgb = XMVectorSelect(p, vt, g_XMSelect1100);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1: // rgb = qvp
|
case 1: // rgb = qvp
|
||||||
{
|
{
|
||||||
XMVECTOR qv = XMVectorSelect(v, q, g_XMSelect1000);
|
XMVECTOR qv = XMVectorSelect(v, q, g_XMSelect1000);
|
||||||
_rgb = XMVectorSelect(p, qv, g_XMSelect1100);
|
_rgb = XMVectorSelect(p, qv, g_XMSelect1100);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // rgb = pvt
|
case 2: // rgb = pvt
|
||||||
{
|
{
|
||||||
XMVECTOR pv = XMVectorSelect(v, p, g_XMSelect1000);
|
XMVECTOR pv = XMVectorSelect(v, p, g_XMSelect1000);
|
||||||
_rgb = XMVectorSelect(t, pv, g_XMSelect1100);
|
_rgb = XMVectorSelect(t, pv, g_XMSelect1100);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3: // rgb = pqv
|
case 3: // rgb = pqv
|
||||||
{
|
{
|
||||||
XMVECTOR pq = XMVectorSelect(q, p, g_XMSelect1000);
|
XMVECTOR pq = XMVectorSelect(q, p, g_XMSelect1000);
|
||||||
_rgb = XMVectorSelect(v, pq, g_XMSelect1100);
|
_rgb = XMVectorSelect(v, pq, g_XMSelect1100);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4: // rgb = tpv
|
case 4: // rgb = tpv
|
||||||
{
|
{
|
||||||
XMVECTOR tp = XMVectorSelect(p, t, g_XMSelect1000);
|
XMVECTOR tp = XMVectorSelect(p, t, g_XMSelect1000);
|
||||||
_rgb = XMVectorSelect(v, tp, g_XMSelect1100);
|
_rgb = XMVectorSelect(v, tp, g_XMSelect1100);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: // rgb = vpq
|
default: // rgb = vpq
|
||||||
{
|
{
|
||||||
XMVECTOR vp = XMVectorSelect(p, v, g_XMSelect1000);
|
XMVECTOR vp = XMVectorSelect(p, v, g_XMSelect1000);
|
||||||
_rgb = XMVectorSelect(q, vp, g_XMSelect1100);
|
_rgb = XMVectorSelect(q, vp, g_XMSelect1100);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return XMVectorSelect(hsv, _rgb, g_XMSelect1110);
|
return XMVectorSelect(hsv, _rgb, g_XMSelect1110);
|
||||||
@ -1779,6 +1820,33 @@ inline XMVECTOR XM_CALLCONV XMColorYUVToRGB_HD(FXMVECTOR yuv) noexcept
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline XMVECTOR XM_CALLCONV XMColorRGBToYUV_UHD(FXMVECTOR rgb) noexcept
|
||||||
|
{
|
||||||
|
static const XMVECTORF32 Scale0 = { { { 0.2627f, -0.1215f, 0.6150f, 0.0f } } };
|
||||||
|
static const XMVECTORF32 Scale1 = { { { 0.6780f, -0.3136f, -0.5655f, 0.0f } } };
|
||||||
|
static const XMVECTORF32 Scale2 = { { { 0.0593f, 0.4351f, -0.0495f, 0.0f } } };
|
||||||
|
|
||||||
|
XMMATRIX M(Scale0, Scale1, Scale2, g_XMZero);
|
||||||
|
XMVECTOR clr = XMVector3Transform(rgb, M);
|
||||||
|
|
||||||
|
return XMVectorSelect(rgb, clr, g_XMSelect1110);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline XMVECTOR XM_CALLCONV XMColorYUVToRGB_UHD(FXMVECTOR yuv) noexcept
|
||||||
|
{
|
||||||
|
static const XMVECTORF32 Scale1 = { { { 0.0f, -0.1891f, 2.1620f, 0.0f } } };
|
||||||
|
static const XMVECTORF32 Scale2 = { { { 1.1989f, -0.4645f, 0.0f, 0.0f } } };
|
||||||
|
|
||||||
|
XMMATRIX M(g_XMOne, Scale1, Scale2, g_XMZero);
|
||||||
|
XMVECTOR clr = XMVector3Transform(yuv, M);
|
||||||
|
|
||||||
|
return XMVectorSelect(yuv, clr, g_XMSelect1110);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
inline XMVECTOR XM_CALLCONV XMColorRGBToXYZ(FXMVECTOR rgb) noexcept
|
inline XMVECTOR XM_CALLCONV XMColorRGBToXYZ(FXMVECTOR rgb) noexcept
|
||||||
{
|
{
|
||||||
static const XMVECTORF32 Scale0 = { { { 0.4887180f, 0.1762044f, 0.0000000f, 0.0f } } };
|
static const XMVECTORF32 Scale0 = { { { 0.4887180f, 0.1762044f, 0.0000000f, 0.0f } } };
|
||||||
@ -1899,13 +1967,13 @@ inline XMVECTOR XM_CALLCONV XMColorSRGBToRGB(FXMVECTOR srgb) noexcept
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
inline bool XMVerifyCPUSupport() noexcept
|
inline bool XMVerifyCPUSupport() noexcept
|
||||||
{
|
{
|
||||||
#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
|
#if defined(_XM_SSE_INTRINSICS_) && !defined(__powerpc64__) && !defined(_XM_NO_INTRINSICS_)
|
||||||
int CPUInfo[4] = { -1 };
|
int CPUInfo[4] = { -1 };
|
||||||
#if defined(__clang__) || defined(__GNUC__)
|
#if (defined(__clang__) || defined(__GNUC__)) && !defined(_MSC_VER) && !defined(__MINGW32__)
|
||||||
__cpuid(0, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
|
__cpuid(0, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
|
||||||
#else
|
#else
|
||||||
__cpuid(CPUInfo, 0);
|
__cpuid(CPUInfo, 0);
|
||||||
@ -1919,7 +1987,7 @@ inline bool XMVerifyCPUSupport() noexcept
|
|||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__clang__) || defined(__GNUC__)
|
#if (defined(__clang__) || defined(__GNUC__)) && !defined(_MSC_VER) && !defined(__MINGW32__)
|
||||||
__cpuid(1, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
|
__cpuid(1, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
|
||||||
#else
|
#else
|
||||||
__cpuid(CPUInfo, 1);
|
__cpuid(CPUInfo, 1);
|
||||||
@ -1954,7 +2022,7 @@ inline bool XMVerifyCPUSupport() noexcept
|
|||||||
return false; // No SSE2/SSE support
|
return false; // No SSE2/SSE support
|
||||||
|
|
||||||
#if defined(__AVX2__) || defined(_XM_AVX2_INTRINSICS_)
|
#if defined(__AVX2__) || defined(_XM_AVX2_INTRINSICS_)
|
||||||
#if defined(__clang__) || defined(__GNUC__)
|
#if (defined(__clang__) || defined(__GNUC__)) && !defined(_MSC_VER) && !defined(__MINGW32__)
|
||||||
__cpuid_count(7, 0, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
|
__cpuid_count(7, 0, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
|
||||||
#else
|
#else
|
||||||
__cpuidex(CPUInfo, 7, 0);
|
__cpuidex(CPUInfo, 7, 0);
|
||||||
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
|
||||||
#include "directxmath/directxmath.h"
|
#include "directxmath/DirectXMath.h"
|
||||||
|
|
||||||
size_t node_alloc(int count)
|
size_t node_alloc(int count)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user