i'm using Swagger to document my Lumen API and im using annotations. The thing is, i don't know how to achieve the structure that you can see on the picture with annotations
Can anyone help me with this?
I finally found the answer to this and how to get the structure that i wanted:
#OA\RequestBody(
* #OA\JsonContent(
* type="object",
* #OA\Property(property="idNumber", type="string"),
* #OA\Property(property="ClientId", type="string"),
* #OA\Property(property="inspection", type="array",
* #OA\Items(type="object", properties = {
* #OA\Property(property="Color", type="string"),
* #OA\Property(property="time", type="string"),
* #OA\Property(property="place", type="string"),
* #OA\Property(property="issue", type="string"),
* #OA\Property(property="details", type="string"),
* }),
* ),
* #OA\Property(property="detailId", type="string"),
* #OA\Property(property="WayPayment", type="array",
* #OA\Items(type="object", properties = {
* #OA\Property(property="banking", type="string"),
* #OA\Property(property="numbercard", type="string"),
* #OA\Property(property="numberpayment", type="string"),
* }),
* ),
* ),
* ),
Related
So, I have the following security vulnerability in activesupport, activerecord and actionpack.
Name: actionpack
Version: 5.2.8.1
CVE: CVE-2023-22792
GHSA: GHSA-p84v-45xj-wwqj
Criticality: Unknown
URL: https://github.com/rails/rails/releases/tag/v7.0.4.1
Title: ReDoS based DoS vulnerability in Action Dispatch
Solution: upgrade to '~> 5.2.8, >= 5.2.8.15', '~> 6.1.7, >= 6.1.7.1', '>= 7.0.4.1'
Name: activerecord
Version: 5.2.8.1
CVE: CVE-2022-44566
GHSA: GHSA-579w-22j4-4749
Criticality: Unknown
URL: https://github.com/rails/rails/releases/tag/v7.0.4.1
Title: Denial of Service Vulnerability in ActiveRecord’s PostgreSQL adapter
Solution: upgrade to '~> 5.2.8, >= 5.2.8.15', '~> 6.1.7, >= 6.1.7.1', '>= 7.0.4.1'
Name: activesupport
Version: 5.2.8.1
CVE: CVE-2023-22796
GHSA: GHSA-j6gc-792m-qgm2
Criticality: Unknown
URL: https://github.com/rails/rails/releases/tag/v7.0.4.1
Title: ReDoS based DoS vulnerability in Active Support’s underscore
Solution: upgrade to '~> 5.2.8, >= 5.2.8.15', '~> 6.1.7, >= 6.1.7.1', '>= 7.0.4.1'
my rails version from gemfile
gem 'rails', '~> 5.2.8', '>= 5.2.8.1'
as the solution suggests upgrade to '~> 5.2.8, >= 5.2.8.15' seems to be the next step. so I changed the gemfile as follows:
gem 'rails', '~> 5.2.8', '>= 5.2.8.15'
and then bundle install' | I've also done bundle update` which produces the same output as the following
Fetching gem metadata from https://rubygems.org/..........
Could not find gem 'rails (~> 5.2.8, >= 5.2.8.15)' in rubygems repository https://rubygems.org/ or installed locally.
The source contains the following gems matching 'rails':
* rails-0.8.0
* rails-0.8.5
* rails-0.9.0
* rails-0.9.1
* rails-0.9.2
* rails-0.9.3
* rails-0.9.4
* rails-0.9.4.1
* rails-0.9.5
* rails-0.10.0
* rails-0.10.1
* rails-0.11.0
* rails-0.11.1
* rails-0.12.0
* rails-0.12.1
* rails-0.13.0
* rails-0.13.1
* rails-0.14.1
* rails-0.14.2
* rails-0.14.3
* rails-0.14.4
* rails-1.0.0
* rails-1.1.0
* rails-1.1.1
* rails-1.1.2
* rails-1.1.3
* rails-1.1.4
* rails-1.1.5
* rails-1.1.6
* rails-1.2.0
* rails-1.2.1
* rails-1.2.2
* rails-1.2.3
* rails-1.2.4
* rails-1.2.5
* rails-1.2.6
* rails-2.0.0
* rails-2.0.1
* rails-2.0.2
* rails-2.0.4
* rails-2.0.5
* rails-2.1.0
* rails-2.1.1
* rails-2.1.2
* rails-2.2.2
* rails-2.2.3
* rails-2.3.2
* rails-2.3.3
* rails-2.3.4
* rails-2.3.5
* rails-2.3.6
* rails-2.3.7
* rails-2.3.8.pre1
* rails-2.3.8
* rails-2.3.9.pre
* rails-2.3.9
* rails-2.3.10
* rails-2.3.11
* rails-2.3.12
* rails-2.3.14
* rails-2.3.15
* rails-2.3.16
* rails-2.3.17
* rails-2.3.18
* rails-3.0.0.beta
* rails-3.0.0.beta2
* rails-3.0.0.beta3
* rails-3.0.0.beta4
* rails-3.0.0.rc
* rails-3.0.0.rc2
* rails-3.0.0
* rails-3.0.1
* rails-3.0.2
* rails-3.0.3
* rails-3.0.4.rc1
* rails-3.0.4
* rails-3.0.5.rc1
* rails-3.0.5
* rails-3.0.6.rc1
* rails-3.0.6.rc2
* rails-3.0.6
* rails-3.0.7.rc1
* rails-3.0.7.rc2
* rails-3.0.7
* rails-3.0.8.rc1
* rails-3.0.8.rc2
* rails-3.0.8.rc4
* rails-3.0.8
* rails-3.0.9.rc1
* rails-3.0.9.rc3
* rails-3.0.9.rc4
* rails-3.0.9.rc5
* rails-3.0.9
* rails-3.0.10.rc1
* rails-3.0.10
* rails-3.0.11
* rails-3.0.12.rc1
* rails-3.0.12
* rails-3.0.13.rc1
* rails-3.0.13
* rails-3.0.14
* rails-3.0.15
* rails-3.0.16
* rails-3.0.17
* rails-3.0.18
* rails-3.0.19
* rails-3.0.20
* rails-3.1.0.beta1
* rails-3.1.0.rc1
* rails-3.1.0.rc2
* rails-3.1.0.rc3
* rails-3.1.0.rc4
* rails-3.1.0.rc5
* rails-3.1.0.rc6
* rails-3.1.0.rc8
* rails-3.1.0
* rails-3.1.1.rc1
* rails-3.1.1.rc2
* rails-3.1.1.rc3
* rails-3.1.1
* rails-3.1.2.rc1
* rails-3.1.2.rc2
* rails-3.1.2
* rails-3.1.3
* rails-3.1.4.rc1
* rails-3.1.4
* rails-3.1.5.rc1
* rails-3.1.5
* rails-3.1.6
* rails-3.1.7
* rails-3.1.8
* rails-3.1.9
* rails-3.1.10
* rails-3.1.11
* rails-3.1.12
* rails-3.2.0.rc1
* rails-3.2.0.rc2
* rails-3.2.0
* rails-3.2.1
* rails-3.2.2.rc1
* rails-3.2.2
* rails-3.2.3.rc1
* rails-3.2.3.rc2
* rails-3.2.3
* rails-3.2.4.rc1
* rails-3.2.4
* rails-3.2.5
* rails-3.2.6
* rails-3.2.7.rc1
* rails-3.2.7
* rails-3.2.8.rc1
* rails-3.2.8.rc2
* rails-3.2.8
* rails-3.2.9.rc1
* rails-3.2.9.rc2
* rails-3.2.9.rc3
* rails-3.2.9
* rails-3.2.10
* rails-3.2.11
* rails-3.2.12
* rails-3.2.13.rc1
* rails-3.2.13.rc2
* rails-3.2.13
* rails-3.2.14.rc1
* rails-3.2.14.rc2
* rails-3.2.14
* rails-3.2.15.rc1
* rails-3.2.15.rc2
* rails-3.2.15.rc3
* rails-3.2.15
* rails-3.2.16
* rails-3.2.17
* rails-3.2.18
* rails-3.2.19
* rails-3.2.20
* rails-3.2.21
* rails-3.2.22
* rails-3.2.22.1
* rails-3.2.22.2
* rails-3.2.22.3
* rails-3.2.22.4
* rails-3.2.22.5
* rails-4.0.0.beta1
* rails-4.0.0.rc1
* rails-4.0.0.rc2
* rails-4.0.0
* rails-4.0.1.rc1
* rails-4.0.1.rc2
* rails-4.0.1.rc3
* rails-4.0.1.rc4
* rails-4.0.1
* rails-4.0.2
* rails-4.0.3
* rails-4.0.4.rc1
* rails-4.0.4
* rails-4.0.5
* rails-4.0.6.rc1
* rails-4.0.6.rc2
* rails-4.0.6.rc3
* rails-4.0.6
* rails-4.0.7
* rails-4.0.8
* rails-4.0.9
* rails-4.0.10.rc1
* rails-4.0.10.rc2
* rails-4.0.10
* rails-4.0.11
* rails-4.0.11.1
* rails-4.0.12
* rails-4.0.13.rc1
* rails-4.0.13
* rails-4.1.0.beta1
* rails-4.1.0.beta2
* rails-4.1.0.rc1
* rails-4.1.0.rc2
* rails-4.1.0
* rails-4.1.1
* rails-4.1.2.rc1
* rails-4.1.2.rc2
* rails-4.1.2.rc3
* rails-4.1.2
* rails-4.1.3
* rails-4.1.4
* rails-4.1.5
* rails-4.1.6.rc1
* rails-4.1.6.rc2
* rails-4.1.6
* rails-4.1.7
* rails-4.1.7.1
* rails-4.1.8
* rails-4.1.9.rc1
* rails-4.1.9
* rails-4.1.10.rc1
* rails-4.1.10.rc2
* rails-4.1.10.rc3
* rails-4.1.10.rc4
* rails-4.1.10
* rails-4.1.11
* rails-4.1.12.rc1
* rails-4.1.12
* rails-4.1.13.rc1
* rails-4.1.13
* rails-4.1.14.rc1
* rails-4.1.14.rc2
* rails-4.1.14
* rails-4.1.14.1
* rails-4.1.14.2
* rails-4.1.15.rc1
* rails-4.1.15
* rails-4.1.16.rc1
* rails-4.1.16
* rails-4.2.0.beta1
* rails-4.2.0.beta2
* rails-4.2.0.beta3
* rails-4.2.0.beta4
* rails-4.2.0.rc1
* rails-4.2.0.rc2
* rails-4.2.0.rc3
* rails-4.2.0
* rails-4.2.1.rc1
* rails-4.2.1.rc2
* rails-4.2.1.rc3
* rails-4.2.1.rc4
* rails-4.2.1
* rails-4.2.2
* rails-4.2.3.rc1
* rails-4.2.3
* rails-4.2.4.rc1
* rails-4.2.4
* rails-4.2.5.rc1
* rails-4.2.5.rc2
* rails-4.2.5
* rails-4.2.5.1
* rails-4.2.5.2
* rails-4.2.6.rc1
* rails-4.2.6
* rails-4.2.7.rc1
* rails-4.2.7
* rails-4.2.7.1
* rails-4.2.8.rc1
* rails-4.2.8
* rails-4.2.9.rc1
* rails-4.2.9.rc2
* rails-4.2.9
* rails-4.2.10.rc1
* rails-4.2.10
* rails-4.2.11
* rails-4.2.11.1
* rails-4.2.11.2
* rails-4.2.11.3
* rails-5.0.0.beta1
* rails-5.0.0.beta1.1
* rails-5.0.0.beta2
* rails-5.0.0.beta3
* rails-5.0.0.beta4
* rails-5.0.0.racecar1
* rails-5.0.0.rc1
* rails-5.0.0.rc2
* rails-5.0.0
* rails-5.0.0.1
* rails-5.0.1.rc1
* rails-5.0.1.rc2
* rails-5.0.1
* rails-5.0.2.rc1
* rails-5.0.2
* rails-5.0.3
* rails-5.0.4.rc1
* rails-5.0.4
* rails-5.0.5.rc1
* rails-5.0.5.rc2
* rails-5.0.5
* rails-5.0.6.rc1
* rails-5.0.6
* rails-5.0.7
* rails-5.0.7.1
* rails-5.0.7.2
* rails-5.1.0.beta1
* rails-5.1.0.rc1
* rails-5.1.0.rc2
* rails-5.1.0
* rails-5.1.1
* rails-5.1.2.rc1
* rails-5.1.2
* rails-5.1.3.rc1
* rails-5.1.3.rc2
* rails-5.1.3.rc3
* rails-5.1.3
* rails-5.1.4.rc1
* rails-5.1.4
* rails-5.1.5.rc1
* rails-5.1.5
* rails-5.1.6
* rails-5.1.6.1
* rails-5.1.6.2
* rails-5.1.7.rc1
* rails-5.1.7
* rails-5.2.0.beta1
* rails-5.2.0.beta2
* rails-5.2.0.rc1
* rails-5.2.0.rc2
* rails-5.2.0
* rails-5.2.1.rc1
* rails-5.2.1
* rails-5.2.1.1
* rails-5.2.2.rc1
* rails-5.2.2
* rails-5.2.2.1
* rails-5.2.3.rc1
* rails-5.2.3
* rails-5.2.4.rc1
* rails-5.2.4
* rails-5.2.4.1
* rails-5.2.4.2
* rails-5.2.4.3
* rails-5.2.4.4
* rails-5.2.4.5
* rails-5.2.4.6
* rails-5.2.5
* rails-5.2.6
* rails-5.2.6.1
* rails-5.2.6.2
* rails-5.2.6.3
* rails-5.2.7
* rails-5.2.7.1
* rails-5.2.8
* rails-5.2.8.1
* rails-6.0.0.beta1
* rails-6.0.0.beta2
* rails-6.0.0.beta3
* rails-6.0.0.rc1
* rails-6.0.0.rc2
* rails-6.0.0
* rails-6.0.1.rc1
* rails-6.0.1
* rails-6.0.2.rc1
* rails-6.0.2.rc2
* rails-6.0.2
* rails-6.0.2.1
* rails-6.0.2.2
* rails-6.0.3.rc1
* rails-6.0.3
* rails-6.0.3.1
* rails-6.0.3.2
* rails-6.0.3.3
* rails-6.0.3.4
* rails-6.0.3.5
* rails-6.0.3.6
* rails-6.0.3.7
* rails-6.0.4
* rails-6.0.4.1
* rails-6.0.4.2
* rails-6.0.4.3
* rails-6.0.4.4
* rails-6.0.4.5
* rails-6.0.4.6
* rails-6.0.4.7
* rails-6.0.4.8
* rails-6.0.5
* rails-6.0.5.1
* rails-6.0.6
* rails-6.0.6.1
* rails-6.1.0.rc1
* rails-6.1.0.rc2
* rails-6.1.0
* rails-6.1.1
* rails-6.1.2
* rails-6.1.2.1
* rails-6.1.3
* rails-6.1.3.1
* rails-6.1.3.2
* rails-6.1.4
* rails-6.1.4.1
* rails-6.1.4.2
* rails-6.1.4.3
* rails-6.1.4.4
* rails-6.1.4.5
* rails-6.1.4.6
* rails-6.1.4.7
* rails-6.1.5
* rails-6.1.5.1
* rails-6.1.6
* rails-6.1.6.1
* rails-6.1.7
* rails-6.1.7.1
* rails-6.1.7.2
* rails-7.0.0.alpha1
* rails-7.0.0.alpha2
* rails-7.0.0.rc1
* rails-7.0.0.rc2
* rails-7.0.0.rc3
* rails-7.0.0
* rails-7.0.1
* rails-7.0.2
* rails-7.0.2.1
* rails-7.0.2.2
* rails-7.0.2.3
* rails-7.0.2.4
* rails-7.0.3
* rails-7.0.3.1
* rails-7.0.4
* rails-7.0.4.1
* rails-7.0.4.2
What am I doing wrong. how can i upgrade those three (activesupport, activerecord and actionpack)?
After defining new rules and versions in your Gemfile, run:
bundle update rails
This will update all direct dependencies of Rails too.
But! be sure the version exists on RubyGems: https://rubygems.org/gems/rails/versions (it seems that v5.2.8.15 does not exist).
I am using "nelmio/api-doc-bundle" 4.9 and I need to pass multi-dimenional array using swagger. In postman I am passing like this.
So far, I have tried this in swagger.
* #OA\Parameter(
* name="banner[]",
* in="query",
* description="Banner information",
* required=true,
* #OA\Schema(
* type="array",
* #OA\Items(
* type="array",
* #OA\Items(type="string", propertyNames="startDate")
* )
* ),
* ),
I want to specify the default JSON body for a POST request in Swagger-PHP. My annotations look like this:
/**
* Setup order
*
* #SWG\Post(
* path="/order/setup",
* operationId="setupOrder",
* tags={"Orders"},
* summary="Setup an order with status draft.",
* description="Setup an order with status draft",
* consumes={"application/json"},
* #SWG\Parameter(
* name="body",
* in="body",
* default="{}",
* description="Json order info body (customer and products info)",
* required=true,
* #SWG\Schema(type="string")
* ),
* #SWG\Response(
* response=200,
* description="successful operation"
* ),
* #SWG\Response(response=400, description="Bad request"),
* security={
* {"api_key_security_example": {}}
* }
* )
*
*/
As you can see I'm trying to achieve the default value with default="{}", but Swagger UI ignores this value and places 'string' instead as default value:
How can I change the 'string' part to a default JSON object?
You can achieve as you expected by modifying your #SWG\Parameter().
Example (look at example of the property):
* #SWG\Parameter(
* name="body",
* in="body",
* description="User email used to create account.",
* required=true,
* #SWG\Schema(#SWG\Property(property="email", type="string", example="email#example.com")),
* )
You can use like below.
/**
* Setup order
* #SWG\Post(
* path="/order/setup",
* operationId="setupOrder",
* tags={"Orders"},
* summary="Setup an order with status draft.",
* description="Setup an order with status draft",
* consumes={"application/json"},
* #SWG\Parameter(
* name="body",
* in="body",
* default="{}",
* description="Json order info body (customer and products info)",
* required=true,
* #SWG\Schema(ref="#/definitions/testDefinitions")
* ),
* #SWG\Response(
* response=200,
* description="successful operation"
* ),
* #SWG\Response(response=400, description="Bad request"),
* security={
* {"api_key_security_example": {}}
* }
* )
* #SWG\Definition(
* definition="PlanResponse",
* example={
* "type":"string"
* }
* )
*/
Thanks,
/**
* #SWG\POST(
* path="/visa-entry/calculate",
* operationId="visaEntryCalculate",
* tags={"Visa Entry"},
* summary="Calculate the price for an array of visa entries",
* description="Calculate the price for an array of visa entries",
*
* #SWG\Parameter(
* name="entries",
* in="body",
* description="Visa Entry IDs to calculate to total price",
* required=true,
* #SWG\Schema(
* type="array",
* #SWG\Items(type="number")
* ),
* collectionFormat="multi"
* ),
*
* #SWG\Response(
* response=200,
* description="OK"
* ),
*
* #SWG\Response(
* response=400,
* description="Bad request"
* ),
* )
*
* Calculates a visa entry
*/
What I'm trying to do is to receive an Array of numbers with the key entries.
entries: [1, 2, 3]
This docblock renders the following CURL.
curl -X POST "app.test/visa-entry/calculate" -H "accept: application/json" -H "Content-Type: application/json" -H "X-CSRF-TOKEN: " -d "[0]"
How can I get it to send the array with the key entries?
If you don't want the client to post the array directly in the request-body, but with a key, you'll need to specify the in=body parameter as type="object" and define the array as a property of that schema.
Like this:
/**
* #SWG\POST(
* path="/visa-entry/calculate",
* operationId="visaEntryCalculate",
* tags={"Visa Entry"},
* summary="Calculate the price for an array of visa entries",
* description="Calculate the price for an array of visa entries",
*
* #SWG\Parameter(
* in="body",
* name="json",
* description="Visa Entry IDs to calculate to total price",
* required=true,
* #SWG\Schema(
* type="object",
* #SWG\Property(
* property="entries",
* type="array",
* #SWG\Items(type="number")
* )
* ),
* collectionFormat="multi"
* ),
*
* #SWG\Response(
* response=200,
* description="OK"
* ),
*
* #SWG\Response(
* response=400,
* description="Bad request"
* ),
* )
*
* Calculates a visa entry
*/
var canvas;
var gl;
var shaderProgram;
var triangleVertexPositionBuffer;
var mvMatrix = mat4.create();
var mOrtho = mat4.create();
var width;
var height;
function start()
{
canvas = document.getElementById("glcanvas");
canvas.addEventListener("mousedown", getPosition, false);
width = canvas.width;
height = canvas.height;
initWebGL(canvas);
if (gl) {
initShaders();
initBuffers();
setInterval( drawScene, 15 );
}
}
function drawScene() {
gl.viewport(0,0,gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mat4.ortho(mOrtho, -gl.viewportWidth, gl.viewportWidth, -gl.viewportHeight, gl.viewportHeight, 0, -200);
mat4.identity(mvMatrix);
setMatrixUniforms();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);
}
function setMatrixUniforms() {
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mOrtho);
}
function initBuffers()
{
triangleVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
var vertices = [
0.0, 0.0, 0.0,
50.0, 50.0, 0.0,
50.0, 0.0, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
triangleVertexPositionBuffer.itemSize = 3;
triangleVertexPositionBuffer.numItems = 3;
}
function initShaders()
{
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Unable to initialize the shader program: " + gl.getProgramInfoLog(shader));
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
}
function initWebGL() {
gl = null;
try {
gl = canvas.getContext("experimental-webgl");
gl.viewportHeight = canvas.height;
gl.viewportWidth = canvas.width;
}
catch(e) {
}
if (!gl) {
alert("Unable to initialize WebGL. Your browser may not support it.");
}
}
function getPosition(event)
{
var x = event.clientX;
var y = event.clientY;
var viewportArray = [
0, 0, 700, 700
];
var modelPointArrayResults = [];
var success = GLU.unProject(
x, y, 0,
mvMatrix, mOrtho,
viewportArray, modelPointArrayResults);
alert("x:" + modelPointArrayResults[0] + " y:" + modelPointArrayResults[1]);
}
function getShader(gl, id) {
var shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}
var theSource = "";
var currentChild = shaderScript.firstChild;
while(currentChild) {
if (currentChild.nodeType == 3) {
theSource += currentChild.textContent;
}
currentChild = currentChild.nextSibling;
}
var shader;
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null; // Unknown shader type
}
gl.shaderSource(shader, theSource);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert("An error occurred compiling the shaders: " + gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
/*jslint white: false, onevar: false, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, sub: true, nomen: false */
/**
* This file contains code that may be under the following license:
*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
*
* See http://oss.sgi.com/projects/FreeB/ for more information.
*
* All code in this file which is NOT under the SGI FREE SOFTWARE LICENSE B
* is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
*
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/** #type {Object} */
var GLU = {};
(function($) {
/**
* Unproject a screen point.
*
* #param {number} winX the window point for the x value.
* #param {number} winY the window point for the y value.
* #param {number} winZ the window point for the z value.
* #param {Array.<number>} model the model-view matrix.
* #param {Array.<number>} proj the projection matrix.
* #param {Array.<number>} view the viewport coordinate array.
* #param {Array.<number>} objPos the model point result.
* #return {boolean} true if the unproject operation was successful, false otherwise.
*/
$.unProject = function(winX, winY, winZ, model, proj, view, objPos) {
/** #type {Array.<number>} */
var inp = [
winX,
winY,
winZ,
1.0
];
/** #type {Array.<number>} */
var finalMatrix = [];
$.multMatrices(model, proj, finalMatrix);
if (!$.invertMatrix(finalMatrix, finalMatrix)) {
return (false);
}
/* Map x and y from window coordinates */
inp[0] = (inp[0] - view[0]) / view[2];
inp[1] = (inp[1] - view[1]) / view[3];
/* Map to range -1 to 1 */
inp[0] = inp[0] * 2 - 1;
inp[1] = inp[1] * 2 - 1;
inp[2] = inp[2] * 2 - 1;
/** #type {Array.<number>} */
var out = [];
$.multMatrixVec(finalMatrix, inp, out);
if (out[3] === 0.0) {
return false;
}
out[0] /= out[3];
out[1] /= out[3];
out[2] /= out[3];
objPos[0] = out[0];
objPos[1] = out[1];
objPos[2] = out[2];
return true;
};
/**
* Multiply the matrix by the specified vector.
*
* #param {Array.<number>} matrix the matrix.
* #param {Array.<number>} inp the vector.
* #param {Array.<number>} out the output.
*/
$.multMatrixVec = function(matrix, inp, out) {
for (var i = 0; i < 4; i = i + 1) {
out[i] =
inp[0] * matrix[0 * 4 + i] +
inp[1] * matrix[1 * 4 + i] +
inp[2] * matrix[2 * 4 + i] +
inp[3] * matrix[3 * 4 + i];
}
};
/**
* Multiply the specified matrices.
*
* #param {Array.<number>} a the first matrix.
* #param {Array.<number>} b the second matrix.
* #param {Array.<number>} r the result.
*/
$.multMatrices = function(a, b, r) {
for (var i = 0; i < 4; i = i + 1) {
for (var j = 0; j < 4; j = j + 1) {
r[i * 4 + j] =
a[i * 4 + 0] * b[0 * 4 + j] +
a[i * 4 + 1] * b[1 * 4 + j] +
a[i * 4 + 2] * b[2 * 4 + j] +
a[i * 4 + 3] * b[3 * 4 + j];
}
}
};
/**
* Invert a matrix.
*
* #param {Array.<number>} m the matrix.
* #param {Array.<number>} invOut the inverted output.
* #return {boolean} true if successful, false otherwise.
*/
$.invertMatrix = function(m, invOut) {
/** #type {Array.<number>} */
var inv = [];
inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] +
m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10];
inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] -
m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10];
inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] +
m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9];
inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] -
m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9];
inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] -
m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10];
inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] +
m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10];
inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] -
m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9];
inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] +
m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9];
inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] +
m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6];
inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] -
m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6];
inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] +
m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5];
inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] -
m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5];
inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] -
m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6];
inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] +
m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6];
inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] -
m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5];
inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] +
m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5];
/** #type {number} */
var det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
if (det === 0) {
return false;
}
det = 1.0 / det;
for (var i = 0; i < 16; i = i + 1) {
invOut[i] = inv[i] * det;
}
return true;
};
}(GLU));
/* EOF */
start();
#glcanvas { width: 700px; height: 700px; background-color: black; margin: 0px; padding: 0px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.3.2/gl-matrix.js"></script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
uniform mat4 uMVMatrix;
void main(void) {
gl_Position = uMVMatrix * vec4(aVertexPosition, 1.0);
}
</script>
<canvas id="glcanvas" />
Library:
https://github.com/bringhurst/webgl-unproject
I have set up an example however the
y value is coming in as a negative value when it's supposed to be a positive value
and the coordinate space is looking like 300 square units after the conversion not 700 square units like things are supposed to be.
Also for some reason the
X and Y seem to be shifted a little bit out of place I'm not sure if this has to do with the canvas bounding rectangle. Does anyone know how to solve these issues?
My matrix library is the latest CDN of glMatrix. The idea is to click the canvas and get an alert to pop up.
Thank you!
function getPosition(event)
{
var x = event.clientX;
var y = event.clientY;
var viewportArray = [
0, 0, 700, 700
];
var modelPointArrayResults = [];
var success = GLU.unProject(
x, y, 0,
mvMatrix, mOrtho,
viewportArray, modelPointArrayResults);
alert("x:" + modelPointArrayResults[0] + " y:" + modelPointArrayResults[1]);
}
1) y value is coming in as a negative value when it's supposed to be a
positive value
In openGL, [-1, -1] is in the bottom-left corner of the viewport, [1, 1] in the top-right corner. The Y coordinate increase "upward".
gluUnProject, specificaly, expect y=0 to be the bottom of the canvas.
https://github.com/bringhurst/webgl-unproject/blob/master/GLU.js#L76
2) and the coordinate space is looking like 300 square units after the
conversion not 700 square units like things are supposed to be.
You only set the canvas css size. There is no relationship between css size of the canvas and it's width and height properties.
The css size only used to "stretch" and display the canvas to a given size (like an img).
The width and height set the actual pixels resolution of the canvas.
Since it's not set, it's default size is 300x150. It's the values you use to set your otho matrix, thus the result you get when unproject.
3) X and Y seem to be shifted a little bit out of place I'm not sure
if this has to do with the canvas bounding rectangle. Does anyone know
how to solve these issues?
You use mouse event's clientX and clientY as input to unproject. It's mouse coordinates relative to the browser screen. You need to give coordinates relative to canvas. The shift come from the default html margin