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 eyePosition = vec3f(d, d / 2, d);
|
||||
let lightPosition = vec3f(1, 1, 1);
|
||||
let lightPosition = vec3f(100, 100, 100);
|
||||
let lightVector = normalize(lightPosition - position);
|
||||
let ndotl = max(dot(lightVector, normal), 0.0);
|
||||
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 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 { loadGltf } from "./index2.js";
|
||||
import { loadLight } from "./light.js";
|
||||
|
||||
if (!navigator.gpu) {
|
||||
throw new Error("WebGPU not supported on this browser.");
|
||||
@ -441,18 +442,150 @@ function 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()
|
||||
{
|
||||
recreateDepth();
|
||||
const colorView = context.getCurrentTexture().createView();
|
||||
|
||||
const aspect = canvas.width / canvas.height;
|
||||
rotate.instance.exports.rotate(tick * 0.01, aspect, 0);
|
||||
device.queue.writeBuffer(gltfRenderer.uniformBuffer, 0, uniformArray, 0, gltfRenderer.uniformBufferSize / 4);
|
||||
updateView();
|
||||
|
||||
{
|
||||
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);
|
||||
|
||||
51
index2.js
51
index2.js
@ -1,7 +1,6 @@
|
||||
import { getPath } from "./common.js";
|
||||
import { parseGltfChunks, vertexBufferLayouts, primitiveAccessors, splitGltf } from "./gltf.js";
|
||||
|
||||
|
||||
function loadGltfNode(module, handle, gltf, nodeIndex)
|
||||
{
|
||||
const node = gltf.json.nodes[nodeIndex];
|
||||
@ -37,7 +36,7 @@ function printMatrix(m, o)
|
||||
}
|
||||
|
||||
class GltfRenderer {
|
||||
constructor(device, canvasFormat, shaderModule, gltf, texture)
|
||||
constructor(device, canvasFormat, viewUniformBuffer, shaderModule, gltf, texture)
|
||||
{
|
||||
this.gltf = gltf;
|
||||
|
||||
@ -153,13 +152,6 @@ class GltfRenderer {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
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.nodeBuffer = device.createBuffer({
|
||||
label: "gltf node buffer",
|
||||
@ -173,7 +165,7 @@ class GltfRenderer {
|
||||
layout: bindGroupLayouts[0],
|
||||
entries: [{
|
||||
binding: 0,
|
||||
resource: { buffer: this.uniformBuffer },
|
||||
resource: { buffer: viewUniformBuffer },
|
||||
}, {
|
||||
binding: 1,
|
||||
resource: { buffer: this.nodeBuffer },
|
||||
@ -235,33 +227,12 @@ class GltfRenderer {
|
||||
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;
|
||||
for (let nodeIndex of this.gltf.json.scenes[0].nodes) {
|
||||
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;
|
||||
}
|
||||
|
||||
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 nodesHandle = loadGltfNodes(module, gltf);
|
||||
|
||||
@ -348,13 +325,7 @@ async function loadGltf(device, canvasFormat, memory, module)
|
||||
|
||||
const textures = await loadTextures(device, memory, module, gltf);
|
||||
|
||||
const code = await getPath("gltf.wgsl");
|
||||
const shaderModule = device.createShaderModule({
|
||||
label: "gltf module",
|
||||
code: await code,
|
||||
});
|
||||
|
||||
const renderer = new GltfRenderer(device, canvasFormat, shaderModule, gltf, textures[0]);
|
||||
const renderer = new GltfRenderer(device, canvasFormat, viewUniformBuffer, shaderModule, gltf, textures[2]);
|
||||
console.log(renderer.nodeBuffer);
|
||||
device.queue.writeBuffer(renderer.nodeBuffer, 0,
|
||||
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 \
|
||||
-O3 \
|
||||
-flto \
|
||||
-ffast-math \
|
||||
-nostdlib \
|
||||
-I$(MINIZ) \
|
||||
-I.. \
|
||||
-I. \
|
||||
-Werror \
|
||||
-Wfatal-errors \
|
||||
@ -29,6 +29,9 @@ LDFLAGS = \
|
||||
-Wl,--export=node_init_translation \
|
||||
-Wl,--export=png_build_crc_table \
|
||||
-Wl,--export=png_decode \
|
||||
-Wl,--export=camera_move \
|
||||
-Wl,--export=camera_init \
|
||||
-Wl,--export=camera_view_projection \
|
||||
-Wl,--import-undefined \
|
||||
-Wl,--print-map \
|
||||
-Wl,--import-memory \
|
||||
@ -45,7 +48,8 @@ PNG_OBJ = \
|
||||
stdlib.o \
|
||||
$(MINIZ)/miniz_tinfl.o \
|
||||
memory.o \
|
||||
node.o
|
||||
node.o \
|
||||
camera.o
|
||||
|
||||
module.wasm: $(PNG_OBJ)
|
||||
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
@ -1,30 +1,25 @@
|
||||
//-------------------------------------------------------------------------------------
|
||||
// DirectXMath.h -- SIMD C++ Math library
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
//
|
||||
// http://go.microsoft.com/fwlink/?LinkID=615560
|
||||
// https://go.microsoft.com/fwlink/?LinkID=615560
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error DirectX Math requires C++
|
||||
#endif
|
||||
|
||||
#define DIRECTX_MATH_VERSION 314
|
||||
#define DIRECTX_MATH_VERSION 321
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1910)
|
||||
#error DirectX Math requires Visual C++ 2017 or later.
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(_M_HYBRID_X86_ARM64) && (!_MANAGED) && (!_M_CEE) && (!defined(_M_IX86_FP) || (_M_IX86_FP > 1)) && !defined(_XM_NO_INTRINSICS_) && !defined(_XM_VECTORCALL_)
|
||||
#if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(_M_HYBRID_X86_ARM64) && !defined(_M_ARM64EC) && (!_MANAGED) && (!_M_CEE) && (!defined(_M_IX86_FP) || (_M_IX86_FP > 1)) && !defined(_XM_NO_INTRINSICS_) && !defined(_XM_VECTORCALL_)
|
||||
#define _XM_VECTORCALL_ 1
|
||||
#endif
|
||||
|
||||
@ -37,7 +32,9 @@
|
||||
#endif
|
||||
|
||||
#ifndef XM_DEPRECATED
|
||||
#ifdef __GNUC__
|
||||
#if (__cplusplus >= 201402L)
|
||||
#define XM_DEPRECATED [[deprecated]]
|
||||
#elif defined(__GNUC__)
|
||||
#define XM_DEPRECATED __attribute__ ((deprecated))
|
||||
#else
|
||||
#define XM_DEPRECATED __declspec(deprecated("This is deprecated and will be removed in a future version."))
|
||||
@ -85,25 +82,33 @@
|
||||
#endif
|
||||
|
||||
#if !defined(_XM_ARM_NEON_INTRINSICS_) && !defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
|
||||
#if (defined(_M_IX86) || defined(_M_X64) || __i386__ || __x86_64__) && !defined(_M_HYBRID_X86_ARM64)
|
||||
#if (defined(_M_IX86) || defined(_M_X64) || __i386__ || __x86_64__ || __powerpc64__) && !defined(_M_HYBRID_X86_ARM64) && !defined(_M_ARM64EC)
|
||||
#define _XM_SSE_INTRINSICS_
|
||||
#elif defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || __arm__ || __aarch64__
|
||||
#elif defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || __arm__ || __aarch64__
|
||||
#define _XM_ARM_NEON_INTRINSICS_
|
||||
#elif !defined(_XM_NO_INTRINSICS_)
|
||||
#error DirectX Math does not support this target
|
||||
#endif
|
||||
#endif // !_XM_ARM_NEON_INTRINSICS_ && !_XM_SSE_INTRINSICS_ && !_XM_NO_INTRINSICS_
|
||||
|
||||
#if !defined(_XM_NO_XMVECTOR_OVERLOADS_) && (defined(__clang__) || defined(__GNUC__))
|
||||
#if defined(_XM_SSE_INTRINSICS_) && defined(_MSC_VER) && (_MSC_VER >= 1920) && !defined(__clang__) && !defined(_XM_SVML_INTRINSICS_) && !defined(_XM_DISABLE_INTEL_SVML_)
|
||||
#define _XM_SVML_INTRINSICS_
|
||||
#endif
|
||||
|
||||
#if !defined(_XM_NO_XMVECTOR_OVERLOADS_) && (defined(__clang__) || defined(__GNUC__)) && !defined(_XM_NO_INTRINSICS_)
|
||||
#define _XM_NO_XMVECTOR_OVERLOADS_
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4514 4820)
|
||||
// C4514/4820: Off by default noise
|
||||
#endif
|
||||
//#include <math.h>
|
||||
#include <float.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#ifndef _XM_NO_INTRINSICS_
|
||||
|
||||
@ -111,11 +116,15 @@
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4987)
|
||||
// C4987: Off by default noise
|
||||
#endif
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#if (defined(__clang__) || defined(__GNUC__)) && (__x86_64__ || __i386__)
|
||||
#if (defined(__clang__) || defined(__GNUC__)) && (__x86_64__ || __i386__) && !defined(__MINGW32__) && !defined(_MSC_VER)
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
@ -136,7 +145,7 @@
|
||||
#endif
|
||||
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
#if defined(_MSC_VER) && (defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64))
|
||||
#if defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC))
|
||||
#include <arm64_neon.h>
|
||||
#else
|
||||
#include <arm_neon.h>
|
||||
@ -147,11 +156,14 @@
|
||||
#include "sal.h"
|
||||
//#include <assert.h>
|
||||
#define assert(x)
|
||||
#define isnan(x) __builtin_isnan(x)
|
||||
#define isnan(x) (false)
|
||||
#define floorf(x) __builtin_floorf(x)
|
||||
#define sqrtf(x) __builtin_sqrtf(x)
|
||||
#define expf(x) __builtin_expf(x)
|
||||
#define exp2f(x) __builtin_exp2f(x)
|
||||
#define logf(x) __builtin_logf(x)
|
||||
#define log2f(x) __builtin_log2f(x)
|
||||
#define log10f(x) __builtin_log10f(x)
|
||||
#define powf(x, y) __builtin_powf(x, y)
|
||||
#define fabsf(x) __builtin_fabsf(x)
|
||||
#define sinf(x) __builtin_sinf(x)
|
||||
@ -164,18 +176,25 @@
|
||||
#define coshf(x) __builtin_coshf(x)
|
||||
#define atanf(x) __builtin_atanf(x)
|
||||
#define atan2f(x, y) __builtin_atan2f(x, y)
|
||||
#define isinf(x) __builtin_isinf(x)
|
||||
#define isinf(x) (false)
|
||||
#define ceilf(x) __builtin_ceilf(x)
|
||||
#define modff(x, y) __builtin_modff(x, y)
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4005 4668)
|
||||
// C4005/4668: Old header issue
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if (__cplusplus >= 201703L)
|
||||
#define XM_ALIGNED_DATA(x) alignas(x)
|
||||
#define XM_ALIGNED_STRUCT(x) struct alignas(x)
|
||||
#elif defined(__GNUC__)
|
||||
#define XM_ALIGNED_DATA(x) __attribute__ ((aligned(x)))
|
||||
#define XM_ALIGNED_STRUCT(x) struct __attribute__ ((aligned(x)))
|
||||
#else
|
||||
@ -183,6 +202,10 @@
|
||||
#define XM_ALIGNED_STRUCT(x) __declspec(align(x)) struct
|
||||
#endif
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
#include <compare>
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Conditional intrinsics
|
||||
@ -215,11 +238,17 @@
|
||||
#define XM_PERMUTE_PS( v, c ) _mm_shuffle_ps((v), (v), c )
|
||||
#endif
|
||||
|
||||
#if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ < 11)) || defined(__powerpc64__)
|
||||
#define XM_LOADU_SI16( p ) _mm_cvtsi32_si128(*reinterpret_cast<unsigned short const*>(p))
|
||||
#else
|
||||
#define XM_LOADU_SI16( p ) _mm_loadu_si16(p)
|
||||
#endif
|
||||
|
||||
#endif // _XM_SSE_INTRINSICS_ && !_XM_NO_INTRINSICS_
|
||||
|
||||
#if defined(_XM_ARM_NEON_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
|
||||
|
||||
#if defined(__clang__)
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#define XM_PREFETCH( a ) __builtin_prefetch(a)
|
||||
#elif defined(_MSC_VER)
|
||||
#define XM_PREFETCH( a ) __prefetch(a)
|
||||
@ -291,7 +320,11 @@ namespace DirectX
|
||||
constexpr uint32_t XM_CRMASK_CR6FALSE = 0x00000020;
|
||||
constexpr uint32_t XM_CRMASK_CR6BOUNDS = XM_CRMASK_CR6FALSE;
|
||||
|
||||
#if defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || __arm__ || __aarch64__
|
||||
constexpr size_t XM_CACHE_LINE_SIZE = 128;
|
||||
#else
|
||||
constexpr size_t XM_CACHE_LINE_SIZE = 64;
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
@ -312,18 +345,18 @@ namespace DirectX
|
||||
|
||||
// Unit conversion
|
||||
|
||||
inline constexpr float XMConvertToRadians(float fDegrees) noexcept { return fDegrees * (XM_PI / 180.0f); }
|
||||
inline constexpr float XMConvertToDegrees(float fRadians) noexcept { return fRadians * (180.0f / XM_PI); }
|
||||
constexpr float XMConvertToRadians(float fDegrees) noexcept { return fDegrees * (XM_PI / 180.0f); }
|
||||
constexpr float XMConvertToDegrees(float fRadians) noexcept { return fRadians * (180.0f / XM_PI); }
|
||||
|
||||
// Condition register evaluation proceeding a recording (R) comparison
|
||||
|
||||
inline constexpr bool XMComparisonAllTrue(uint32_t CR) noexcept { return (((CR)&XM_CRMASK_CR6TRUE) == XM_CRMASK_CR6TRUE); }
|
||||
inline constexpr bool XMComparisonAnyTrue(uint32_t CR) noexcept { return (((CR)&XM_CRMASK_CR6FALSE) != XM_CRMASK_CR6FALSE); }
|
||||
inline constexpr bool XMComparisonAllFalse(uint32_t CR) noexcept { return (((CR)&XM_CRMASK_CR6FALSE) == XM_CRMASK_CR6FALSE); }
|
||||
inline constexpr bool XMComparisonAnyFalse(uint32_t CR) noexcept { return (((CR)&XM_CRMASK_CR6TRUE) != XM_CRMASK_CR6TRUE); }
|
||||
inline constexpr bool XMComparisonMixed(uint32_t CR) noexcept { return (((CR)&XM_CRMASK_CR6) == 0); }
|
||||
inline constexpr bool XMComparisonAllInBounds(uint32_t CR) noexcept { return (((CR)&XM_CRMASK_CR6BOUNDS) == XM_CRMASK_CR6BOUNDS); }
|
||||
inline constexpr bool XMComparisonAnyOutOfBounds(uint32_t CR) noexcept { return (((CR)&XM_CRMASK_CR6BOUNDS) != XM_CRMASK_CR6BOUNDS); }
|
||||
constexpr bool XMComparisonAllTrue(uint32_t CR) noexcept { return (CR & XM_CRMASK_CR6TRUE) == XM_CRMASK_CR6TRUE; }
|
||||
constexpr bool XMComparisonAnyTrue(uint32_t CR) noexcept { return (CR & XM_CRMASK_CR6FALSE) != XM_CRMASK_CR6FALSE; }
|
||||
constexpr bool XMComparisonAllFalse(uint32_t CR) noexcept { return (CR & XM_CRMASK_CR6FALSE) == XM_CRMASK_CR6FALSE; }
|
||||
constexpr bool XMComparisonAnyFalse(uint32_t CR) noexcept { return (CR & XM_CRMASK_CR6TRUE) != XM_CRMASK_CR6TRUE; }
|
||||
constexpr bool XMComparisonMixed(uint32_t CR) noexcept { return (CR & XM_CRMASK_CR6) == 0; }
|
||||
constexpr bool XMComparisonAllInBounds(uint32_t CR) noexcept { return (CR & XM_CRMASK_CR6BOUNDS) == XM_CRMASK_CR6BOUNDS; }
|
||||
constexpr bool XMComparisonAnyOutOfBounds(uint32_t CR) noexcept { return (CR & XM_CRMASK_CR6BOUNDS) != XM_CRMASK_CR6BOUNDS; }
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
@ -332,12 +365,14 @@ namespace DirectX
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4068 4201 4365 4324 4820)
|
||||
// C4068: ignore unknown pragmas
|
||||
// C4201: nonstandard extension used : nameless struct/union
|
||||
// C4365: Off by default noise
|
||||
// C4324/4820: padding warnings
|
||||
#endif
|
||||
|
||||
#ifdef _PREFAST_
|
||||
#pragma prefast(push)
|
||||
@ -360,11 +395,11 @@ namespace DirectX
|
||||
// Vector intrinsic: Four 32 bit floating point components aligned on a 16 byte
|
||||
// boundary and mapped to hardware vector registers
|
||||
#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
|
||||
typedef __m128 XMVECTOR;
|
||||
using XMVECTOR = __m128;
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
|
||||
typedef float32x4_t XMVECTOR;
|
||||
using XMVECTOR = float32x4_t;
|
||||
#else
|
||||
typedef __vector4 XMVECTOR;
|
||||
using XMVECTOR = __vector4;
|
||||
#endif
|
||||
|
||||
// Fix-up for (1st-3rd) XMVECTOR parameters that are pass-in-register for x86, ARM, ARM64, and vector call; by reference otherwise
|
||||
@ -374,15 +409,15 @@ namespace DirectX
|
||||
typedef const XMVECTOR& FXMVECTOR;
|
||||
#endif
|
||||
|
||||
// Fix-up for (4th) XMVECTOR parameter to pass in-register for ARM, ARM64, and x64 vector call; by reference otherwise
|
||||
#if ( defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || (_XM_VECTORCALL_ && !defined(_M_IX86) ) || __arm__ || __aarch64__ ) && !defined(_XM_NO_INTRINSICS_)
|
||||
// Fix-up for (4th) XMVECTOR parameter to pass in-register for ARM, ARM64, and vector call; by reference otherwise
|
||||
#if ( defined(_M_ARM) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || _XM_VECTORCALL_ || __arm__ || __aarch64__ ) && !defined(_XM_NO_INTRINSICS_)
|
||||
typedef const XMVECTOR GXMVECTOR;
|
||||
#else
|
||||
typedef const XMVECTOR& GXMVECTOR;
|
||||
#endif
|
||||
|
||||
// Fix-up for (5th & 6th) XMVECTOR parameter to pass in-register for ARM64 and vector call; by reference otherwise
|
||||
#if ( defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || _XM_VECTORCALL_ || __aarch64__ ) && !defined(_XM_NO_INTRINSICS_)
|
||||
#if ( defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || _XM_VECTORCALL_ || __aarch64__ ) && !defined(_XM_NO_INTRINSICS_)
|
||||
typedef const XMVECTOR HXMVECTOR;
|
||||
#else
|
||||
typedef const XMVECTOR& HXMVECTOR;
|
||||
@ -403,9 +438,13 @@ namespace DirectX
|
||||
|
||||
inline operator XMVECTOR() const noexcept { return v; }
|
||||
inline operator const float* () const noexcept { return f; }
|
||||
#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_SSE_INTRINSICS_)
|
||||
#ifdef _XM_NO_INTRINSICS_
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
inline operator __m128i() const noexcept { return _mm_castps_si128(v); }
|
||||
inline operator __m128d() const noexcept { return _mm_castps_pd(v); }
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_) && (defined(__GNUC__) || defined(_ARM64_DISTINCT_NEON_TYPES))
|
||||
inline operator int32x4_t() const noexcept { return vreinterpretq_s32_f32(v); }
|
||||
inline operator uint32x4_t() const noexcept { return vreinterpretq_u32_f32(v); }
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -418,9 +457,13 @@ namespace DirectX
|
||||
};
|
||||
|
||||
inline operator XMVECTOR() const noexcept { return v; }
|
||||
#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_SSE_INTRINSICS_)
|
||||
#ifdef _XM_NO_INTRINSICS_
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
inline operator __m128i() const noexcept { return _mm_castps_si128(v); }
|
||||
inline operator __m128d() const noexcept { return _mm_castps_pd(v); }
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_) && (defined(__GNUC__) || defined(_ARM64_DISTINCT_NEON_TYPES))
|
||||
inline operator int32x4_t() const noexcept { return vreinterpretq_s32_f32(v); }
|
||||
inline operator uint32x4_t() const noexcept { return vreinterpretq_u32_f32(v); }
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -433,9 +476,13 @@ namespace DirectX
|
||||
};
|
||||
|
||||
inline operator XMVECTOR() const noexcept { return v; }
|
||||
#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_SSE_INTRINSICS_)
|
||||
#ifdef _XM_NO_INTRINSICS_
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
inline operator __m128i() const noexcept { return _mm_castps_si128(v); }
|
||||
inline operator __m128d() const noexcept { return _mm_castps_pd(v); }
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_) && (defined(__GNUC__) || defined(_ARM64_DISTINCT_NEON_TYPES))
|
||||
inline operator int32x4_t() const noexcept { return vreinterpretq_s32_f32(v); }
|
||||
inline operator uint32x4_t() const noexcept { return vreinterpretq_u32_f32(v); }
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -448,9 +495,13 @@ namespace DirectX
|
||||
};
|
||||
|
||||
inline operator XMVECTOR() const noexcept { return v; }
|
||||
#if !defined(_XM_NO_INTRINSICS_) && defined(_XM_SSE_INTRINSICS_)
|
||||
#ifdef _XM_NO_INTRINSICS_
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
inline operator __m128i() const noexcept { return _mm_castps_si128(v); }
|
||||
inline operator __m128d() const noexcept { return _mm_castps_pd(v); }
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_) && (defined(__GNUC__) || defined(_ARM64_DISTINCT_NEON_TYPES))
|
||||
inline operator int32x4_t() const noexcept { return vreinterpretq_s32_f32(v); }
|
||||
inline operator uint32x4_t() const noexcept { return vreinterpretq_u32_f32(v); }
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -485,7 +536,7 @@ namespace DirectX
|
||||
struct XMMATRIX;
|
||||
|
||||
// Fix-up for (1st) XMMATRIX parameter to pass in-register for ARM64 and vector call; by reference otherwise
|
||||
#if ( defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || _XM_VECTORCALL_ || __aarch64__ ) && !defined(_XM_NO_INTRINSICS_)
|
||||
#if ( defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || _XM_VECTORCALL_ || __aarch64__ ) && !defined(_XM_NO_INTRINSICS_)
|
||||
typedef const XMMATRIX FXMMATRIX;
|
||||
#else
|
||||
typedef const XMMATRIX& FXMMATRIX;
|
||||
@ -577,21 +628,17 @@ namespace DirectX
|
||||
|
||||
constexpr XMFLOAT2(float _x, float _y) noexcept : x(_x), y(_y) {}
|
||||
explicit XMFLOAT2(_In_reads_(2) const float* pArray) noexcept : x(pArray[0]), y(pArray[1]) {}
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
bool operator == (const XMFLOAT2&) const = default;
|
||||
auto operator <=> (const XMFLOAT2&) const = default;
|
||||
#endif
|
||||
};
|
||||
|
||||
// 2D Vector; 32 bit floating point components aligned on a 16 byte boundary
|
||||
XM_ALIGNED_STRUCT(16) XMFLOAT2A : public XMFLOAT2
|
||||
{
|
||||
XMFLOAT2A() = default;
|
||||
|
||||
XMFLOAT2A(const XMFLOAT2A&) = default;
|
||||
XMFLOAT2A& operator=(const XMFLOAT2A&) = default;
|
||||
|
||||
XMFLOAT2A(XMFLOAT2A&&) = default;
|
||||
XMFLOAT2A& operator=(XMFLOAT2A&&) = default;
|
||||
|
||||
constexpr XMFLOAT2A(float _x, float _y) noexcept : XMFLOAT2(_x, _y) {}
|
||||
explicit XMFLOAT2A(_In_reads_(2) const float* pArray) noexcept : XMFLOAT2(pArray) {}
|
||||
using XMFLOAT2::XMFLOAT2;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -611,6 +658,11 @@ namespace DirectX
|
||||
|
||||
constexpr XMINT2(int32_t _x, int32_t _y) noexcept : x(_x), y(_y) {}
|
||||
explicit XMINT2(_In_reads_(2) const int32_t* pArray) noexcept : x(pArray[0]), y(pArray[1]) {}
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
bool operator == (const XMINT2&) const = default;
|
||||
auto operator <=> (const XMINT2&) const = default;
|
||||
#endif
|
||||
};
|
||||
|
||||
// 2D Vector; 32 bit unsigned integer components
|
||||
@ -629,6 +681,11 @@ namespace DirectX
|
||||
|
||||
constexpr XMUINT2(uint32_t _x, uint32_t _y) noexcept : x(_x), y(_y) {}
|
||||
explicit XMUINT2(_In_reads_(2) const uint32_t* pArray) noexcept : x(pArray[0]), y(pArray[1]) {}
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
bool operator == (const XMUINT2&) const = default;
|
||||
auto operator <=> (const XMUINT2&) const = default;
|
||||
#endif
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -649,21 +706,17 @@ namespace DirectX
|
||||
|
||||
constexpr XMFLOAT3(float _x, float _y, float _z) noexcept : x(_x), y(_y), z(_z) {}
|
||||
explicit XMFLOAT3(_In_reads_(3) const float* pArray) noexcept : x(pArray[0]), y(pArray[1]), z(pArray[2]) {}
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
bool operator == (const XMFLOAT3&) const = default;
|
||||
auto operator <=> (const XMFLOAT3&) const = default;
|
||||
#endif
|
||||
};
|
||||
|
||||
// 3D Vector; 32 bit floating point components aligned on a 16 byte boundary
|
||||
XM_ALIGNED_STRUCT(16) XMFLOAT3A : public XMFLOAT3
|
||||
{
|
||||
XMFLOAT3A() = default;
|
||||
|
||||
XMFLOAT3A(const XMFLOAT3A&) = default;
|
||||
XMFLOAT3A& operator=(const XMFLOAT3A&) = default;
|
||||
|
||||
XMFLOAT3A(XMFLOAT3A&&) = default;
|
||||
XMFLOAT3A& operator=(XMFLOAT3A&&) = default;
|
||||
|
||||
constexpr XMFLOAT3A(float _x, float _y, float _z) noexcept : XMFLOAT3(_x, _y, _z) {}
|
||||
explicit XMFLOAT3A(_In_reads_(3) const float* pArray) noexcept : XMFLOAT3(pArray) {}
|
||||
using XMFLOAT3::XMFLOAT3;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -684,6 +737,11 @@ namespace DirectX
|
||||
|
||||
constexpr XMINT3(int32_t _x, int32_t _y, int32_t _z) noexcept : x(_x), y(_y), z(_z) {}
|
||||
explicit XMINT3(_In_reads_(3) const int32_t* pArray) noexcept : x(pArray[0]), y(pArray[1]), z(pArray[2]) {}
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
bool operator == (const XMINT3&) const = default;
|
||||
auto operator <=> (const XMINT3&) const = default;
|
||||
#endif
|
||||
};
|
||||
|
||||
// 3D Vector; 32 bit unsigned integer components
|
||||
@ -703,6 +761,11 @@ namespace DirectX
|
||||
|
||||
constexpr XMUINT3(uint32_t _x, uint32_t _y, uint32_t _z) noexcept : x(_x), y(_y), z(_z) {}
|
||||
explicit XMUINT3(_In_reads_(3) const uint32_t* pArray) noexcept : x(pArray[0]), y(pArray[1]), z(pArray[2]) {}
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
bool operator == (const XMUINT3&) const = default;
|
||||
auto operator <=> (const XMUINT3&) const = default;
|
||||
#endif
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -724,21 +787,17 @@ namespace DirectX
|
||||
|
||||
constexpr XMFLOAT4(float _x, float _y, float _z, float _w) noexcept : x(_x), y(_y), z(_z), w(_w) {}
|
||||
explicit XMFLOAT4(_In_reads_(4) const float* pArray) noexcept : x(pArray[0]), y(pArray[1]), z(pArray[2]), w(pArray[3]) {}
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
bool operator == (const XMFLOAT4&) const = default;
|
||||
auto operator <=> (const XMFLOAT4&) const = default;
|
||||
#endif
|
||||
};
|
||||
|
||||
// 4D Vector; 32 bit floating point components aligned on a 16 byte boundary
|
||||
XM_ALIGNED_STRUCT(16) XMFLOAT4A : public XMFLOAT4
|
||||
{
|
||||
XMFLOAT4A() = default;
|
||||
|
||||
XMFLOAT4A(const XMFLOAT4A&) = default;
|
||||
XMFLOAT4A& operator=(const XMFLOAT4A&) = default;
|
||||
|
||||
XMFLOAT4A(XMFLOAT4A&&) = default;
|
||||
XMFLOAT4A& operator=(XMFLOAT4A&&) = default;
|
||||
|
||||
constexpr XMFLOAT4A(float _x, float _y, float _z, float _w) noexcept : XMFLOAT4(_x, _y, _z, _w) {}
|
||||
explicit XMFLOAT4A(_In_reads_(4) const float* pArray) noexcept : XMFLOAT4(pArray) {}
|
||||
using XMFLOAT4::XMFLOAT4;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -760,6 +819,11 @@ namespace DirectX
|
||||
|
||||
constexpr XMINT4(int32_t _x, int32_t _y, int32_t _z, int32_t _w) noexcept : x(_x), y(_y), z(_z), w(_w) {}
|
||||
explicit XMINT4(_In_reads_(4) const int32_t* pArray) noexcept : x(pArray[0]), y(pArray[1]), z(pArray[2]), w(pArray[3]) {}
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
bool operator == (const XMINT4&) const = default;
|
||||
auto operator <=> (const XMINT4&) const = default;
|
||||
#endif
|
||||
};
|
||||
|
||||
// 4D Vector; 32 bit unsigned integer components
|
||||
@ -780,12 +844,19 @@ namespace DirectX
|
||||
|
||||
constexpr XMUINT4(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) noexcept : x(_x), y(_y), z(_z), w(_w) {}
|
||||
explicit XMUINT4(_In_reads_(4) const uint32_t* pArray) noexcept : x(pArray[0]), y(pArray[1]), z(pArray[2]), w(pArray[3]) {}
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
bool operator == (const XMUINT4&) const = default;
|
||||
auto operator <=> (const XMUINT4&) const = default;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
|
||||
#pragma clang diagnostic ignored "-Wnested-anon-types"
|
||||
#pragma clang diagnostic ignored "-Wunknown-warning-option"
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -816,11 +887,34 @@ namespace DirectX
|
||||
float m20, float m21, float m22) noexcept
|
||||
: _11(m00), _12(m01), _13(m02),
|
||||
_21(m10), _22(m11), _23(m12),
|
||||
_31(m20), _32(m21), _33(m22) {}
|
||||
_31(m20), _32(m21), _33(m22)
|
||||
{}
|
||||
explicit XMFLOAT3X3(_In_reads_(9) const float* pArray) noexcept;
|
||||
|
||||
float operator() (size_t Row, size_t Column) const noexcept { return m[Row][Column]; }
|
||||
float& operator() (size_t Row, size_t Column) noexcept { return m[Row][Column]; }
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
constexpr bool operator == (const XMFLOAT3X3& M) const noexcept
|
||||
{
|
||||
return _11 == M._11 && _12 == M._12 && _13 == M._13
|
||||
&& _21 == M._21 && _22 == M._22 && _23 == M._23
|
||||
&& _31 == M._31 && _32 == M._32 && _33 == M._33;
|
||||
}
|
||||
|
||||
constexpr auto operator <=> (const XMFLOAT3X3& M) const noexcept
|
||||
{
|
||||
if (auto cmp = _11 <=> M._11; cmp != 0) return cmp;
|
||||
if (auto cmp = _12 <=> M._12; cmp != 0) return cmp;
|
||||
if (auto cmp = _13 <=> M._13; cmp != 0) return cmp;
|
||||
if (auto cmp = _21 <=> M._21; cmp != 0) return cmp;
|
||||
if (auto cmp = _22 <=> M._22; cmp != 0) return cmp;
|
||||
if (auto cmp = _23 <=> M._23; cmp != 0) return cmp;
|
||||
if (auto cmp = _31 <=> M._31; cmp != 0) return cmp;
|
||||
if (auto cmp = _32 <=> M._32; cmp != 0) return cmp;
|
||||
return _33 <=> M._33;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -855,30 +949,44 @@ namespace DirectX
|
||||
: _11(m00), _12(m01), _13(m02),
|
||||
_21(m10), _22(m11), _23(m12),
|
||||
_31(m20), _32(m21), _33(m22),
|
||||
_41(m30), _42(m31), _43(m32) {}
|
||||
_41(m30), _42(m31), _43(m32)
|
||||
{}
|
||||
explicit XMFLOAT4X3(_In_reads_(12) const float* pArray) noexcept;
|
||||
|
||||
float operator() (size_t Row, size_t Column) const noexcept { return m[Row][Column]; }
|
||||
float& operator() (size_t Row, size_t Column) noexcept { return m[Row][Column]; }
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
constexpr bool operator == (const XMFLOAT4X3& M) const noexcept
|
||||
{
|
||||
return _11 == M._11 && _12 == M._12 && _13 == M._13
|
||||
&& _21 == M._21 && _22 == M._22 && _23 == M._23
|
||||
&& _31 == M._31 && _32 == M._32 && _33 == M._33
|
||||
&& _41 == M._41 && _42 == M._42 && _43 == M._43;
|
||||
}
|
||||
|
||||
constexpr auto operator <=> (const XMFLOAT4X3& M) const noexcept
|
||||
{
|
||||
if (auto cmp = _11 <=> M._11; cmp != 0) return cmp;
|
||||
if (auto cmp = _12 <=> M._12; cmp != 0) return cmp;
|
||||
if (auto cmp = _13 <=> M._13; cmp != 0) return cmp;
|
||||
if (auto cmp = _21 <=> M._21; cmp != 0) return cmp;
|
||||
if (auto cmp = _22 <=> M._22; cmp != 0) return cmp;
|
||||
if (auto cmp = _23 <=> M._23; cmp != 0) return cmp;
|
||||
if (auto cmp = _31 <=> M._31; cmp != 0) return cmp;
|
||||
if (auto cmp = _32 <=> M._32; cmp != 0) return cmp;
|
||||
if (auto cmp = _33 <=> M._33; cmp != 0) return cmp;
|
||||
if (auto cmp = _41 <=> M._41; cmp != 0) return cmp;
|
||||
if (auto cmp = _42 <=> M._42; cmp != 0) return cmp;
|
||||
return _43 <=> M._43;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// 4x3 Row-major Matrix: 32 bit floating point components aligned on a 16 byte boundary
|
||||
XM_ALIGNED_STRUCT(16) XMFLOAT4X3A : public XMFLOAT4X3
|
||||
{
|
||||
XMFLOAT4X3A() = default;
|
||||
|
||||
XMFLOAT4X3A(const XMFLOAT4X3A&) = default;
|
||||
XMFLOAT4X3A& operator=(const XMFLOAT4X3A&) = default;
|
||||
|
||||
XMFLOAT4X3A(XMFLOAT4X3A&&) = default;
|
||||
XMFLOAT4X3A& operator=(XMFLOAT4X3A&&) = default;
|
||||
|
||||
constexpr XMFLOAT4X3A(float m00, float m01, float m02,
|
||||
float m10, float m11, float m12,
|
||||
float m20, float m21, float m22,
|
||||
float m30, float m31, float m32) noexcept :
|
||||
XMFLOAT4X3(m00, m01, m02, m10, m11, m12, m20, m21, m22, m30, m31, m32) {}
|
||||
explicit XMFLOAT4X3A(_In_reads_(12) const float* pArray) noexcept : XMFLOAT4X3(pArray) {}
|
||||
using XMFLOAT4X3::XMFLOAT4X3;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -910,29 +1018,43 @@ namespace DirectX
|
||||
float m20, float m21, float m22, float m23) noexcept
|
||||
: _11(m00), _12(m01), _13(m02), _14(m03),
|
||||
_21(m10), _22(m11), _23(m12), _24(m13),
|
||||
_31(m20), _32(m21), _33(m22), _34(m23) {}
|
||||
_31(m20), _32(m21), _33(m22), _34(m23)
|
||||
{}
|
||||
explicit XMFLOAT3X4(_In_reads_(12) const float* pArray) noexcept;
|
||||
|
||||
float operator() (size_t Row, size_t Column) const noexcept { return m[Row][Column]; }
|
||||
float& operator() (size_t Row, size_t Column) noexcept { return m[Row][Column]; }
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
constexpr bool operator == (const XMFLOAT3X4& M) const noexcept
|
||||
{
|
||||
return _11 == M._11 && _12 == M._12 && _13 == M._13 && _14 == M._14
|
||||
&& _21 == M._21 && _22 == M._22 && _23 == M._23 && _24 == M._24
|
||||
&& _31 == M._31 && _32 == M._32 && _33 == M._33 && _34 == M._34;
|
||||
}
|
||||
|
||||
constexpr auto operator <=> (const XMFLOAT3X4& M) const noexcept
|
||||
{
|
||||
if (auto cmp = _11 <=> M._11; cmp != 0) return cmp;
|
||||
if (auto cmp = _12 <=> M._12; cmp != 0) return cmp;
|
||||
if (auto cmp = _13 <=> M._13; cmp != 0) return cmp;
|
||||
if (auto cmp = _14 <=> M._14; cmp != 0) return cmp;
|
||||
if (auto cmp = _21 <=> M._21; cmp != 0) return cmp;
|
||||
if (auto cmp = _22 <=> M._22; cmp != 0) return cmp;
|
||||
if (auto cmp = _23 <=> M._23; cmp != 0) return cmp;
|
||||
if (auto cmp = _24 <=> M._24; cmp != 0) return cmp;
|
||||
if (auto cmp = _31 <=> M._31; cmp != 0) return cmp;
|
||||
if (auto cmp = _32 <=> M._32; cmp != 0) return cmp;
|
||||
if (auto cmp = _33 <=> M._33; cmp != 0) return cmp;
|
||||
return _34 <=> M._34;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// 3x4 Column-major Matrix: 32 bit floating point components aligned on a 16 byte boundary
|
||||
XM_ALIGNED_STRUCT(16) XMFLOAT3X4A : public XMFLOAT3X4
|
||||
{
|
||||
XMFLOAT3X4A() = default;
|
||||
|
||||
XMFLOAT3X4A(const XMFLOAT3X4A&) = default;
|
||||
XMFLOAT3X4A& operator=(const XMFLOAT3X4A&) = default;
|
||||
|
||||
XMFLOAT3X4A(XMFLOAT3X4A&&) = default;
|
||||
XMFLOAT3X4A& operator=(XMFLOAT3X4A&&) = default;
|
||||
|
||||
constexpr XMFLOAT3X4A(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23) noexcept :
|
||||
XMFLOAT3X4(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23) {}
|
||||
explicit XMFLOAT3X4A(_In_reads_(12) const float* pArray) noexcept : XMFLOAT3X4(pArray) {}
|
||||
using XMFLOAT3X4::XMFLOAT3X4;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -966,30 +1088,48 @@ namespace DirectX
|
||||
: _11(m00), _12(m01), _13(m02), _14(m03),
|
||||
_21(m10), _22(m11), _23(m12), _24(m13),
|
||||
_31(m20), _32(m21), _33(m22), _34(m23),
|
||||
_41(m30), _42(m31), _43(m32), _44(m33) {}
|
||||
_41(m30), _42(m31), _43(m32), _44(m33)
|
||||
{}
|
||||
explicit XMFLOAT4X4(_In_reads_(16) const float* pArray) noexcept;
|
||||
|
||||
float operator() (size_t Row, size_t Column) const noexcept { return m[Row][Column]; }
|
||||
float& operator() (size_t Row, size_t Column) noexcept { return m[Row][Column]; }
|
||||
|
||||
#if (__cplusplus >= 202002L)
|
||||
constexpr bool operator == (const XMFLOAT4X4& M) const noexcept
|
||||
{
|
||||
return _11 == M._11 && _12 == M._12 && _13 == M._13 && _14 == M._14
|
||||
&& _21 == M._21 && _22 == M._22 && _23 == M._23 && _24 == M._24
|
||||
&& _31 == M._31 && _32 == M._32 && _33 == M._33 && _34 == M._34
|
||||
&& _41 == M._41 && _42 == M._42 && _43 == M._43 && _44 == M._44;
|
||||
}
|
||||
|
||||
constexpr auto operator <=> (const XMFLOAT4X4& M) const noexcept
|
||||
{
|
||||
if (auto cmp = _11 <=> M._11; cmp != 0) return cmp;
|
||||
if (auto cmp = _12 <=> M._12; cmp != 0) return cmp;
|
||||
if (auto cmp = _13 <=> M._13; cmp != 0) return cmp;
|
||||
if (auto cmp = _14 <=> M._14; cmp != 0) return cmp;
|
||||
if (auto cmp = _21 <=> M._21; cmp != 0) return cmp;
|
||||
if (auto cmp = _22 <=> M._22; cmp != 0) return cmp;
|
||||
if (auto cmp = _23 <=> M._23; cmp != 0) return cmp;
|
||||
if (auto cmp = _24 <=> M._24; cmp != 0) return cmp;
|
||||
if (auto cmp = _31 <=> M._31; cmp != 0) return cmp;
|
||||
if (auto cmp = _32 <=> M._32; cmp != 0) return cmp;
|
||||
if (auto cmp = _33 <=> M._33; cmp != 0) return cmp;
|
||||
if (auto cmp = _34 <=> M._34; cmp != 0) return cmp;
|
||||
if (auto cmp = _41 <=> M._41; cmp != 0) return cmp;
|
||||
if (auto cmp = _42 <=> M._42; cmp != 0) return cmp;
|
||||
if (auto cmp = _43 <=> M._43; cmp != 0) return cmp;
|
||||
return _44 <=> M._44;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// 4x4 Matrix: 32 bit floating point components aligned on a 16 byte boundary
|
||||
XM_ALIGNED_STRUCT(16) XMFLOAT4X4A : public XMFLOAT4X4
|
||||
{
|
||||
XMFLOAT4X4A() = default;
|
||||
|
||||
XMFLOAT4X4A(const XMFLOAT4X4A&) = default;
|
||||
XMFLOAT4X4A& operator=(const XMFLOAT4X4A&) = default;
|
||||
|
||||
XMFLOAT4X4A(XMFLOAT4X4A&&) = default;
|
||||
XMFLOAT4X4A& operator=(XMFLOAT4X4A&&) = default;
|
||||
|
||||
constexpr XMFLOAT4X4A(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33) noexcept
|
||||
: XMFLOAT4X4(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {}
|
||||
explicit XMFLOAT4X4A(_In_reads_(16) const float* pArray) noexcept : XMFLOAT4X4(pArray) {}
|
||||
using XMFLOAT4X4::XMFLOAT4X4;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -997,12 +1137,12 @@ namespace DirectX
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef _PREFAST_
|
||||
#pragma prefast(pop)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
@ -1250,9 +1390,11 @@ namespace DirectX
|
||||
XMVECTOR XM_CALLCONV XMVectorReciprocalSqrtEst(FXMVECTOR V) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMVectorReciprocalSqrt(FXMVECTOR V) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMVectorExp2(FXMVECTOR V) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMVectorExp10(FXMVECTOR V) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMVectorExpE(FXMVECTOR V) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMVectorExp(FXMVECTOR V) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMVectorLog2(FXMVECTOR V) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMVectorLog10(FXMVECTOR V) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMVectorLogE(FXMVECTOR V) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMVectorLog(FXMVECTOR V) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMVectorPow(FXMVECTOR V1, FXMVECTOR V2) noexcept;
|
||||
@ -1505,8 +1647,13 @@ namespace DirectX
|
||||
XMMATRIX XM_CALLCONV XMMatrixRotationX(float Angle) noexcept;
|
||||
XMMATRIX XM_CALLCONV XMMatrixRotationY(float Angle) noexcept;
|
||||
XMMATRIX XM_CALLCONV XMMatrixRotationZ(float Angle) noexcept;
|
||||
|
||||
// Rotates about y-axis (Yaw), then x-axis (Pitch), then z-axis (Roll)
|
||||
XMMATRIX XM_CALLCONV XMMatrixRotationRollPitchYaw(float Pitch, float Yaw, float Roll) noexcept;
|
||||
|
||||
// Rotates about y-axis (Angles.y), then x-axis (Angles.x), then z-axis (Angles.z)
|
||||
XMMATRIX XM_CALLCONV XMMatrixRotationRollPitchYawFromVector(FXMVECTOR Angles) noexcept;
|
||||
|
||||
XMMATRIX XM_CALLCONV XMMatrixRotationNormal(FXMVECTOR NormalAxis, float Angle) noexcept;
|
||||
XMMATRIX XM_CALLCONV XMMatrixRotationAxis(FXMVECTOR Axis, float Angle) noexcept;
|
||||
XMMATRIX XM_CALLCONV XMMatrixRotationQuaternion(FXMVECTOR Quaternion) noexcept;
|
||||
@ -1568,8 +1715,13 @@ namespace DirectX
|
||||
XMVECTOR XM_CALLCONV XMQuaternionBaryCentricV(FXMVECTOR Q0, FXMVECTOR Q1, FXMVECTOR Q2, GXMVECTOR F, HXMVECTOR G) noexcept;
|
||||
|
||||
XMVECTOR XM_CALLCONV XMQuaternionIdentity() noexcept;
|
||||
|
||||
// Rotates about y-axis (Yaw), then x-axis (Pitch), then z-axis (Roll)
|
||||
XMVECTOR XM_CALLCONV XMQuaternionRotationRollPitchYaw(float Pitch, float Yaw, float Roll) noexcept;
|
||||
|
||||
// Rotates about y-axis (Angles.y), then x-axis (Angles.x), then z-axis (Angles.z)
|
||||
XMVECTOR XM_CALLCONV XMQuaternionRotationRollPitchYawFromVector(FXMVECTOR Angles) noexcept;
|
||||
|
||||
XMVECTOR XM_CALLCONV XMQuaternionRotationNormal(FXMVECTOR NormalAxis, float Angle) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMQuaternionRotationAxis(FXMVECTOR Axis, float Angle) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMQuaternionRotationMatrix(FXMMATRIX M) noexcept;
|
||||
@ -1596,11 +1748,15 @@ namespace DirectX
|
||||
XMVECTOR XM_CALLCONV XMPlaneNormalize(FXMVECTOR P) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMPlaneIntersectLine(FXMVECTOR P, FXMVECTOR LinePoint1, FXMVECTOR LinePoint2) noexcept;
|
||||
void XM_CALLCONV XMPlaneIntersectPlane(_Out_ XMVECTOR* pLinePoint1, _Out_ XMVECTOR* pLinePoint2, _In_ FXMVECTOR P1, _In_ FXMVECTOR P2) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMPlaneTransform(FXMVECTOR P, FXMMATRIX M) noexcept;
|
||||
|
||||
// Transforms a plane given an inverse transpose matrix
|
||||
XMVECTOR XM_CALLCONV XMPlaneTransform(FXMVECTOR P, FXMMATRIX ITM) noexcept;
|
||||
|
||||
// Transforms an array of planes given an inverse transpose matrix
|
||||
XMFLOAT4* XM_CALLCONV XMPlaneTransformStream(_Out_writes_bytes_(sizeof(XMFLOAT4) + OutputStride * (PlaneCount - 1)) XMFLOAT4* pOutputStream,
|
||||
_In_ size_t OutputStride,
|
||||
_In_reads_bytes_(sizeof(XMFLOAT4) + InputStride * (PlaneCount - 1)) const XMFLOAT4* pInputStream,
|
||||
_In_ size_t InputStride, _In_ size_t PlaneCount, _In_ FXMMATRIX M) noexcept;
|
||||
_In_ size_t InputStride, _In_ size_t PlaneCount, _In_ FXMMATRIX ITM) noexcept;
|
||||
|
||||
XMVECTOR XM_CALLCONV XMPlaneFromPointNormal(FXMVECTOR Point, FXMVECTOR Normal) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMPlaneFromPoints(FXMVECTOR Point1, FXMVECTOR Point2, FXMVECTOR Point3) noexcept;
|
||||
@ -1638,6 +1794,9 @@ namespace DirectX
|
||||
XMVECTOR XM_CALLCONV XMColorRGBToYUV_HD(FXMVECTOR rgb) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMColorYUVToRGB_HD(FXMVECTOR yuv) noexcept;
|
||||
|
||||
XMVECTOR XM_CALLCONV XMColorRGBToYUV_UHD(FXMVECTOR rgb) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMColorYUVToRGB_UHD(FXMVECTOR yuv) noexcept;
|
||||
|
||||
XMVECTOR XM_CALLCONV XMColorRGBToXYZ(FXMVECTOR rgb) noexcept;
|
||||
XMVECTOR XM_CALLCONV XMColorXYZToRGB(FXMVECTOR xyz) noexcept;
|
||||
|
||||
@ -1687,15 +1846,15 @@ namespace DirectX
|
||||
#undef XMMax
|
||||
#endif
|
||||
|
||||
template<class T> inline T XMMin(T a, T b) { return (a < b) ? a : b; }
|
||||
template<class T> inline T XMMax(T a, T b) { return (a > b) ? a : b; }
|
||||
template<class T> inline T XMMin(T a, T b) noexcept { return (a < b) ? a : b; }
|
||||
template<class T> inline T XMMax(T a, T b) noexcept { return (a > b) ? a : b; }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
|
||||
|
||||
// PermuteHelper internal template (SSE only)
|
||||
namespace Internal
|
||||
namespace MathInternal
|
||||
{
|
||||
// Slow path fallback for permutes that do not map to a single SSE shuffle opcode.
|
||||
template<uint32_t Shuffle, bool WhichX, bool WhichY, bool WhichZ, bool WhichW> struct PermuteHelper
|
||||
@ -1757,14 +1916,14 @@ namespace DirectX
|
||||
static_assert(PermuteW <= 7, "PermuteW template parameter out of range");
|
||||
|
||||
#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
|
||||
const uint32_t Shuffle = _MM_SHUFFLE(PermuteW & 3, PermuteZ & 3, PermuteY & 3, PermuteX & 3);
|
||||
constexpr uint32_t Shuffle = _MM_SHUFFLE(PermuteW & 3, PermuteZ & 3, PermuteY & 3, PermuteX & 3);
|
||||
|
||||
const bool WhichX = PermuteX > 3;
|
||||
const bool WhichY = PermuteY > 3;
|
||||
const bool WhichZ = PermuteZ > 3;
|
||||
const bool WhichW = PermuteW > 3;
|
||||
constexpr bool WhichX = PermuteX > 3;
|
||||
constexpr bool WhichY = PermuteY > 3;
|
||||
constexpr bool WhichZ = PermuteZ > 3;
|
||||
constexpr bool WhichW = PermuteW > 3;
|
||||
|
||||
return Internal::PermuteHelper<Shuffle, WhichX, WhichY, WhichZ, WhichW>::Permute(V1, V2);
|
||||
return MathInternal::PermuteHelper<Shuffle, WhichX, WhichY, WhichZ, WhichW>::Permute(V1, V2);
|
||||
#else
|
||||
|
||||
return XMVectorPermute(V1, V2, PermuteX, PermuteY, PermuteZ, PermuteW);
|
||||
@ -1773,8 +1932,8 @@ namespace DirectX
|
||||
}
|
||||
|
||||
// Special-case permute templates
|
||||
template<> inline XMVECTOR XM_CALLCONV XMVectorPermute<0, 1, 2, 3>(FXMVECTOR V1, FXMVECTOR) noexcept { return V1; }
|
||||
template<> inline XMVECTOR XM_CALLCONV XMVectorPermute<4, 5, 6, 7>(FXMVECTOR, FXMVECTOR V2) noexcept { return V2; }
|
||||
template<> constexpr XMVECTOR XM_CALLCONV XMVectorPermute<0, 1, 2, 3>(FXMVECTOR V1, FXMVECTOR) noexcept { return V1; }
|
||||
template<> constexpr XMVECTOR XM_CALLCONV XMVectorPermute<4, 5, 6, 7>(FXMVECTOR, FXMVECTOR V2) noexcept { return V2; }
|
||||
|
||||
#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
|
||||
template<> inline XMVECTOR XM_CALLCONV XMVectorPermute<0, 1, 4, 5>(FXMVECTOR V1, FXMVECTOR V2) noexcept { return _mm_movelh_ps(V1, V2); }
|
||||
@ -1862,7 +2021,7 @@ namespace DirectX
|
||||
}
|
||||
|
||||
// Specialized swizzles
|
||||
template<> inline XMVECTOR XM_CALLCONV XMVectorSwizzle<0, 1, 2, 3>(FXMVECTOR V) noexcept { return V; }
|
||||
template<> constexpr XMVECTOR XM_CALLCONV XMVectorSwizzle<0, 1, 2, 3>(FXMVECTOR V) noexcept { return V; }
|
||||
|
||||
#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
|
||||
template<> inline XMVECTOR XM_CALLCONV XMVectorSwizzle<0, 1, 0, 1>(FXMVECTOR V) noexcept { return _mm_movelh_ps(V, V); }
|
||||
@ -1960,7 +2119,9 @@ namespace DirectX
|
||||
// separate math routine it would be reloaded.
|
||||
|
||||
#ifndef XMGLOBALCONST
|
||||
#if defined(__GNUC__) && !defined(__MINGW32__)
|
||||
#if __cplusplus >= 201703L
|
||||
#define XMGLOBALCONST inline constexpr
|
||||
#elif defined(__GNUC__) && !defined(__MINGW32__)
|
||||
#define XMGLOBALCONST extern const __attribute__((weak))
|
||||
#else
|
||||
#define XMGLOBALCONST extern const __declspec(selectany)
|
||||
@ -2101,6 +2262,8 @@ namespace DirectX
|
||||
XMGLOBALCONST XMVECTORF32 g_XMLogEst7 = { { { -0.010578f, -0.010578f, -0.010578f, -0.010578f } } };
|
||||
XMGLOBALCONST XMVECTORF32 g_XMLgE = { { { +1.442695f, +1.442695f, +1.442695f, +1.442695f } } };
|
||||
XMGLOBALCONST XMVECTORF32 g_XMInvLgE = { { { +6.93147182e-1f, +6.93147182e-1f, +6.93147182e-1f, +6.93147182e-1f } } };
|
||||
XMGLOBALCONST XMVECTORF32 g_XMLg10 = { { { +3.321928f, +3.321928f, +3.321928f, +3.321928f } } };
|
||||
XMGLOBALCONST XMVECTORF32 g_XMInvLg10 = { { { +3.010299956e-1f, +3.010299956e-1f, +3.010299956e-1f, +3.010299956e-1f } } };
|
||||
XMGLOBALCONST XMVECTORF32 g_UByteMax = { { { 255.0f, 255.0f, 255.0f, 255.0f } } };
|
||||
XMGLOBALCONST XMVECTORF32 g_ByteMin = { { { -127.0f, -127.0f, -127.0f, -127.0f } } };
|
||||
XMGLOBALCONST XMVECTORF32 g_ByteMax = { { { 127.0f, 127.0f, 127.0f, 127.0f } } };
|
||||
@ -2114,12 +2277,14 @@ namespace DirectX
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4068 4214 4204 4365 4616 4640 6001 6101)
|
||||
// C4068/4616: ignore unknown pragmas
|
||||
// C4214/4204: nonstandard extension used
|
||||
// C4365/4640: Off by default noise
|
||||
// C6001/6101: False positives
|
||||
#endif
|
||||
|
||||
#ifdef _PREFAST_
|
||||
#pragma prefast(push)
|
||||
@ -2129,7 +2294,10 @@ namespace DirectX
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wfloat-equal"
|
||||
#pragma clang diagnostic ignored "-Wundefined-reinterpret-cast"
|
||||
#pragma clang diagnostic ignored "-Wunknown-warning-option"
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -2185,7 +2353,7 @@ namespace DirectX
|
||||
// Convert DivExponent into 1.0f/(1<<DivExponent)
|
||||
uint32_t uScale = 0x3F800000U - (DivExponent << 23);
|
||||
// Splat the scalar value (It's really a float)
|
||||
vScale = vdupq_n_u32(uScale);
|
||||
vScale = vreinterpretq_s32_u32(vdupq_n_u32(uScale));
|
||||
// Multiply by the reciprocal (Perform a right shift by DivExponent)
|
||||
vResult = vmulq_f32(vResult, reinterpret_cast<const float32x4_t*>(&vScale)[0]);
|
||||
return vResult;
|
||||
@ -2223,25 +2391,21 @@ namespace DirectX
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "directxmath/directxmathconvert.inl"
|
||||
#include "directxmath/directxmathvector.inl"
|
||||
#include "directxmath/directxmathmatrix.inl"
|
||||
#include "directxmath/directxmathmisc.inl"
|
||||
#include "DirectXMathConvert.inl"
|
||||
#include "DirectXMathVector.inl"
|
||||
#include "DirectXMathMatrix.inl"
|
||||
#include "DirectXMathMisc.inl"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef _PREFAST_
|
||||
#pragma prefast(pop)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace DirectX
|
||||
|
||||
using namespace DirectX;
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
@ -1,10 +1,10 @@
|
||||
//-------------------------------------------------------------------------------------
|
||||
// DirectXMathConvert.inl -- SIMD C++ Math library
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
//
|
||||
// http://go.microsoft.com/fwlink/?LinkID=615560
|
||||
// https://go.microsoft.com/fwlink/?LinkID=615560
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
@ -17,9 +17,11 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4701)
|
||||
// C4701: false positives
|
||||
#endif
|
||||
|
||||
inline XMVECTOR XM_CALLCONV XMConvertVectorIntToFloat
|
||||
(
|
||||
@ -32,14 +34,16 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorIntToFloat
|
||||
float fScale = 1.0f / static_cast<float>(1U << DivExponent);
|
||||
uint32_t ElementIndex = 0;
|
||||
XMVECTOR Result;
|
||||
do {
|
||||
do
|
||||
{
|
||||
auto iTemp = static_cast<int32_t>(VInt.vector4_u32[ElementIndex]);
|
||||
Result.vector4_f32[ElementIndex] = static_cast<float>(iTemp)* fScale;
|
||||
} while (++ElementIndex < 4);
|
||||
}
|
||||
while (++ElementIndex < 4);
|
||||
return Result;
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
float fScale = 1.0f / (float)(1U << DivExponent);
|
||||
float32x4_t vResult = vcvtq_f32_s32(VInt);
|
||||
float fScale = 1.0f / static_cast<float>(1U << DivExponent);
|
||||
float32x4_t vResult = vcvtq_f32_s32(vreinterpretq_s32_f32(VInt));
|
||||
return vmulq_n_f32(vResult, fScale);
|
||||
#else // _XM_SSE_INTRINSICS_
|
||||
// Convert to floats
|
||||
@ -67,7 +71,8 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorFloatToInt
|
||||
auto fScale = static_cast<float>(1U << MulExponent);
|
||||
uint32_t ElementIndex = 0;
|
||||
XMVECTOR Result;
|
||||
do {
|
||||
do
|
||||
{
|
||||
int32_t iResult;
|
||||
float fTemp = VFloat.vector4_f32[ElementIndex] * fScale;
|
||||
if (fTemp <= -(65536.0f * 32768.0f))
|
||||
@ -78,23 +83,25 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorFloatToInt
|
||||
{
|
||||
iResult = 0x7FFFFFFF;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
iResult = static_cast<int32_t>(fTemp);
|
||||
}
|
||||
Result.vector4_u32[ElementIndex] = static_cast<uint32_t>(iResult);
|
||||
} while (++ElementIndex < 4);
|
||||
}
|
||||
while (++ElementIndex < 4);
|
||||
return Result;
|
||||
#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
|
||||
uint32x4_t vOverflow = vcgtq_f32(vResult, g_XMMaxInt);
|
||||
// Float to int conversion
|
||||
int32x4_t vResulti = vcvtq_s32_f32(vResult);
|
||||
// If there was positive overflow, set to 0x7FFFFFFF
|
||||
vResult = vandq_u32(vOverflow, g_XMAbsMask);
|
||||
vOverflow = vbicq_u32(vResulti, vOverflow);
|
||||
vOverflow = vorrq_u32(vOverflow, vResult);
|
||||
return vOverflow;
|
||||
vResult = vreinterpretq_f32_u32(vandq_u32(vOverflow, g_XMAbsMask));
|
||||
vOverflow = vbicq_u32(vreinterpretq_u32_s32(vResulti), vOverflow);
|
||||
vOverflow = vorrq_u32(vOverflow, vreinterpretq_u32_f32(vResult));
|
||||
return vreinterpretq_f32_u32(vOverflow);
|
||||
#else // _XM_SSE_INTRINSICS_
|
||||
XMVECTOR vResult = _mm_set_ps1(static_cast<float>(1U << MulExponent));
|
||||
vResult = _mm_mul_ps(vResult, VFloat);
|
||||
@ -123,13 +130,15 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorUIntToFloat
|
||||
float fScale = 1.0f / static_cast<float>(1U << DivExponent);
|
||||
uint32_t ElementIndex = 0;
|
||||
XMVECTOR Result;
|
||||
do {
|
||||
do
|
||||
{
|
||||
Result.vector4_f32[ElementIndex] = static_cast<float>(VUInt.vector4_u32[ElementIndex])* fScale;
|
||||
} while (++ElementIndex < 4);
|
||||
}
|
||||
while (++ElementIndex < 4);
|
||||
return Result;
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
float fScale = 1.0f / (float)(1U << DivExponent);
|
||||
float32x4_t vResult = vcvtq_f32_u32(VUInt);
|
||||
float fScale = 1.0f / static_cast<float>(1U << DivExponent);
|
||||
float32x4_t vResult = vcvtq_f32_u32(vreinterpretq_u32_f32(VUInt));
|
||||
return vmulq_n_f32(vResult, fScale);
|
||||
#else // _XM_SSE_INTRINSICS_
|
||||
// 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);
|
||||
uint32_t ElementIndex = 0;
|
||||
XMVECTOR Result;
|
||||
do {
|
||||
do
|
||||
{
|
||||
uint32_t uResult;
|
||||
float fTemp = VFloat.vector4_f32[ElementIndex] * fScale;
|
||||
if (fTemp <= 0.0f)
|
||||
@ -178,22 +188,24 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorFloatToUInt
|
||||
{
|
||||
uResult = 0xFFFFFFFFU;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
uResult = static_cast<uint32_t>(fTemp);
|
||||
}
|
||||
Result.vector4_u32[ElementIndex] = uResult;
|
||||
} while (++ElementIndex < 4);
|
||||
}
|
||||
while (++ElementIndex < 4);
|
||||
return Result;
|
||||
#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
|
||||
uint32x4_t vOverflow = vcgtq_f32(vResult, g_XMMaxUInt);
|
||||
// Float to int conversion
|
||||
uint32x4_t vResulti = vcvtq_u32_f32(vResult);
|
||||
// If there was overflow, set to 0xFFFFFFFFU
|
||||
vResult = vbicq_u32(vResulti, vOverflow);
|
||||
vOverflow = vorrq_u32(vOverflow, vResult);
|
||||
return vOverflow;
|
||||
vResult = vreinterpretq_f32_u32(vbicq_u32(vResulti, vOverflow));
|
||||
vOverflow = vorrq_u32(vOverflow, vreinterpretq_u32_f32(vResult));
|
||||
return vreinterpretq_f32_u32(vOverflow);
|
||||
#else // _XM_SSE_INTRINSICS_
|
||||
XMVECTOR vResult = _mm_set_ps1(static_cast<float>(1U << MulExponent));
|
||||
vResult = _mm_mul_ps(vResult, VFloat);
|
||||
@ -218,7 +230,9 @@ inline XMVECTOR XM_CALLCONV XMConvertVectorFloatToUInt
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
@ -240,7 +254,7 @@ inline XMVECTOR XM_CALLCONV XMLoadInt(const uint32_t* pSource) noexcept
|
||||
return V;
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
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_)
|
||||
return _mm_load_ss(reinterpret_cast<const float*>(pSource));
|
||||
#endif
|
||||
@ -281,7 +295,7 @@ inline XMVECTOR XM_CALLCONV XMLoadInt2(const uint32_t* pSource) noexcept
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
uint32x2_t x = vld1_u32(pSource);
|
||||
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_)
|
||||
return _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(pSource)));
|
||||
#endif
|
||||
@ -301,13 +315,13 @@ inline XMVECTOR XM_CALLCONV XMLoadInt2A(const uint32_t* pSource) noexcept
|
||||
V.vector4_u32[3] = 0;
|
||||
return V;
|
||||
#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);
|
||||
#else
|
||||
uint32x2_t x = vld1_u32(pSource);
|
||||
#endif
|
||||
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_)
|
||||
return _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(pSource)));
|
||||
#endif
|
||||
@ -348,7 +362,7 @@ inline XMVECTOR XM_CALLCONV XMLoadFloat2A(const XMFLOAT2A* pSource) noexcept
|
||||
V.vector4_f32[3] = 0.f;
|
||||
return V;
|
||||
#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);
|
||||
#else
|
||||
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 zero = vdup_n_u32(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_)
|
||||
__m128 xy = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(pSource)));
|
||||
__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;
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
// 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);
|
||||
#else
|
||||
uint32x4_t V = vld1q_u32(pSource);
|
||||
#endif
|
||||
return vsetq_lane_u32(0, V, 3);
|
||||
return vreinterpretq_f32_u32(vsetq_lane_u32(0, V, 3));
|
||||
#elif defined(_XM_SSE4_INTRINSICS_)
|
||||
__m128 xy = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(pSource)));
|
||||
__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;
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
// 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);
|
||||
#else
|
||||
float32x4_t V = vld1q_f32(reinterpret_cast<const float*>(pSource));
|
||||
#endif
|
||||
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_)
|
||||
// Reads an extra float which is zero'd
|
||||
__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];
|
||||
return V;
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
return vld1q_u32(pSource);
|
||||
return vreinterpretq_f32_u32(vld1q_u32(pSource));
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
__m128i V = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pSource));
|
||||
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];
|
||||
return V;
|
||||
#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);
|
||||
#else
|
||||
return vld1q_u32(pSource);
|
||||
return vreinterpretq_f32_u32(vld1q_u32(pSource));
|
||||
#endif
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
__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;
|
||||
return V;
|
||||
#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);
|
||||
#else
|
||||
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);
|
||||
|
||||
XMMATRIX M;
|
||||
M.r[0] = vandq_u32(v0, g_XMMask3);
|
||||
M.r[1] = vandq_u32(T, g_XMMask3);
|
||||
M.r[0] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(v0), 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[3] = g_XMIdentityR3;
|
||||
return M;
|
||||
@ -846,9 +864,9 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat4x3(const XMFLOAT4X3* pSource) noexcept
|
||||
float32x4_t T3 = vextq_f32(v2, v2, 1);
|
||||
|
||||
XMMATRIX M;
|
||||
M.r[0] = vandq_u32(v0, g_XMMask3);
|
||||
M.r[1] = vandq_u32(T1, g_XMMask3);
|
||||
M.r[2] = vandq_u32(T2, g_XMMask3);
|
||||
M.r[0] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(v0), g_XMMask3));
|
||||
M.r[1] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T1), 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);
|
||||
return M;
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
@ -867,11 +885,18 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat4x3(const XMFLOAT4X3* pSource) noexcept
|
||||
// vTemp2 = x2,y2,z2,z2
|
||||
vTemp2 = XM_PERMUTE_PS(vTemp2, _MM_SHUFFLE(1, 1, 0, 2));
|
||||
// vTemp1 = x1,y1,z1,0
|
||||
vTemp1 = _mm_and_ps(vTemp1, g_XMMask3);
|
||||
// vTemp2 = x2,y2,z2,0
|
||||
vTemp2 = _mm_and_ps(vTemp2, g_XMMask3);
|
||||
// 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);
|
||||
#endif
|
||||
// vTemp4i = x4,y4,z4,0
|
||||
__m128i vTemp4i = _mm_srli_si128(_mm_castps_si128(vTemp4), 32 / 8);
|
||||
// vTemp4i = x4,y4,z4,1.0f
|
||||
@ -915,7 +940,7 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat4x3A(const XMFLOAT4X3A* pSource) noexcept
|
||||
return M;
|
||||
|
||||
#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 v1 = vld1q_f32_ex(&pSource->m[1][1], 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);
|
||||
|
||||
XMMATRIX M;
|
||||
M.r[0] = vandq_u32(v0, g_XMMask3);
|
||||
M.r[1] = vandq_u32(T1, g_XMMask3);
|
||||
M.r[2] = vandq_u32(T2, g_XMMask3);
|
||||
M.r[0] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(v0), g_XMMask3));
|
||||
M.r[1] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T1), 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);
|
||||
return M;
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
@ -951,11 +976,18 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat4x3A(const XMFLOAT4X3A* pSource) noexcept
|
||||
// vTemp2 = x2,y2,z2,z2
|
||||
vTemp2 = XM_PERMUTE_PS(vTemp2, _MM_SHUFFLE(1, 1, 0, 2));
|
||||
// vTemp1 = x1,y1,z1,0
|
||||
vTemp1 = _mm_and_ps(vTemp1, g_XMMask3);
|
||||
// vTemp2 = x2,y2,z2,0
|
||||
vTemp2 = _mm_and_ps(vTemp2, g_XMMask3);
|
||||
// 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);
|
||||
#endif
|
||||
// vTemp4i = x4,y4,z4,0
|
||||
__m128i vTemp4i = _mm_srli_si128(_mm_castps_si128(vTemp4), 32 / 8);
|
||||
// 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);
|
||||
|
||||
XMMATRIX M = {};
|
||||
M.r[0] = vandq_u32(T0, g_XMMask3);
|
||||
M.r[1] = vandq_u32(T1, g_XMMask3);
|
||||
M.r[2] = vandq_u32(T2, g_XMMask3);
|
||||
M.r[0] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T0), g_XMMask3));
|
||||
M.r[1] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T1), 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);
|
||||
return M;
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
@ -1077,7 +1109,7 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat3x4A(const XMFLOAT3X4A* pSource) noexcept
|
||||
return M;
|
||||
|
||||
#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);
|
||||
float32x4_t vTemp1 = vld1q_f32_ex(&pSource->_31, 128);
|
||||
#else
|
||||
@ -1096,9 +1128,9 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat3x4A(const XMFLOAT3X4A* pSource) noexcept
|
||||
float32x4_t T3 = vcombine_f32(vTemp0.val[3], rh);
|
||||
|
||||
XMMATRIX M = {};
|
||||
M.r[0] = vandq_u32(T0, g_XMMask3);
|
||||
M.r[1] = vandq_u32(T1, g_XMMask3);
|
||||
M.r[2] = vandq_u32(T2, g_XMMask3);
|
||||
M.r[0] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T0), g_XMMask3));
|
||||
M.r[1] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(T1), 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);
|
||||
return M;
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
@ -1208,7 +1240,7 @@ inline XMMATRIX XM_CALLCONV XMLoadFloat4x4A(const XMFLOAT4X4A* pSource) noexcept
|
||||
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
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[1] = vld1q_f32_ex(reinterpret_cast<const float*>(&pSource->_21), 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[1] = V.vector4_u32[1];
|
||||
#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);
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
_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[1] = V.vector4_u32[1];
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
uint32x2_t VL = vget_low_u32(V);
|
||||
#ifdef _MSC_VER
|
||||
uint32x2_t VL = vget_low_u32(vreinterpretq_u32_f32(V));
|
||||
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||
vst1_u32_ex(pDestination, VL, 64);
|
||||
#else
|
||||
vst1_u32(pDestination, VL);
|
||||
@ -1350,7 +1382,7 @@ inline void XM_CALLCONV XMStoreFloat2A
|
||||
pDestination->y = V.vector4_f32[1];
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
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);
|
||||
#else
|
||||
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->y = static_cast<int32_t>(V.vector4_f32[1]);
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
int32x2_t v = vget_low_s32(V);
|
||||
v = vcvt_s32_f32(v);
|
||||
vst1_s32(reinterpret_cast<int32_t*>(pDestination), v);
|
||||
float32x2_t v = vget_low_f32(V);
|
||||
int32x2_t iv = vcvt_s32_f32(v);
|
||||
vst1_s32(reinterpret_cast<int32_t*>(pDestination), iv);
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
// In case of positive overflow, detect it
|
||||
XMVECTOR vOverflow = _mm_cmpgt_ps(V, g_XMMaxInt);
|
||||
@ -1443,7 +1475,7 @@ inline void XM_CALLCONV XMStoreInt3
|
||||
pDestination[1] = V.vector4_u32[1];
|
||||
pDestination[2] = V.vector4_u32[2];
|
||||
#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);
|
||||
vst1q_lane_u32(pDestination + 2, *reinterpret_cast<const uint32x4_t*>(&V), 2);
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
@ -1468,8 +1500,8 @@ inline void XM_CALLCONV XMStoreInt3A
|
||||
pDestination[1] = V.vector4_u32[1];
|
||||
pDestination[2] = V.vector4_u32[2];
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
uint32x2_t VL = vget_low_u32(V);
|
||||
#ifdef _MSC_VER
|
||||
uint32x2_t VL = vget_low_u32(vreinterpretq_u32_f32(V));
|
||||
#if defined(_MSC_VER) && !defined(__clang__) && !defined(_ARM64_DISTINCT_NEON_TYPES)
|
||||
vst1_u32_ex(pDestination, VL, 64);
|
||||
#else
|
||||
vst1_u32(pDestination, VL);
|
||||
@ -1526,7 +1558,7 @@ inline void XM_CALLCONV XMStoreFloat3A
|
||||
pDestination->z = V.vector4_f32[2];
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
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);
|
||||
#else
|
||||
vst1_f32(reinterpret_cast<float*>(pDestination), VL);
|
||||
@ -1634,7 +1666,7 @@ inline void XM_CALLCONV XMStoreInt4
|
||||
pDestination[2] = V.vector4_u32[2];
|
||||
pDestination[3] = V.vector4_u32[3];
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
vst1q_u32(pDestination, V);
|
||||
vst1q_u32(pDestination, vreinterpretq_u32_f32(V));
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i*>(pDestination), _mm_castps_si128(V));
|
||||
#endif
|
||||
@ -1656,10 +1688,10 @@ inline void XM_CALLCONV XMStoreInt4A
|
||||
pDestination[2] = V.vector4_u32[2];
|
||||
pDestination[3] = V.vector4_u32[3];
|
||||
#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);
|
||||
#else
|
||||
vst1q_u32(pDestination, V);
|
||||
vst1q_u32(pDestination, vreinterpretq_u32_f32(V));
|
||||
#endif
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
_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->w = V.vector4_f32[3];
|
||||
#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);
|
||||
#else
|
||||
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];
|
||||
|
||||
#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 T2 = vbslq_f32(g_XMMask3, M.r[0], T1);
|
||||
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 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[1][0], T0.val[1], 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];
|
||||
|
||||
#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->_21), M.r[1], 128);
|
||||
vst1q_f32_ex(reinterpret_cast<float*>(&pDestination->_31), M.r[2], 128);
|
||||
@ -1,10 +1,10 @@
|
||||
//-------------------------------------------------------------------------------------
|
||||
// DirectXMathMatrix.inl -- SIMD C++ Math library
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
//
|
||||
// http://go.microsoft.com/fwlink/?LinkID=615560
|
||||
// https://go.microsoft.com/fwlink/?LinkID=615560
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#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(precise, on)
|
||||
#endif
|
||||
@ -32,7 +32,8 @@ inline bool XM_CALLCONV XMMatrixIsNaN(FXMMATRIX M) noexcept
|
||||
#if defined(_XM_NO_INTRINSICS_)
|
||||
size_t i = 16;
|
||||
auto pWork = reinterpret_cast<const uint32_t*>(&M.m[0][0]);
|
||||
do {
|
||||
do
|
||||
{
|
||||
// Fetch value into integer unit
|
||||
uint32_t uTest = pWork[0];
|
||||
// Remove sign
|
||||
@ -44,27 +45,30 @@ inline bool XM_CALLCONV XMMatrixIsNaN(FXMMATRIX M) noexcept
|
||||
break; // NaN found
|
||||
}
|
||||
++pWork; // Next entry
|
||||
} while (--i);
|
||||
}
|
||||
while (--i);
|
||||
return (i != 0); // i == 0 if nothing matched
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
// Load in registers
|
||||
XMVECTOR vX = M.r[0];
|
||||
XMVECTOR vY = M.r[1];
|
||||
XMVECTOR vZ = M.r[2];
|
||||
XMVECTOR vW = M.r[3];
|
||||
float32x4_t vX = M.r[0];
|
||||
float32x4_t vY = M.r[1];
|
||||
float32x4_t vZ = M.r[2];
|
||||
float32x4_t vW = M.r[3];
|
||||
// Test themselves to check for NaN
|
||||
vX = vmvnq_u32(vceqq_f32(vX, vX));
|
||||
vY = vmvnq_u32(vceqq_f32(vY, vY));
|
||||
vZ = vmvnq_u32(vceqq_f32(vZ, vZ));
|
||||
vW = vmvnq_u32(vceqq_f32(vW, vW));
|
||||
uint32x4_t xmask = vmvnq_u32(vceqq_f32(vX, vX));
|
||||
uint32x4_t ymask = vmvnq_u32(vceqq_f32(vY, vY));
|
||||
uint32x4_t zmask = vmvnq_u32(vceqq_f32(vZ, vZ));
|
||||
uint32x4_t wmask = vmvnq_u32(vceqq_f32(vW, vW));
|
||||
// Or all the results
|
||||
vX = vorrq_u32(vX, vZ);
|
||||
vY = vorrq_u32(vY, vW);
|
||||
vX = vorrq_u32(vX, vY);
|
||||
xmask = vorrq_u32(xmask, zmask);
|
||||
ymask = vorrq_u32(ymask, wmask);
|
||||
xmask = vorrq_u32(xmask, ymask);
|
||||
// If any tested true, return true
|
||||
uint8x8x2_t vTemp = vzip_u8(vget_low_u8(vX), vget_high_u8(vX));
|
||||
uint16x4x2_t vTemp2 = vzip_u16(vTemp.val[0], vTemp.val[1]);
|
||||
uint32_t r = vget_lane_u32(vTemp2.val[1], 1);
|
||||
uint8x8x2_t vTemp = vzip_u8(
|
||||
vget_low_u8(vreinterpretq_u8_u32(xmask)),
|
||||
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);
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
// Load in registers
|
||||
@ -87,7 +91,7 @@ inline bool XM_CALLCONV XMMatrixIsNaN(FXMMATRIX M) noexcept
|
||||
#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)
|
||||
#endif
|
||||
|
||||
@ -99,7 +103,8 @@ inline bool XM_CALLCONV XMMatrixIsInfinite(FXMMATRIX M) noexcept
|
||||
#if defined(_XM_NO_INTRINSICS_)
|
||||
size_t i = 16;
|
||||
auto pWork = reinterpret_cast<const uint32_t*>(&M.m[0][0]);
|
||||
do {
|
||||
do
|
||||
{
|
||||
// Fetch value into integer unit
|
||||
uint32_t uTest = pWork[0];
|
||||
// Remove sign
|
||||
@ -110,27 +115,35 @@ inline bool XM_CALLCONV XMMatrixIsInfinite(FXMMATRIX M) noexcept
|
||||
break; // INF found
|
||||
}
|
||||
++pWork; // Next entry
|
||||
} while (--i);
|
||||
}
|
||||
while (--i);
|
||||
return (i != 0); // i == 0 if nothing matched
|
||||
#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
|
||||
XMVECTOR vTemp1 = vandq_u32(M.r[0], g_XMAbsMask);
|
||||
XMVECTOR vTemp2 = vandq_u32(M.r[1], g_XMAbsMask);
|
||||
XMVECTOR vTemp3 = vandq_u32(M.r[2], g_XMAbsMask);
|
||||
XMVECTOR vTemp4 = vandq_u32(M.r[3], g_XMAbsMask);
|
||||
vX = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(vX), g_XMAbsMask));
|
||||
vY = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(vY), g_XMAbsMask));
|
||||
vZ = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(vZ), g_XMAbsMask));
|
||||
vW = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(vW), g_XMAbsMask));
|
||||
// Compare to infinity
|
||||
vTemp1 = vceqq_f32(vTemp1, g_XMInfinity);
|
||||
vTemp2 = vceqq_f32(vTemp2, g_XMInfinity);
|
||||
vTemp3 = vceqq_f32(vTemp3, g_XMInfinity);
|
||||
vTemp4 = vceqq_f32(vTemp4, g_XMInfinity);
|
||||
uint32x4_t xmask = vceqq_f32(vX, g_XMInfinity);
|
||||
uint32x4_t ymask = vceqq_f32(vY, g_XMInfinity);
|
||||
uint32x4_t zmask = vceqq_f32(vZ, g_XMInfinity);
|
||||
uint32x4_t wmask = vceqq_f32(vW, g_XMInfinity);
|
||||
// Or the answers together
|
||||
vTemp1 = vorrq_u32(vTemp1, vTemp2);
|
||||
vTemp3 = vorrq_u32(vTemp3, vTemp4);
|
||||
vTemp1 = vorrq_u32(vTemp1, vTemp3);
|
||||
// If any are infinity, the signs are true.
|
||||
uint8x8x2_t vTemp = vzip_u8(vget_low_u8(vTemp1), vget_high_u8(vTemp1));
|
||||
uint16x4x2_t vTemp5 = vzip_u16(vTemp.val[0], vTemp.val[1]);
|
||||
uint32_t r = vget_lane_u32(vTemp5.val[1], 1);
|
||||
xmask = vorrq_u32(xmask, zmask);
|
||||
ymask = vorrq_u32(ymask, wmask);
|
||||
xmask = vorrq_u32(xmask, ymask);
|
||||
// If any tested true, return true
|
||||
uint8x8x2_t vTemp = vzip_u8(
|
||||
vget_low_u8(vreinterpretq_u8_u32(xmask)),
|
||||
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);
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
// Mask off the sign bits
|
||||
@ -187,16 +200,16 @@ inline bool XM_CALLCONV XMMatrixIsIdentity(FXMMATRIX M) noexcept
|
||||
uOne |= uZero;
|
||||
return (uOne == 0);
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
XMVECTOR vTemp1 = vceqq_f32(M.r[0], g_XMIdentityR0);
|
||||
XMVECTOR vTemp2 = vceqq_f32(M.r[1], g_XMIdentityR1);
|
||||
XMVECTOR vTemp3 = vceqq_f32(M.r[2], g_XMIdentityR2);
|
||||
XMVECTOR vTemp4 = vceqq_f32(M.r[3], g_XMIdentityR3);
|
||||
vTemp1 = vandq_u32(vTemp1, vTemp2);
|
||||
vTemp3 = vandq_u32(vTemp3, vTemp4);
|
||||
vTemp1 = vandq_u32(vTemp1, vTemp3);
|
||||
uint8x8x2_t vTemp = vzip_u8(vget_low_u8(vTemp1), vget_high_u8(vTemp1));
|
||||
uint16x4x2_t vTemp5 = vzip_u16(vTemp.val[0], vTemp.val[1]);
|
||||
uint32_t r = vget_lane_u32(vTemp5.val[1], 1);
|
||||
uint32x4_t xmask = vceqq_f32(M.r[0], g_XMIdentityR0);
|
||||
uint32x4_t ymask = vceqq_f32(M.r[1], g_XMIdentityR1);
|
||||
uint32x4_t zmask = vceqq_f32(M.r[2], g_XMIdentityR2);
|
||||
uint32x4_t wmask = vceqq_f32(M.r[3], g_XMIdentityR3);
|
||||
xmask = vandq_u32(xmask, zmask);
|
||||
ymask = vandq_u32(ymask, wmask);
|
||||
xmask = vandq_u32(xmask, ymask);
|
||||
uint8x8x2_t vTemp = vzip_u8(vget_low_u8(vreinterpretq_u8_u32(xmask)), 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 == 0xFFFFFFFFU);
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
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 VH = vget_high_f32(M1.r[0]);
|
||||
// Perform the operation on the first row
|
||||
XMVECTOR vX = vmulq_lane_f32(M2.r[0], VL, 0);
|
||||
XMVECTOR vY = vmulq_lane_f32(M2.r[1], VL, 1);
|
||||
XMVECTOR vZ = vmlaq_lane_f32(vX, M2.r[2], VH, 0);
|
||||
XMVECTOR vW = vmlaq_lane_f32(vY, M2.r[3], VH, 1);
|
||||
float32x4_t vX = vmulq_lane_f32(M2.r[0], VL, 0);
|
||||
float32x4_t vY = vmulq_lane_f32(M2.r[1], VL, 1);
|
||||
float32x4_t vZ = vmlaq_lane_f32(vX, M2.r[2], VH, 0);
|
||||
float32x4_t vW = vmlaq_lane_f32(vY, M2.r[3], VH, 1);
|
||||
mResult.r[0] = vaddq_f32(vZ, vW);
|
||||
// Repeat for the other 3 rows
|
||||
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 VH = vget_high_f32(M1.r[0]);
|
||||
// Perform the operation on the first row
|
||||
XMVECTOR vX = vmulq_lane_f32(M2.r[0], VL, 0);
|
||||
XMVECTOR vY = vmulq_lane_f32(M2.r[1], VL, 1);
|
||||
XMVECTOR vZ = vmlaq_lane_f32(vX, M2.r[2], VH, 0);
|
||||
XMVECTOR vW = vmlaq_lane_f32(vY, M2.r[3], VH, 1);
|
||||
float32x4_t vX = vmulq_lane_f32(M2.r[0], VL, 0);
|
||||
float32x4_t vY = vmulq_lane_f32(M2.r[1], VL, 1);
|
||||
float32x4_t vZ = vmlaq_lane_f32(vX, M2.r[2], VH, 0);
|
||||
float32x4_t vW = vmlaq_lane_f32(vY, M2.r[3], VH, 1);
|
||||
float32x4_t r0 = vaddq_f32(vZ, vW);
|
||||
// Repeat for the other 3 rows
|
||||
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_)
|
||||
XMMATRIX M;
|
||||
M.r[0] = vandq_u32(Scale, g_XMMaskX);
|
||||
M.r[1] = vandq_u32(Scale, g_XMMaskY);
|
||||
M.r[2] = vandq_u32(Scale, g_XMMaskZ);
|
||||
M.r[0] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(Scale), g_XMMaskX));
|
||||
M.r[1] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(Scale), g_XMMaskY));
|
||||
M.r[2] = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(Scale), g_XMMaskZ));
|
||||
M.r[3] = g_XMIdentityR3.v;
|
||||
return M;
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
@ -1455,12 +1468,12 @@ inline XMMATRIX XM_CALLCONV XMMatrixRotationX(float Angle) noexcept
|
||||
float fCosAngle;
|
||||
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);
|
||||
|
||||
XMVECTOR T2 = vsetq_lane_f32(-fSinAngle, Zero, 1);
|
||||
float32x4_t T2 = vsetq_lane_f32(-fSinAngle, Zero, 1);
|
||||
T2 = vsetq_lane_f32(fCosAngle, T2, 2);
|
||||
|
||||
XMMATRIX M;
|
||||
@ -1528,12 +1541,12 @@ inline XMMATRIX XM_CALLCONV XMMatrixRotationY(float Angle) noexcept
|
||||
float fCosAngle;
|
||||
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);
|
||||
|
||||
XMVECTOR T2 = vsetq_lane_f32(fSinAngle, Zero, 0);
|
||||
float32x4_t T2 = vsetq_lane_f32(fSinAngle, Zero, 0);
|
||||
T2 = vsetq_lane_f32(fCosAngle, T2, 2);
|
||||
|
||||
XMMATRIX M;
|
||||
@ -1601,12 +1614,12 @@ inline XMMATRIX XM_CALLCONV XMMatrixRotationZ(float Angle) noexcept
|
||||
float fCosAngle;
|
||||
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);
|
||||
|
||||
XMVECTOR T1 = vsetq_lane_f32(-fSinAngle, Zero, 0);
|
||||
float32x4_t T1 = vsetq_lane_f32(-fSinAngle, Zero, 0);
|
||||
T1 = vsetq_lane_f32(fCosAngle, T1, 1);
|
||||
|
||||
XMMATRIX M;
|
||||
@ -1646,8 +1659,41 @@ inline XMMATRIX XM_CALLCONV XMMatrixRotationRollPitchYaw
|
||||
float Roll
|
||||
) 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);
|
||||
return XMMatrixRotationRollPitchYawFromVector(Angles);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -1657,8 +1703,69 @@ inline XMMATRIX XM_CALLCONV XMMatrixRotationRollPitchYawFromVector
|
||||
FXMVECTOR Angles // <Pitch, Yaw, Roll, undefined>
|
||||
) noexcept
|
||||
{
|
||||
XMVECTOR Q = XMQuaternionRotationRollPitchYawFromVector(Angles);
|
||||
return XMMatrixRotationQuaternion(Q);
|
||||
#if defined(_XM_NO_INTRINSICS_)
|
||||
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
|
||||
{
|
||||
#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 } } };
|
||||
|
||||
XMVECTOR Q0 = XMVectorAdd(Quaternion, Quaternion);
|
||||
@ -2166,7 +2307,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveLH
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
float TwoNearZ = NearZ + NearZ;
|
||||
float fRange = FarZ / (FarZ - NearZ);
|
||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
||||
const float32x4_t Zero = vdupq_n_f32(0);
|
||||
XMMATRIX M;
|
||||
M.r[0] = vsetq_lane_f32(TwoNearZ / ViewWidth, Zero, 0);
|
||||
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_)
|
||||
float TwoNearZ = NearZ + NearZ;
|
||||
float fRange = FarZ / (NearZ - FarZ);
|
||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
||||
const float32x4_t Zero = vdupq_n_f32(0);
|
||||
|
||||
XMMATRIX M;
|
||||
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 Height = CosFov / SinFov;
|
||||
float Width = Height / AspectRatio;
|
||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
||||
const float32x4_t Zero = vdupq_n_f32(0);
|
||||
|
||||
XMMATRIX M;
|
||||
M.r[0] = vsetq_lane_f32(Width, Zero, 0);
|
||||
@ -2378,10 +2519,10 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveFovLH
|
||||
XMVECTOR vTemp = _mm_setzero_ps();
|
||||
// Copy x only
|
||||
vTemp = _mm_move_ss(vTemp, vValues);
|
||||
// CosFov / SinFov,0,0,0
|
||||
// Height / AspectRatio,0,0,0
|
||||
XMMATRIX M;
|
||||
M.r[0] = vTemp;
|
||||
// 0,Height / AspectRatio,0,0
|
||||
// 0,Height,0,0
|
||||
vTemp = vValues;
|
||||
vTemp = _mm_and_ps(vTemp, g_XMMaskY);
|
||||
M.r[1] = vTemp;
|
||||
@ -2452,7 +2593,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveFovRH
|
||||
float fRange = FarZ / (NearZ - FarZ);
|
||||
float Height = CosFov / SinFov;
|
||||
float Width = Height / AspectRatio;
|
||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
||||
const float32x4_t Zero = vdupq_n_f32(0);
|
||||
|
||||
XMMATRIX M;
|
||||
M.r[0] = vsetq_lane_f32(Width, Zero, 0);
|
||||
@ -2478,10 +2619,10 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveFovRH
|
||||
XMVECTOR vTemp = _mm_setzero_ps();
|
||||
// Copy x only
|
||||
vTemp = _mm_move_ss(vTemp, vValues);
|
||||
// CosFov / SinFov,0,0,0
|
||||
// Height / AspectRatio,0,0,0
|
||||
XMMATRIX M;
|
||||
M.r[0] = vTemp;
|
||||
// 0,Height / AspectRatio,0,0
|
||||
// 0,Height,0,0
|
||||
vTemp = vValues;
|
||||
vTemp = _mm_and_ps(vTemp, g_XMMaskY);
|
||||
M.r[1] = vTemp;
|
||||
@ -2549,7 +2690,7 @@ inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveOffCenterLH
|
||||
float ReciprocalWidth = 1.0f / (ViewRight - ViewLeft);
|
||||
float ReciprocalHeight = 1.0f / (ViewTop - ViewBottom);
|
||||
float fRange = FarZ / (FarZ - NearZ);
|
||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
||||
const float32x4_t Zero = vdupq_n_f32(0);
|
||||
|
||||
XMMATRIX M;
|
||||
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 ReciprocalHeight = 1.0f / (ViewTop - ViewBottom);
|
||||
float fRange = FarZ / (NearZ - FarZ);
|
||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
||||
const float32x4_t Zero = vdupq_n_f32(0);
|
||||
|
||||
XMMATRIX M;
|
||||
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_)
|
||||
float fRange = 1.0f / (FarZ - NearZ);
|
||||
|
||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
||||
const float32x4_t Zero = vdupq_n_f32(0);
|
||||
XMMATRIX M;
|
||||
M.r[0] = vsetq_lane_f32(2.0f / ViewWidth, Zero, 0);
|
||||
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_)
|
||||
float fRange = 1.0f / (NearZ - FarZ);
|
||||
|
||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
||||
const float32x4_t Zero = vdupq_n_f32(0);
|
||||
XMMATRIX M;
|
||||
M.r[0] = vsetq_lane_f32(2.0f / ViewWidth, Zero, 0);
|
||||
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 ReciprocalHeight = 1.0f / (ViewTop - ViewBottom);
|
||||
float fRange = 1.0f / (FarZ - NearZ);
|
||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
||||
const float32x4_t Zero = vdupq_n_f32(0);
|
||||
XMMATRIX M;
|
||||
M.r[0] = vsetq_lane_f32(ReciprocalWidth + ReciprocalWidth, Zero, 0);
|
||||
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 ReciprocalHeight = 1.0f / (ViewTop - ViewBottom);
|
||||
float fRange = 1.0f / (NearZ - FarZ);
|
||||
const XMVECTOR Zero = vdupq_n_f32(0);
|
||||
const float32x4_t Zero = vdupq_n_f32(0);
|
||||
XMMATRIX M;
|
||||
M.r[0] = vsetq_lane_f32(ReciprocalWidth + ReciprocalWidth, Zero, 0);
|
||||
M.r[1] = vsetq_lane_f32(ReciprocalHeight + ReciprocalHeight, Zero, 1);
|
||||
@ -3164,7 +3305,7 @@ inline XMMATRIX& XMMATRIX::operator/= (float S) noexcept
|
||||
r[3] = XMVectorDivide(r[3], vS);
|
||||
return *this;
|
||||
#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);
|
||||
r[0] = vdivq_f32(r[0], vS);
|
||||
r[1] = vdivq_f32(r[1], vS);
|
||||
@ -3178,7 +3319,7 @@ inline XMMATRIX& XMMATRIX::operator/= (float S) noexcept
|
||||
R0 = vmul_f32(S0, R0);
|
||||
S0 = vrecps_f32(R0, vS);
|
||||
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[1] = vmulq_f32(r[1], 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);
|
||||
return R;
|
||||
#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);
|
||||
XMMATRIX R;
|
||||
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);
|
||||
S0 = vrecps_f32(R0, vS);
|
||||
R0 = vmul_f32(S0, R0);
|
||||
float32x4_t Reciprocal = vcombine_u32(R0, R0);
|
||||
float32x4_t Reciprocal = vcombine_f32(R0, R0);
|
||||
XMMATRIX R;
|
||||
R.r[0] = vmulq_f32(r[0], Reciprocal);
|
||||
R.r[1] = vmulq_f32(r[1], Reciprocal);
|
||||
@ -1,10 +1,10 @@
|
||||
//-------------------------------------------------------------------------------------
|
||||
// DirectXMathMisc.inl -- SIMD C++ Math library
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
//
|
||||
// http://go.microsoft.com/fwlink/?LinkID=615560
|
||||
// https://go.microsoft.com/fwlink/?LinkID=615560
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
@ -120,12 +120,12 @@ inline XMVECTOR XM_CALLCONV XMQuaternionMultiply
|
||||
vResult = vmlaq_f32(vResult, Q2X, ControlWZYX);
|
||||
|
||||
// Mul by Q1ZWXY
|
||||
vTemp = vrev64q_u32(vTemp);
|
||||
vTemp = vreinterpretq_f32_u32(vrev64q_u32(vreinterpretq_u32_f32(vTemp)));
|
||||
Q2Y = vmulq_f32(Q2Y, vTemp);
|
||||
vResult = vmlaq_f32(vResult, Q2Y, ControlZWXY);
|
||||
|
||||
// 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));
|
||||
Q2Z = vmulq_f32(Q2Z, vTemp);
|
||||
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
|
||||
{
|
||||
const XMVECTOR Zero = XMVectorZero();
|
||||
|
||||
XMVECTOR L = XMVector4LengthSq(Q);
|
||||
XMVECTOR Conjugate = XMQuaternionConjugate(Q);
|
||||
|
||||
@ -237,7 +235,7 @@ inline XMVECTOR XM_CALLCONV XMQuaternionInverse(FXMVECTOR Q) noexcept
|
||||
|
||||
XMVECTOR Result = XMVectorDivide(Conjugate, L);
|
||||
|
||||
Result = XMVectorSelect(Result, Zero, Control);
|
||||
Result = XMVectorSelect(Result, g_XMZero, Control);
|
||||
|
||||
return Result;
|
||||
}
|
||||
@ -582,9 +580,30 @@ inline XMVECTOR XM_CALLCONV XMQuaternionRotationRollPitchYaw
|
||||
float Roll
|
||||
) 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 Q = XMQuaternionRotationRollPitchYawFromVector(Angles);
|
||||
return Q;
|
||||
return XMQuaternionRotationRollPitchYawFromVector(Angles);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -594,6 +613,27 @@ inline XMVECTOR XM_CALLCONV XMQuaternionRotationRollPitchYawFromVector
|
||||
FXMVECTOR Angles // <Pitch, Yaw, Roll, 0>
|
||||
) 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 } } };
|
||||
|
||||
XMVECTOR HalfAngles = XMVectorMultiply(Angles, g_XMOneHalf.v);
|
||||
@ -615,6 +655,7 @@ inline XMVECTOR XM_CALLCONV XMQuaternionRotationRollPitchYawFromVector
|
||||
XMVECTOR Q = XMVectorMultiplyAdd(Q1, R1, Q0);
|
||||
|
||||
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 Select0010 = { { { XM_SELECT_0, XM_SELECT_0, XM_SELECT_1, XM_SELECT_0 } } };
|
||||
|
||||
XMVECTOR r0 = M.r[0];
|
||||
XMVECTOR r1 = M.r[1];
|
||||
XMVECTOR r2 = M.r[2];
|
||||
float32x4_t r0 = M.r[0];
|
||||
float32x4_t r1 = M.r[1];
|
||||
float32x4_t r2 = M.r[2];
|
||||
|
||||
XMVECTOR r00 = vdupq_lane_f32(vget_low_f32(r0), 0);
|
||||
XMVECTOR r11 = vdupq_lane_f32(vget_low_f32(r1), 1);
|
||||
XMVECTOR r22 = vdupq_lane_f32(vget_high_f32(r2), 0);
|
||||
float32x4_t r00 = vdupq_lane_f32(vget_low_f32(r0), 0);
|
||||
float32x4_t r11 = vdupq_lane_f32(vget_low_f32(r1), 1);
|
||||
float32x4_t r22 = vdupq_lane_f32(vget_high_f32(r2), 0);
|
||||
|
||||
// x^2 >= y^2 equivalent to r11 - r00 <= 0
|
||||
XMVECTOR r11mr00 = vsubq_f32(r11, r00);
|
||||
XMVECTOR x2gey2 = vcleq_f32(r11mr00, g_XMZero);
|
||||
float32x4_t r11mr00 = vsubq_f32(r11, r00);
|
||||
uint32x4_t x2gey2 = vcleq_f32(r11mr00, g_XMZero);
|
||||
|
||||
// z^2 >= w^2 equivalent to r11 + r00 <= 0
|
||||
XMVECTOR r11pr00 = vaddq_f32(r11, r00);
|
||||
XMVECTOR z2gew2 = vcleq_f32(r11pr00, g_XMZero);
|
||||
float32x4_t r11pr00 = vaddq_f32(r11, r00);
|
||||
uint32x4_t z2gew2 = vcleq_f32(r11pr00, g_XMZero);
|
||||
|
||||
// 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)
|
||||
XMVECTOR t0 = vmulq_f32(XMPMMP, r00);
|
||||
XMVECTOR x2y2z2w2 = vmlaq_f32(t0, XMMPMP, r11);
|
||||
float32x4_t t0 = vmulq_f32(XMPMMP, r00);
|
||||
float32x4_t x2y2z2w2 = vmlaq_f32(t0, XMMPMP, r11);
|
||||
x2y2z2w2 = vmlaq_f32(x2y2z2w2, XMMMPP, r22);
|
||||
x2y2z2w2 = vaddq_f32(x2y2z2w2, g_XMOne);
|
||||
|
||||
// (r01, r02, r12, r11)
|
||||
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)));
|
||||
|
||||
// (r10, r20, r21, r10)
|
||||
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);
|
||||
|
||||
// (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)
|
||||
t0 = vcombine_f32(vrev64_f32(vget_low_f32(r2)), vget_low_f32(r10));
|
||||
|
||||
// (r12, r02, r01, r12)
|
||||
XMVECTOR 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 t2 = vcombine_f32(vrev64_f32(vget_high_f32(r0)), vrev64_f32(vget_low_f32(r0)));
|
||||
float32x4_t t3 = vdupq_lane_f32(vget_high_f32(r1), 0);
|
||||
t1 = vbslq_f32(Select0110, t2, t3);
|
||||
|
||||
// (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);
|
||||
|
||||
// (4*x*x, 4*x*y, 4*x*z, 4*x*w)
|
||||
t0 = vextq_f32(xyxzyz, xyxzyz, 3);
|
||||
t1 = vbslq_f32(Select0110, t0, x2y2z2w2);
|
||||
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)
|
||||
t0 = vbslq_f32(g_XMSelect1011, xyxzyz, x2y2z2w2);
|
||||
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)
|
||||
t0 = vextq_f32(xyxzyz, xyxzyz, 1);
|
||||
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)
|
||||
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
|
||||
// magnitude.
|
||||
@ -1176,7 +1217,7 @@ inline void XM_CALLCONV XMPlaneIntersectPlane
|
||||
inline XMVECTOR XM_CALLCONV XMPlaneTransform
|
||||
(
|
||||
FXMVECTOR P,
|
||||
FXMMATRIX M
|
||||
FXMMATRIX ITM
|
||||
) noexcept
|
||||
{
|
||||
XMVECTOR W = XMVectorSplatW(P);
|
||||
@ -1184,10 +1225,10 @@ inline XMVECTOR XM_CALLCONV XMPlaneTransform
|
||||
XMVECTOR Y = XMVectorSplatY(P);
|
||||
XMVECTOR X = XMVectorSplatX(P);
|
||||
|
||||
XMVECTOR Result = XMVectorMultiply(W, M.r[3]);
|
||||
Result = XMVectorMultiplyAdd(Z, M.r[2], Result);
|
||||
Result = XMVectorMultiplyAdd(Y, M.r[1], Result);
|
||||
Result = XMVectorMultiplyAdd(X, M.r[0], Result);
|
||||
XMVECTOR Result = XMVectorMultiply(W, ITM.r[3]);
|
||||
Result = XMVectorMultiplyAdd(Z, ITM.r[2], Result);
|
||||
Result = XMVectorMultiplyAdd(Y, ITM.r[1], Result);
|
||||
Result = XMVectorMultiplyAdd(X, ITM.r[0], Result);
|
||||
return Result;
|
||||
}
|
||||
|
||||
@ -1200,7 +1241,7 @@ inline XMFLOAT4* XM_CALLCONV XMPlaneTransformStream
|
||||
const XMFLOAT4* pInputStream,
|
||||
size_t InputStride,
|
||||
size_t PlaneCount,
|
||||
FXMMATRIX M
|
||||
FXMMATRIX ITM
|
||||
) noexcept
|
||||
{
|
||||
return XMVector4TransformStream(pOutputStream,
|
||||
@ -1208,7 +1249,7 @@ inline XMFLOAT4* XM_CALLCONV XMPlaneTransformStream
|
||||
pInputStream,
|
||||
InputStride,
|
||||
PlaneCount,
|
||||
M);
|
||||
ITM);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -1358,8 +1399,8 @@ inline XMVECTOR XM_CALLCONV XMColorNegative(FXMVECTOR vColor) noexcept
|
||||
} } };
|
||||
return vResult.v;
|
||||
#elif defined(_XM_ARM_NEON_INTRINSICS_)
|
||||
XMVECTOR vTemp = veorq_u32(vColor, g_XMNegate3);
|
||||
return vaddq_f32(vTemp, g_XMOne3);
|
||||
uint32x4_t vTemp = veorq_u32(vreinterpretq_u32_f32(vColor), g_XMNegate3);
|
||||
return vaddq_f32(vreinterpretq_f32_u32(vTemp), g_XMOne3);
|
||||
#elif defined(_XM_SSE_INTRINSICS_)
|
||||
// Negate only x,y and z.
|
||||
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
|
||||
@ -1558,7 +1599,7 @@ namespace Internal
|
||||
return p;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace MathInternal
|
||||
|
||||
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 r = DirectX::Internal::XMColorHue2Clr(p, q, XMVectorAdd(h, oneThird));
|
||||
XMVECTOR g = DirectX::Internal::XMColorHue2Clr(p, q, h);
|
||||
XMVECTOR b = DirectX::Internal::XMColorHue2Clr(p, q, XMVectorSubtract(h, oneThird));
|
||||
XMVECTOR r = DirectX::MathInternal::XMColorHue2Clr(p, q, XMVectorAdd(h, oneThird));
|
||||
XMVECTOR g = DirectX::MathInternal::XMColorHue2Clr(p, q, h);
|
||||
XMVECTOR b = DirectX::MathInternal::XMColorHue2Clr(p, q, XMVectorSubtract(h, oneThird));
|
||||
|
||||
XMVECTOR rg = XMVectorSelect(g, r, g_XMSelect1000);
|
||||
XMVECTOR ba = XMVectorSelect(hsl, b, 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
|
||||
{
|
||||
static const XMVECTORF32 Scale0 = { { { 0.4887180f, 0.1762044f, 0.0000000f, 0.0f } } };
|
||||
@ -1903,9 +1971,9 @@ inline XMVECTOR XM_CALLCONV XMColorSRGBToRGB(FXMVECTOR srgb) 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 };
|
||||
#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]);
|
||||
#else
|
||||
__cpuid(CPUInfo, 0);
|
||||
@ -1919,7 +1987,7 @@ inline bool XMVerifyCPUSupport() noexcept
|
||||
return false;
|
||||
#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]);
|
||||
#else
|
||||
__cpuid(CPUInfo, 1);
|
||||
@ -1954,7 +2022,7 @@ inline bool XMVerifyCPUSupport() noexcept
|
||||
return false; // No SSE2/SSE support
|
||||
|
||||
#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]);
|
||||
#else
|
||||
__cpuidex(CPUInfo, 7, 0);
|
||||
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
||||
#include "memory.h"
|
||||
#include "node.h"
|
||||
|
||||
#include "directxmath/directxmath.h"
|
||||
#include "directxmath/DirectXMath.h"
|
||||
|
||||
size_t node_alloc(int count)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user