1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232 |
- import Cartesian3 from "./Cartesian3.js";
- import Cartesian4 from "./Cartesian4.js";
- import Check from "./Check.js";
- import defaultValue from "./defaultValue.js";
- import defined from "./defined.js";
- import DeveloperError from "./DeveloperError.js";
- import CesiumMath from "./Math.js";
- import Matrix3 from "./Matrix3.js";
- import RuntimeError from "./RuntimeError.js";
- /**
- * A 4x4 matrix, indexable as a column-major order array.
- * Constructor parameters are in row-major order for code readability.
- * @alias Matrix4
- * @constructor
- * @implements {ArrayLike<number>}
- *
- * @param {Number} [column0Row0=0.0] The value for column 0, row 0.
- * @param {Number} [column1Row0=0.0] The value for column 1, row 0.
- * @param {Number} [column2Row0=0.0] The value for column 2, row 0.
- * @param {Number} [column3Row0=0.0] The value for column 3, row 0.
- * @param {Number} [column0Row1=0.0] The value for column 0, row 1.
- * @param {Number} [column1Row1=0.0] The value for column 1, row 1.
- * @param {Number} [column2Row1=0.0] The value for column 2, row 1.
- * @param {Number} [column3Row1=0.0] The value for column 3, row 1.
- * @param {Number} [column0Row2=0.0] The value for column 0, row 2.
- * @param {Number} [column1Row2=0.0] The value for column 1, row 2.
- * @param {Number} [column2Row2=0.0] The value for column 2, row 2.
- * @param {Number} [column3Row2=0.0] The value for column 3, row 2.
- * @param {Number} [column0Row3=0.0] The value for column 0, row 3.
- * @param {Number} [column1Row3=0.0] The value for column 1, row 3.
- * @param {Number} [column2Row3=0.0] The value for column 2, row 3.
- * @param {Number} [column3Row3=0.0] The value for column 3, row 3.
- *
- * @see Matrix4.fromArray
- * @see Matrix4.fromColumnMajorArray
- * @see Matrix4.fromRowMajorArray
- * @see Matrix4.fromRotationTranslation
- * @see Matrix4.fromTranslationQuaternionRotationScale
- * @see Matrix4.fromTranslationRotationScale
- * @see Matrix4.fromTranslation
- * @see Matrix4.fromScale
- * @see Matrix4.fromUniformScale
- * @see Matrix4.fromRotation
- * @see Matrix4.fromCamera
- * @see Matrix4.computePerspectiveFieldOfView
- * @see Matrix4.computeOrthographicOffCenter
- * @see Matrix4.computePerspectiveOffCenter
- * @see Matrix4.computeInfinitePerspectiveOffCenter
- * @see Matrix4.computeViewportTransformation
- * @see Matrix4.computeView
- * @see Matrix2
- * @see Matrix3
- * @see Packable
- */
- function Matrix4(
- column0Row0,
- column1Row0,
- column2Row0,
- column3Row0,
- column0Row1,
- column1Row1,
- column2Row1,
- column3Row1,
- column0Row2,
- column1Row2,
- column2Row2,
- column3Row2,
- column0Row3,
- column1Row3,
- column2Row3,
- column3Row3
- ) {
- this[0] = defaultValue(column0Row0, 0.0);
- this[1] = defaultValue(column0Row1, 0.0);
- this[2] = defaultValue(column0Row2, 0.0);
- this[3] = defaultValue(column0Row3, 0.0);
- this[4] = defaultValue(column1Row0, 0.0);
- this[5] = defaultValue(column1Row1, 0.0);
- this[6] = defaultValue(column1Row2, 0.0);
- this[7] = defaultValue(column1Row3, 0.0);
- this[8] = defaultValue(column2Row0, 0.0);
- this[9] = defaultValue(column2Row1, 0.0);
- this[10] = defaultValue(column2Row2, 0.0);
- this[11] = defaultValue(column2Row3, 0.0);
- this[12] = defaultValue(column3Row0, 0.0);
- this[13] = defaultValue(column3Row1, 0.0);
- this[14] = defaultValue(column3Row2, 0.0);
- this[15] = defaultValue(column3Row3, 0.0);
- }
- /**
- * The number of elements used to pack the object into an array.
- * @type {Number}
- */
- Matrix4.packedLength = 16;
- /**
- * Stores the provided instance into the provided array.
- *
- * @param {Matrix4} value The value to pack.
- * @param {Number[]} array The array to pack into.
- * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
- *
- * @returns {Number[]} The array that was packed into
- */
- Matrix4.pack = function (value, array, startingIndex) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("value", value);
- Check.defined("array", array);
- //>>includeEnd('debug');
- startingIndex = defaultValue(startingIndex, 0);
- array[startingIndex++] = value[0];
- array[startingIndex++] = value[1];
- array[startingIndex++] = value[2];
- array[startingIndex++] = value[3];
- array[startingIndex++] = value[4];
- array[startingIndex++] = value[5];
- array[startingIndex++] = value[6];
- array[startingIndex++] = value[7];
- array[startingIndex++] = value[8];
- array[startingIndex++] = value[9];
- array[startingIndex++] = value[10];
- array[startingIndex++] = value[11];
- array[startingIndex++] = value[12];
- array[startingIndex++] = value[13];
- array[startingIndex++] = value[14];
- array[startingIndex] = value[15];
- return array;
- };
- /**
- * Retrieves an instance from a packed array.
- *
- * @param {Number[]} array The packed array.
- * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
- * @param {Matrix4} [result] The object into which to store the result.
- * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided.
- */
- Matrix4.unpack = function (array, startingIndex, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.defined("array", array);
- //>>includeEnd('debug');
- startingIndex = defaultValue(startingIndex, 0);
- if (!defined(result)) {
- result = new Matrix4();
- }
- result[0] = array[startingIndex++];
- result[1] = array[startingIndex++];
- result[2] = array[startingIndex++];
- result[3] = array[startingIndex++];
- result[4] = array[startingIndex++];
- result[5] = array[startingIndex++];
- result[6] = array[startingIndex++];
- result[7] = array[startingIndex++];
- result[8] = array[startingIndex++];
- result[9] = array[startingIndex++];
- result[10] = array[startingIndex++];
- result[11] = array[startingIndex++];
- result[12] = array[startingIndex++];
- result[13] = array[startingIndex++];
- result[14] = array[startingIndex++];
- result[15] = array[startingIndex];
- return result;
- };
- /**
- * Flattens an array of Matrix4s into an array of components. The components
- * are stored in column-major order.
- *
- * @param {Matrix4[]} array The array of matrices to pack.
- * @param {Number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 16 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 16) elements.
- * @returns {Number[]} The packed array.
- */
- Matrix4.packArray = function (array, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.defined("array", array);
- //>>includeEnd('debug');
- const length = array.length;
- const resultLength = length * 16;
- if (!defined(result)) {
- result = new Array(resultLength);
- } else if (!Array.isArray(result) && result.length !== resultLength) {
- //>>includeStart('debug', pragmas.debug);
- throw new DeveloperError(
- "If result is a typed array, it must have exactly array.length * 16 elements"
- );
- //>>includeEnd('debug');
- } else if (result.length !== resultLength) {
- result.length = resultLength;
- }
- for (let i = 0; i < length; ++i) {
- Matrix4.pack(array[i], result, i * 16);
- }
- return result;
- };
- /**
- * Unpacks an array of column-major matrix components into an array of Matrix4s.
- *
- * @param {Number[]} array The array of components to unpack.
- * @param {Matrix4[]} [result] The array onto which to store the result.
- * @returns {Matrix4[]} The unpacked array.
- */
- Matrix4.unpackArray = function (array, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.defined("array", array);
- Check.typeOf.number.greaterThanOrEquals("array.length", array.length, 16);
- if (array.length % 16 !== 0) {
- throw new DeveloperError("array length must be a multiple of 16.");
- }
- //>>includeEnd('debug');
- const length = array.length;
- if (!defined(result)) {
- result = new Array(length / 16);
- } else {
- result.length = length / 16;
- }
- for (let i = 0; i < length; i += 16) {
- const index = i / 16;
- result[index] = Matrix4.unpack(array, i, result[index]);
- }
- return result;
- };
- /**
- * Duplicates a Matrix4 instance.
- *
- * @param {Matrix4} matrix The matrix to duplicate.
- * @param {Matrix4} [result] The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. (Returns undefined if matrix is undefined)
- */
- Matrix4.clone = function (matrix, result) {
- if (!defined(matrix)) {
- return undefined;
- }
- if (!defined(result)) {
- return new Matrix4(
- matrix[0],
- matrix[4],
- matrix[8],
- matrix[12],
- matrix[1],
- matrix[5],
- matrix[9],
- matrix[13],
- matrix[2],
- matrix[6],
- matrix[10],
- matrix[14],
- matrix[3],
- matrix[7],
- matrix[11],
- matrix[15]
- );
- }
- result[0] = matrix[0];
- result[1] = matrix[1];
- result[2] = matrix[2];
- result[3] = matrix[3];
- result[4] = matrix[4];
- result[5] = matrix[5];
- result[6] = matrix[6];
- result[7] = matrix[7];
- result[8] = matrix[8];
- result[9] = matrix[9];
- result[10] = matrix[10];
- result[11] = matrix[11];
- result[12] = matrix[12];
- result[13] = matrix[13];
- result[14] = matrix[14];
- result[15] = matrix[15];
- return result;
- };
- /**
- * Creates a Matrix4 from 16 consecutive elements in an array.
- * @function
- *
- * @param {Number[]} array The array whose 16 consecutive elements correspond to the positions of the matrix. Assumes column-major order.
- * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to first column first row position in the matrix.
- * @param {Matrix4} [result] The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided.
- *
- * @example
- * // Create the Matrix4:
- * // [1.0, 2.0, 3.0, 4.0]
- * // [1.0, 2.0, 3.0, 4.0]
- * // [1.0, 2.0, 3.0, 4.0]
- * // [1.0, 2.0, 3.0, 4.0]
- *
- * const v = [1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0];
- * const m = Cesium.Matrix4.fromArray(v);
- *
- * // Create same Matrix4 with using an offset into an array
- * const v2 = [0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0];
- * const m2 = Cesium.Matrix4.fromArray(v2, 2);
- */
- Matrix4.fromArray = Matrix4.unpack;
- /**
- * Computes a Matrix4 instance from a column-major order array.
- *
- * @param {Number[]} values The column-major order array.
- * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created.
- * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided.
- */
- Matrix4.fromColumnMajorArray = function (values, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.defined("values", values);
- //>>includeEnd('debug');
- return Matrix4.clone(values, result);
- };
- /**
- * Computes a Matrix4 instance from a row-major order array.
- * The resulting matrix will be in column-major order.
- *
- * @param {Number[]} values The row-major order array.
- * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created.
- * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided.
- */
- Matrix4.fromRowMajorArray = function (values, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.defined("values", values);
- //>>includeEnd('debug');
- if (!defined(result)) {
- return new Matrix4(
- values[0],
- values[1],
- values[2],
- values[3],
- values[4],
- values[5],
- values[6],
- values[7],
- values[8],
- values[9],
- values[10],
- values[11],
- values[12],
- values[13],
- values[14],
- values[15]
- );
- }
- result[0] = values[0];
- result[1] = values[4];
- result[2] = values[8];
- result[3] = values[12];
- result[4] = values[1];
- result[5] = values[5];
- result[6] = values[9];
- result[7] = values[13];
- result[8] = values[2];
- result[9] = values[6];
- result[10] = values[10];
- result[11] = values[14];
- result[12] = values[3];
- result[13] = values[7];
- result[14] = values[11];
- result[15] = values[15];
- return result;
- };
- /**
- * Computes a Matrix4 instance from a Matrix3 representing the rotation
- * and a Cartesian3 representing the translation.
- *
- * @param {Matrix3} rotation The upper left portion of the matrix representing the rotation.
- * @param {Cartesian3} [translation=Cartesian3.ZERO] The upper right portion of the matrix representing the translation.
- * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created.
- * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided.
- */
- Matrix4.fromRotationTranslation = function (rotation, translation, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("rotation", rotation);
- //>>includeEnd('debug');
- translation = defaultValue(translation, Cartesian3.ZERO);
- if (!defined(result)) {
- return new Matrix4(
- rotation[0],
- rotation[3],
- rotation[6],
- translation.x,
- rotation[1],
- rotation[4],
- rotation[7],
- translation.y,
- rotation[2],
- rotation[5],
- rotation[8],
- translation.z,
- 0.0,
- 0.0,
- 0.0,
- 1.0
- );
- }
- result[0] = rotation[0];
- result[1] = rotation[1];
- result[2] = rotation[2];
- result[3] = 0.0;
- result[4] = rotation[3];
- result[5] = rotation[4];
- result[6] = rotation[5];
- result[7] = 0.0;
- result[8] = rotation[6];
- result[9] = rotation[7];
- result[10] = rotation[8];
- result[11] = 0.0;
- result[12] = translation.x;
- result[13] = translation.y;
- result[14] = translation.z;
- result[15] = 1.0;
- return result;
- };
- /**
- * Computes a Matrix4 instance from a translation, rotation, and scale (TRS)
- * representation with the rotation represented as a quaternion.
- *
- * @param {Cartesian3} translation The translation transformation.
- * @param {Quaternion} rotation The rotation transformation.
- * @param {Cartesian3} scale The non-uniform scale transformation.
- * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created.
- * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided.
- *
- * @example
- * const result = Cesium.Matrix4.fromTranslationQuaternionRotationScale(
- * new Cesium.Cartesian3(1.0, 2.0, 3.0), // translation
- * Cesium.Quaternion.IDENTITY, // rotation
- * new Cesium.Cartesian3(7.0, 8.0, 9.0), // scale
- * result);
- */
- Matrix4.fromTranslationQuaternionRotationScale = function (
- translation,
- rotation,
- scale,
- result
- ) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("translation", translation);
- Check.typeOf.object("rotation", rotation);
- Check.typeOf.object("scale", scale);
- //>>includeEnd('debug');
- if (!defined(result)) {
- result = new Matrix4();
- }
- const scaleX = scale.x;
- const scaleY = scale.y;
- const scaleZ = scale.z;
- const x2 = rotation.x * rotation.x;
- const xy = rotation.x * rotation.y;
- const xz = rotation.x * rotation.z;
- const xw = rotation.x * rotation.w;
- const y2 = rotation.y * rotation.y;
- const yz = rotation.y * rotation.z;
- const yw = rotation.y * rotation.w;
- const z2 = rotation.z * rotation.z;
- const zw = rotation.z * rotation.w;
- const w2 = rotation.w * rotation.w;
- const m00 = x2 - y2 - z2 + w2;
- const m01 = 2.0 * (xy - zw);
- const m02 = 2.0 * (xz + yw);
- const m10 = 2.0 * (xy + zw);
- const m11 = -x2 + y2 - z2 + w2;
- const m12 = 2.0 * (yz - xw);
- const m20 = 2.0 * (xz - yw);
- const m21 = 2.0 * (yz + xw);
- const m22 = -x2 - y2 + z2 + w2;
- result[0] = m00 * scaleX;
- result[1] = m10 * scaleX;
- result[2] = m20 * scaleX;
- result[3] = 0.0;
- result[4] = m01 * scaleY;
- result[5] = m11 * scaleY;
- result[6] = m21 * scaleY;
- result[7] = 0.0;
- result[8] = m02 * scaleZ;
- result[9] = m12 * scaleZ;
- result[10] = m22 * scaleZ;
- result[11] = 0.0;
- result[12] = translation.x;
- result[13] = translation.y;
- result[14] = translation.z;
- result[15] = 1.0;
- return result;
- };
- /**
- * Creates a Matrix4 instance from a {@link TranslationRotationScale} instance.
- *
- * @param {TranslationRotationScale} translationRotationScale The instance.
- * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created.
- * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided.
- */
- Matrix4.fromTranslationRotationScale = function (
- translationRotationScale,
- result
- ) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("translationRotationScale", translationRotationScale);
- //>>includeEnd('debug');
- return Matrix4.fromTranslationQuaternionRotationScale(
- translationRotationScale.translation,
- translationRotationScale.rotation,
- translationRotationScale.scale,
- result
- );
- };
- /**
- * Creates a Matrix4 instance from a Cartesian3 representing the translation.
- *
- * @param {Cartesian3} translation The upper right portion of the matrix representing the translation.
- * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created.
- * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided.
- *
- * @see Matrix4.multiplyByTranslation
- */
- Matrix4.fromTranslation = function (translation, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("translation", translation);
- //>>includeEnd('debug');
- return Matrix4.fromRotationTranslation(Matrix3.IDENTITY, translation, result);
- };
- /**
- * Computes a Matrix4 instance representing a non-uniform scale.
- *
- * @param {Cartesian3} scale The x, y, and z scale factors.
- * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created.
- * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided.
- *
- * @example
- * // Creates
- * // [7.0, 0.0, 0.0, 0.0]
- * // [0.0, 8.0, 0.0, 0.0]
- * // [0.0, 0.0, 9.0, 0.0]
- * // [0.0, 0.0, 0.0, 1.0]
- * const m = Cesium.Matrix4.fromScale(new Cesium.Cartesian3(7.0, 8.0, 9.0));
- */
- Matrix4.fromScale = function (scale, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("scale", scale);
- //>>includeEnd('debug');
- if (!defined(result)) {
- return new Matrix4(
- scale.x,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- scale.y,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- scale.z,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 1.0
- );
- }
- result[0] = scale.x;
- result[1] = 0.0;
- result[2] = 0.0;
- result[3] = 0.0;
- result[4] = 0.0;
- result[5] = scale.y;
- result[6] = 0.0;
- result[7] = 0.0;
- result[8] = 0.0;
- result[9] = 0.0;
- result[10] = scale.z;
- result[11] = 0.0;
- result[12] = 0.0;
- result[13] = 0.0;
- result[14] = 0.0;
- result[15] = 1.0;
- return result;
- };
- /**
- * Computes a Matrix4 instance representing a uniform scale.
- *
- * @param {Number} scale The uniform scale factor.
- * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created.
- * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided.
- *
- * @example
- * // Creates
- * // [2.0, 0.0, 0.0, 0.0]
- * // [0.0, 2.0, 0.0, 0.0]
- * // [0.0, 0.0, 2.0, 0.0]
- * // [0.0, 0.0, 0.0, 1.0]
- * const m = Cesium.Matrix4.fromUniformScale(2.0);
- */
- Matrix4.fromUniformScale = function (scale, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.number("scale", scale);
- //>>includeEnd('debug');
- if (!defined(result)) {
- return new Matrix4(
- scale,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- scale,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- scale,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 1.0
- );
- }
- result[0] = scale;
- result[1] = 0.0;
- result[2] = 0.0;
- result[3] = 0.0;
- result[4] = 0.0;
- result[5] = scale;
- result[6] = 0.0;
- result[7] = 0.0;
- result[8] = 0.0;
- result[9] = 0.0;
- result[10] = scale;
- result[11] = 0.0;
- result[12] = 0.0;
- result[13] = 0.0;
- result[14] = 0.0;
- result[15] = 1.0;
- return result;
- };
- /**
- * Creates a rotation matrix.
- *
- * @param {Matrix3} rotation The rotation matrix.
- * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created.
- * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided.
- */
- Matrix4.fromRotation = function (rotation, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("rotation", rotation);
- //>>includeEnd('debug');
- if (!defined(result)) {
- result = new Matrix4();
- }
- result[0] = rotation[0];
- result[1] = rotation[1];
- result[2] = rotation[2];
- result[3] = 0.0;
- result[4] = rotation[3];
- result[5] = rotation[4];
- result[6] = rotation[5];
- result[7] = 0.0;
- result[8] = rotation[6];
- result[9] = rotation[7];
- result[10] = rotation[8];
- result[11] = 0.0;
- result[12] = 0.0;
- result[13] = 0.0;
- result[14] = 0.0;
- result[15] = 1.0;
- return result;
- };
- const fromCameraF = new Cartesian3();
- const fromCameraR = new Cartesian3();
- const fromCameraU = new Cartesian3();
- /**
- * Computes a Matrix4 instance from a Camera.
- *
- * @param {Camera} camera The camera to use.
- * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created.
- * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided.
- */
- Matrix4.fromCamera = function (camera, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("camera", camera);
- //>>includeEnd('debug');
- const position = camera.position;
- const direction = camera.direction;
- const up = camera.up;
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("camera.position", position);
- Check.typeOf.object("camera.direction", direction);
- Check.typeOf.object("camera.up", up);
- //>>includeEnd('debug');
- Cartesian3.normalize(direction, fromCameraF);
- Cartesian3.normalize(
- Cartesian3.cross(fromCameraF, up, fromCameraR),
- fromCameraR
- );
- Cartesian3.normalize(
- Cartesian3.cross(fromCameraR, fromCameraF, fromCameraU),
- fromCameraU
- );
- const sX = fromCameraR.x;
- const sY = fromCameraR.y;
- const sZ = fromCameraR.z;
- const fX = fromCameraF.x;
- const fY = fromCameraF.y;
- const fZ = fromCameraF.z;
- const uX = fromCameraU.x;
- const uY = fromCameraU.y;
- const uZ = fromCameraU.z;
- const positionX = position.x;
- const positionY = position.y;
- const positionZ = position.z;
- const t0 = sX * -positionX + sY * -positionY + sZ * -positionZ;
- const t1 = uX * -positionX + uY * -positionY + uZ * -positionZ;
- const t2 = fX * positionX + fY * positionY + fZ * positionZ;
- // The code below this comment is an optimized
- // version of the commented lines.
- // Rather that create two matrices and then multiply,
- // we just bake in the multiplcation as part of creation.
- // const rotation = new Matrix4(
- // sX, sY, sZ, 0.0,
- // uX, uY, uZ, 0.0,
- // -fX, -fY, -fZ, 0.0,
- // 0.0, 0.0, 0.0, 1.0);
- // const translation = new Matrix4(
- // 1.0, 0.0, 0.0, -position.x,
- // 0.0, 1.0, 0.0, -position.y,
- // 0.0, 0.0, 1.0, -position.z,
- // 0.0, 0.0, 0.0, 1.0);
- // return rotation.multiply(translation);
- if (!defined(result)) {
- return new Matrix4(
- sX,
- sY,
- sZ,
- t0,
- uX,
- uY,
- uZ,
- t1,
- -fX,
- -fY,
- -fZ,
- t2,
- 0.0,
- 0.0,
- 0.0,
- 1.0
- );
- }
- result[0] = sX;
- result[1] = uX;
- result[2] = -fX;
- result[3] = 0.0;
- result[4] = sY;
- result[5] = uY;
- result[6] = -fY;
- result[7] = 0.0;
- result[8] = sZ;
- result[9] = uZ;
- result[10] = -fZ;
- result[11] = 0.0;
- result[12] = t0;
- result[13] = t1;
- result[14] = t2;
- result[15] = 1.0;
- return result;
- };
- /**
- * Computes a Matrix4 instance representing a perspective transformation matrix.
- *
- * @param {Number} fovY The field of view along the Y axis in radians.
- * @param {Number} aspectRatio The aspect ratio.
- * @param {Number} near The distance to the near plane in meters.
- * @param {Number} far The distance to the far plane in meters.
- * @param {Matrix4} result The object in which the result will be stored.
- * @returns {Matrix4} The modified result parameter.
- *
- * @exception {DeveloperError} fovY must be in (0, PI].
- * @exception {DeveloperError} aspectRatio must be greater than zero.
- * @exception {DeveloperError} near must be greater than zero.
- * @exception {DeveloperError} far must be greater than zero.
- */
- Matrix4.computePerspectiveFieldOfView = function (
- fovY,
- aspectRatio,
- near,
- far,
- result
- ) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.number.greaterThan("fovY", fovY, 0.0);
- Check.typeOf.number.lessThan("fovY", fovY, Math.PI);
- Check.typeOf.number.greaterThan("near", near, 0.0);
- Check.typeOf.number.greaterThan("far", far, 0.0);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const bottom = Math.tan(fovY * 0.5);
- const column1Row1 = 1.0 / bottom;
- const column0Row0 = column1Row1 / aspectRatio;
- const column2Row2 = (far + near) / (near - far);
- const column3Row2 = (2.0 * far * near) / (near - far);
- result[0] = column0Row0;
- result[1] = 0.0;
- result[2] = 0.0;
- result[3] = 0.0;
- result[4] = 0.0;
- result[5] = column1Row1;
- result[6] = 0.0;
- result[7] = 0.0;
- result[8] = 0.0;
- result[9] = 0.0;
- result[10] = column2Row2;
- result[11] = -1.0;
- result[12] = 0.0;
- result[13] = 0.0;
- result[14] = column3Row2;
- result[15] = 0.0;
- return result;
- };
- /**
- * Computes a Matrix4 instance representing an orthographic transformation matrix.
- *
- * @param {Number} left The number of meters to the left of the camera that will be in view.
- * @param {Number} right The number of meters to the right of the camera that will be in view.
- * @param {Number} bottom The number of meters below of the camera that will be in view.
- * @param {Number} top The number of meters above of the camera that will be in view.
- * @param {Number} near The distance to the near plane in meters.
- * @param {Number} far The distance to the far plane in meters.
- * @param {Matrix4} result The object in which the result will be stored.
- * @returns {Matrix4} The modified result parameter.
- */
- Matrix4.computeOrthographicOffCenter = function (
- left,
- right,
- bottom,
- top,
- near,
- far,
- result
- ) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.number("left", left);
- Check.typeOf.number("right", right);
- Check.typeOf.number("bottom", bottom);
- Check.typeOf.number("top", top);
- Check.typeOf.number("near", near);
- Check.typeOf.number("far", far);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- let a = 1.0 / (right - left);
- let b = 1.0 / (top - bottom);
- let c = 1.0 / (far - near);
- const tx = -(right + left) * a;
- const ty = -(top + bottom) * b;
- const tz = -(far + near) * c;
- a *= 2.0;
- b *= 2.0;
- c *= -2.0;
- result[0] = a;
- result[1] = 0.0;
- result[2] = 0.0;
- result[3] = 0.0;
- result[4] = 0.0;
- result[5] = b;
- result[6] = 0.0;
- result[7] = 0.0;
- result[8] = 0.0;
- result[9] = 0.0;
- result[10] = c;
- result[11] = 0.0;
- result[12] = tx;
- result[13] = ty;
- result[14] = tz;
- result[15] = 1.0;
- return result;
- };
- /**
- * Computes a Matrix4 instance representing an off center perspective transformation.
- *
- * @param {Number} left The number of meters to the left of the camera that will be in view.
- * @param {Number} right The number of meters to the right of the camera that will be in view.
- * @param {Number} bottom The number of meters below of the camera that will be in view.
- * @param {Number} top The number of meters above of the camera that will be in view.
- * @param {Number} near The distance to the near plane in meters.
- * @param {Number} far The distance to the far plane in meters.
- * @param {Matrix4} result The object in which the result will be stored.
- * @returns {Matrix4} The modified result parameter.
- */
- Matrix4.computePerspectiveOffCenter = function (
- left,
- right,
- bottom,
- top,
- near,
- far,
- result
- ) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.number("left", left);
- Check.typeOf.number("right", right);
- Check.typeOf.number("bottom", bottom);
- Check.typeOf.number("top", top);
- Check.typeOf.number("near", near);
- Check.typeOf.number("far", far);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const column0Row0 = (2.0 * near) / (right - left);
- const column1Row1 = (2.0 * near) / (top - bottom);
- const column2Row0 = (right + left) / (right - left);
- const column2Row1 = (top + bottom) / (top - bottom);
- const column2Row2 = -(far + near) / (far - near);
- const column2Row3 = -1.0;
- const column3Row2 = (-2.0 * far * near) / (far - near);
- result[0] = column0Row0;
- result[1] = 0.0;
- result[2] = 0.0;
- result[3] = 0.0;
- result[4] = 0.0;
- result[5] = column1Row1;
- result[6] = 0.0;
- result[7] = 0.0;
- result[8] = column2Row0;
- result[9] = column2Row1;
- result[10] = column2Row2;
- result[11] = column2Row3;
- result[12] = 0.0;
- result[13] = 0.0;
- result[14] = column3Row2;
- result[15] = 0.0;
- return result;
- };
- /**
- * Computes a Matrix4 instance representing an infinite off center perspective transformation.
- *
- * @param {Number} left The number of meters to the left of the camera that will be in view.
- * @param {Number} right The number of meters to the right of the camera that will be in view.
- * @param {Number} bottom The number of meters below of the camera that will be in view.
- * @param {Number} top The number of meters above of the camera that will be in view.
- * @param {Number} near The distance to the near plane in meters.
- * @param {Matrix4} result The object in which the result will be stored.
- * @returns {Matrix4} The modified result parameter.
- */
- Matrix4.computeInfinitePerspectiveOffCenter = function (
- left,
- right,
- bottom,
- top,
- near,
- result
- ) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.number("left", left);
- Check.typeOf.number("right", right);
- Check.typeOf.number("bottom", bottom);
- Check.typeOf.number("top", top);
- Check.typeOf.number("near", near);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const column0Row0 = (2.0 * near) / (right - left);
- const column1Row1 = (2.0 * near) / (top - bottom);
- const column2Row0 = (right + left) / (right - left);
- const column2Row1 = (top + bottom) / (top - bottom);
- const column2Row2 = -1.0;
- const column2Row3 = -1.0;
- const column3Row2 = -2.0 * near;
- result[0] = column0Row0;
- result[1] = 0.0;
- result[2] = 0.0;
- result[3] = 0.0;
- result[4] = 0.0;
- result[5] = column1Row1;
- result[6] = 0.0;
- result[7] = 0.0;
- result[8] = column2Row0;
- result[9] = column2Row1;
- result[10] = column2Row2;
- result[11] = column2Row3;
- result[12] = 0.0;
- result[13] = 0.0;
- result[14] = column3Row2;
- result[15] = 0.0;
- return result;
- };
- /**
- * Computes a Matrix4 instance that transforms from normalized device coordinates to window coordinates.
- *
- * @param {Object} [viewport = { x : 0.0, y : 0.0, width : 0.0, height : 0.0 }] The viewport's corners as shown in Example 1.
- * @param {Number} [nearDepthRange=0.0] The near plane distance in window coordinates.
- * @param {Number} [farDepthRange=1.0] The far plane distance in window coordinates.
- * @param {Matrix4} [result] The object in which the result will be stored.
- * @returns {Matrix4} The modified result parameter.
- *
- * @example
- * // Create viewport transformation using an explicit viewport and depth range.
- * const m = Cesium.Matrix4.computeViewportTransformation({
- * x : 0.0,
- * y : 0.0,
- * width : 1024.0,
- * height : 768.0
- * }, 0.0, 1.0, new Cesium.Matrix4());
- */
- Matrix4.computeViewportTransformation = function (
- viewport,
- nearDepthRange,
- farDepthRange,
- result
- ) {
- if (!defined(result)) {
- result = new Matrix4();
- }
- viewport = defaultValue(viewport, defaultValue.EMPTY_OBJECT);
- const x = defaultValue(viewport.x, 0.0);
- const y = defaultValue(viewport.y, 0.0);
- const width = defaultValue(viewport.width, 0.0);
- const height = defaultValue(viewport.height, 0.0);
- nearDepthRange = defaultValue(nearDepthRange, 0.0);
- farDepthRange = defaultValue(farDepthRange, 1.0);
- const halfWidth = width * 0.5;
- const halfHeight = height * 0.5;
- const halfDepth = (farDepthRange - nearDepthRange) * 0.5;
- const column0Row0 = halfWidth;
- const column1Row1 = halfHeight;
- const column2Row2 = halfDepth;
- const column3Row0 = x + halfWidth;
- const column3Row1 = y + halfHeight;
- const column3Row2 = nearDepthRange + halfDepth;
- const column3Row3 = 1.0;
- result[0] = column0Row0;
- result[1] = 0.0;
- result[2] = 0.0;
- result[3] = 0.0;
- result[4] = 0.0;
- result[5] = column1Row1;
- result[6] = 0.0;
- result[7] = 0.0;
- result[8] = 0.0;
- result[9] = 0.0;
- result[10] = column2Row2;
- result[11] = 0.0;
- result[12] = column3Row0;
- result[13] = column3Row1;
- result[14] = column3Row2;
- result[15] = column3Row3;
- return result;
- };
- /**
- * Computes a Matrix4 instance that transforms from world space to view space.
- *
- * @param {Cartesian3} position The position of the camera.
- * @param {Cartesian3} direction The forward direction.
- * @param {Cartesian3} up The up direction.
- * @param {Cartesian3} right The right direction.
- * @param {Matrix4} result The object in which the result will be stored.
- * @returns {Matrix4} The modified result parameter.
- */
- Matrix4.computeView = function (position, direction, up, right, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("position", position);
- Check.typeOf.object("direction", direction);
- Check.typeOf.object("up", up);
- Check.typeOf.object("right", right);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result[0] = right.x;
- result[1] = up.x;
- result[2] = -direction.x;
- result[3] = 0.0;
- result[4] = right.y;
- result[5] = up.y;
- result[6] = -direction.y;
- result[7] = 0.0;
- result[8] = right.z;
- result[9] = up.z;
- result[10] = -direction.z;
- result[11] = 0.0;
- result[12] = -Cartesian3.dot(right, position);
- result[13] = -Cartesian3.dot(up, position);
- result[14] = Cartesian3.dot(direction, position);
- result[15] = 1.0;
- return result;
- };
- /**
- * Computes an Array from the provided Matrix4 instance.
- * The array will be in column-major order.
- *
- * @param {Matrix4} matrix The matrix to use..
- * @param {Number[]} [result] The Array onto which to store the result.
- * @returns {Number[]} The modified Array parameter or a new Array instance if one was not provided.
- *
- * @example
- * //create an array from an instance of Matrix4
- * // m = [10.0, 14.0, 18.0, 22.0]
- * // [11.0, 15.0, 19.0, 23.0]
- * // [12.0, 16.0, 20.0, 24.0]
- * // [13.0, 17.0, 21.0, 25.0]
- * const a = Cesium.Matrix4.toArray(m);
- *
- * // m remains the same
- * //creates a = [10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0]
- */
- Matrix4.toArray = function (matrix, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- //>>includeEnd('debug');
- if (!defined(result)) {
- return [
- matrix[0],
- matrix[1],
- matrix[2],
- matrix[3],
- matrix[4],
- matrix[5],
- matrix[6],
- matrix[7],
- matrix[8],
- matrix[9],
- matrix[10],
- matrix[11],
- matrix[12],
- matrix[13],
- matrix[14],
- matrix[15],
- ];
- }
- result[0] = matrix[0];
- result[1] = matrix[1];
- result[2] = matrix[2];
- result[3] = matrix[3];
- result[4] = matrix[4];
- result[5] = matrix[5];
- result[6] = matrix[6];
- result[7] = matrix[7];
- result[8] = matrix[8];
- result[9] = matrix[9];
- result[10] = matrix[10];
- result[11] = matrix[11];
- result[12] = matrix[12];
- result[13] = matrix[13];
- result[14] = matrix[14];
- result[15] = matrix[15];
- return result;
- };
- /**
- * Computes the array index of the element at the provided row and column.
- *
- * @param {Number} row The zero-based index of the row.
- * @param {Number} column The zero-based index of the column.
- * @returns {Number} The index of the element at the provided row and column.
- *
- * @exception {DeveloperError} row must be 0, 1, 2, or 3.
- * @exception {DeveloperError} column must be 0, 1, 2, or 3.
- *
- * @example
- * const myMatrix = new Cesium.Matrix4();
- * const column1Row0Index = Cesium.Matrix4.getElementIndex(1, 0);
- * const column1Row0 = myMatrix[column1Row0Index];
- * myMatrix[column1Row0Index] = 10.0;
- */
- Matrix4.getElementIndex = function (column, row) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.number.greaterThanOrEquals("row", row, 0);
- Check.typeOf.number.lessThanOrEquals("row", row, 3);
- Check.typeOf.number.greaterThanOrEquals("column", column, 0);
- Check.typeOf.number.lessThanOrEquals("column", column, 3);
- //>>includeEnd('debug');
- return column * 4 + row;
- };
- /**
- * Retrieves a copy of the matrix column at the provided index as a Cartesian4 instance.
- *
- * @param {Matrix4} matrix The matrix to use.
- * @param {Number} index The zero-based index of the column to retrieve.
- * @param {Cartesian4} result The object onto which to store the result.
- * @returns {Cartesian4} The modified result parameter.
- *
- * @exception {DeveloperError} index must be 0, 1, 2, or 3.
- *
- * @example
- * //returns a Cartesian4 instance with values from the specified column
- * // m = [10.0, 11.0, 12.0, 13.0]
- * // [14.0, 15.0, 16.0, 17.0]
- * // [18.0, 19.0, 20.0, 21.0]
- * // [22.0, 23.0, 24.0, 25.0]
- *
- * //Example 1: Creates an instance of Cartesian
- * const a = Cesium.Matrix4.getColumn(m, 2, new Cesium.Cartesian4());
- *
- * @example
- * //Example 2: Sets values for Cartesian instance
- * const a = new Cesium.Cartesian4();
- * Cesium.Matrix4.getColumn(m, 2, a);
- *
- * // a.x = 12.0; a.y = 16.0; a.z = 20.0; a.w = 24.0;
- */
- Matrix4.getColumn = function (matrix, index, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.number.greaterThanOrEquals("index", index, 0);
- Check.typeOf.number.lessThanOrEquals("index", index, 3);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const startIndex = index * 4;
- const x = matrix[startIndex];
- const y = matrix[startIndex + 1];
- const z = matrix[startIndex + 2];
- const w = matrix[startIndex + 3];
- result.x = x;
- result.y = y;
- result.z = z;
- result.w = w;
- return result;
- };
- /**
- * Computes a new matrix that replaces the specified column in the provided matrix with the provided Cartesian4 instance.
- *
- * @param {Matrix4} matrix The matrix to use.
- * @param {Number} index The zero-based index of the column to set.
- * @param {Cartesian4} cartesian The Cartesian whose values will be assigned to the specified column.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @exception {DeveloperError} index must be 0, 1, 2, or 3.
- *
- * @example
- * //creates a new Matrix4 instance with new column values from the Cartesian4 instance
- * // m = [10.0, 11.0, 12.0, 13.0]
- * // [14.0, 15.0, 16.0, 17.0]
- * // [18.0, 19.0, 20.0, 21.0]
- * // [22.0, 23.0, 24.0, 25.0]
- *
- * const a = Cesium.Matrix4.setColumn(m, 2, new Cesium.Cartesian4(99.0, 98.0, 97.0, 96.0), new Cesium.Matrix4());
- *
- * // m remains the same
- * // a = [10.0, 11.0, 99.0, 13.0]
- * // [14.0, 15.0, 98.0, 17.0]
- * // [18.0, 19.0, 97.0, 21.0]
- * // [22.0, 23.0, 96.0, 25.0]
- */
- Matrix4.setColumn = function (matrix, index, cartesian, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.number.greaterThanOrEquals("index", index, 0);
- Check.typeOf.number.lessThanOrEquals("index", index, 3);
- Check.typeOf.object("cartesian", cartesian);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result = Matrix4.clone(matrix, result);
- const startIndex = index * 4;
- result[startIndex] = cartesian.x;
- result[startIndex + 1] = cartesian.y;
- result[startIndex + 2] = cartesian.z;
- result[startIndex + 3] = cartesian.w;
- return result;
- };
- /**
- * Retrieves a copy of the matrix row at the provided index as a Cartesian4 instance.
- *
- * @param {Matrix4} matrix The matrix to use.
- * @param {Number} index The zero-based index of the row to retrieve.
- * @param {Cartesian4} result The object onto which to store the result.
- * @returns {Cartesian4} The modified result parameter.
- *
- * @exception {DeveloperError} index must be 0, 1, 2, or 3.
- *
- * @example
- * //returns a Cartesian4 instance with values from the specified column
- * // m = [10.0, 11.0, 12.0, 13.0]
- * // [14.0, 15.0, 16.0, 17.0]
- * // [18.0, 19.0, 20.0, 21.0]
- * // [22.0, 23.0, 24.0, 25.0]
- *
- * //Example 1: Returns an instance of Cartesian
- * const a = Cesium.Matrix4.getRow(m, 2, new Cesium.Cartesian4());
- *
- * @example
- * //Example 2: Sets values for a Cartesian instance
- * const a = new Cesium.Cartesian4();
- * Cesium.Matrix4.getRow(m, 2, a);
- *
- * // a.x = 18.0; a.y = 19.0; a.z = 20.0; a.w = 21.0;
- */
- Matrix4.getRow = function (matrix, index, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.number.greaterThanOrEquals("index", index, 0);
- Check.typeOf.number.lessThanOrEquals("index", index, 3);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const x = matrix[index];
- const y = matrix[index + 4];
- const z = matrix[index + 8];
- const w = matrix[index + 12];
- result.x = x;
- result.y = y;
- result.z = z;
- result.w = w;
- return result;
- };
- /**
- * Computes a new matrix that replaces the specified row in the provided matrix with the provided Cartesian4 instance.
- *
- * @param {Matrix4} matrix The matrix to use.
- * @param {Number} index The zero-based index of the row to set.
- * @param {Cartesian4} cartesian The Cartesian whose values will be assigned to the specified row.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @exception {DeveloperError} index must be 0, 1, 2, or 3.
- *
- * @example
- * //create a new Matrix4 instance with new row values from the Cartesian4 instance
- * // m = [10.0, 11.0, 12.0, 13.0]
- * // [14.0, 15.0, 16.0, 17.0]
- * // [18.0, 19.0, 20.0, 21.0]
- * // [22.0, 23.0, 24.0, 25.0]
- *
- * const a = Cesium.Matrix4.setRow(m, 2, new Cesium.Cartesian4(99.0, 98.0, 97.0, 96.0), new Cesium.Matrix4());
- *
- * // m remains the same
- * // a = [10.0, 11.0, 12.0, 13.0]
- * // [14.0, 15.0, 16.0, 17.0]
- * // [99.0, 98.0, 97.0, 96.0]
- * // [22.0, 23.0, 24.0, 25.0]
- */
- Matrix4.setRow = function (matrix, index, cartesian, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.number.greaterThanOrEquals("index", index, 0);
- Check.typeOf.number.lessThanOrEquals("index", index, 3);
- Check.typeOf.object("cartesian", cartesian);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result = Matrix4.clone(matrix, result);
- result[index] = cartesian.x;
- result[index + 4] = cartesian.y;
- result[index + 8] = cartesian.z;
- result[index + 12] = cartesian.w;
- return result;
- };
- /**
- * Computes a new matrix that replaces the translation in the rightmost column of the provided
- * matrix with the provided translation. This assumes the matrix is an affine transformation.
- *
- * @param {Matrix4} matrix The matrix to use.
- * @param {Cartesian3} translation The translation that replaces the translation of the provided matrix.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- */
- Matrix4.setTranslation = function (matrix, translation, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("translation", translation);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result[0] = matrix[0];
- result[1] = matrix[1];
- result[2] = matrix[2];
- result[3] = matrix[3];
- result[4] = matrix[4];
- result[5] = matrix[5];
- result[6] = matrix[6];
- result[7] = matrix[7];
- result[8] = matrix[8];
- result[9] = matrix[9];
- result[10] = matrix[10];
- result[11] = matrix[11];
- result[12] = translation.x;
- result[13] = translation.y;
- result[14] = translation.z;
- result[15] = matrix[15];
- return result;
- };
- const scaleScratch1 = new Cartesian3();
- /**
- * Computes a new matrix that replaces the scale with the provided scale.
- * This assumes the matrix is an affine transformation.
- *
- * @param {Matrix4} matrix The matrix to use.
- * @param {Cartesian3} scale The scale that replaces the scale of the provided matrix.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @see Matrix4.setUniformScale
- * @see Matrix4.fromScale
- * @see Matrix4.fromUniformScale
- * @see Matrix4.multiplyByScale
- * @see Matrix4.multiplyByUniformScale
- * @see Matrix4.getScale
- */
- Matrix4.setScale = function (matrix, scale, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("scale", scale);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const existingScale = Matrix4.getScale(matrix, scaleScratch1);
- const scaleRatioX = scale.x / existingScale.x;
- const scaleRatioY = scale.y / existingScale.y;
- const scaleRatioZ = scale.z / existingScale.z;
- result[0] = matrix[0] * scaleRatioX;
- result[1] = matrix[1] * scaleRatioX;
- result[2] = matrix[2] * scaleRatioX;
- result[3] = matrix[3];
- result[4] = matrix[4] * scaleRatioY;
- result[5] = matrix[5] * scaleRatioY;
- result[6] = matrix[6] * scaleRatioY;
- result[7] = matrix[7];
- result[8] = matrix[8] * scaleRatioZ;
- result[9] = matrix[9] * scaleRatioZ;
- result[10] = matrix[10] * scaleRatioZ;
- result[11] = matrix[11];
- result[12] = matrix[12];
- result[13] = matrix[13];
- result[14] = matrix[14];
- result[15] = matrix[15];
- return result;
- };
- const scaleScratch2 = new Cartesian3();
- /**
- * Computes a new matrix that replaces the scale with the provided uniform scale.
- * This assumes the matrix is an affine transformation.
- *
- * @param {Matrix4} matrix The matrix to use.
- * @param {Number} scale The uniform scale that replaces the scale of the provided matrix.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @see Matrix4.setScale
- * @see Matrix4.fromScale
- * @see Matrix4.fromUniformScale
- * @see Matrix4.multiplyByScale
- * @see Matrix4.multiplyByUniformScale
- * @see Matrix4.getScale
- */
- Matrix4.setUniformScale = function (matrix, scale, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.number("scale", scale);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const existingScale = Matrix4.getScale(matrix, scaleScratch2);
- const scaleRatioX = scale / existingScale.x;
- const scaleRatioY = scale / existingScale.y;
- const scaleRatioZ = scale / existingScale.z;
- result[0] = matrix[0] * scaleRatioX;
- result[1] = matrix[1] * scaleRatioX;
- result[2] = matrix[2] * scaleRatioX;
- result[3] = matrix[3];
- result[4] = matrix[4] * scaleRatioY;
- result[5] = matrix[5] * scaleRatioY;
- result[6] = matrix[6] * scaleRatioY;
- result[7] = matrix[7];
- result[8] = matrix[8] * scaleRatioZ;
- result[9] = matrix[9] * scaleRatioZ;
- result[10] = matrix[10] * scaleRatioZ;
- result[11] = matrix[11];
- result[12] = matrix[12];
- result[13] = matrix[13];
- result[14] = matrix[14];
- result[15] = matrix[15];
- return result;
- };
- const scratchColumn = new Cartesian3();
- /**
- * Extracts the non-uniform scale assuming the matrix is an affine transformation.
- *
- * @param {Matrix4} matrix The matrix.
- * @param {Cartesian3} result The object onto which to store the result.
- * @returns {Cartesian3} The modified result parameter
- *
- * @see Matrix4.multiplyByScale
- * @see Matrix4.multiplyByUniformScale
- * @see Matrix4.fromScale
- * @see Matrix4.fromUniformScale
- * @see Matrix4.setScale
- * @see Matrix4.setUniformScale
- */
- Matrix4.getScale = function (matrix, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result.x = Cartesian3.magnitude(
- Cartesian3.fromElements(matrix[0], matrix[1], matrix[2], scratchColumn)
- );
- result.y = Cartesian3.magnitude(
- Cartesian3.fromElements(matrix[4], matrix[5], matrix[6], scratchColumn)
- );
- result.z = Cartesian3.magnitude(
- Cartesian3.fromElements(matrix[8], matrix[9], matrix[10], scratchColumn)
- );
- return result;
- };
- const scaleScratch3 = new Cartesian3();
- /**
- * Computes the maximum scale assuming the matrix is an affine transformation.
- * The maximum scale is the maximum length of the column vectors in the upper-left
- * 3x3 matrix.
- *
- * @param {Matrix4} matrix The matrix.
- * @returns {Number} The maximum scale.
- */
- Matrix4.getMaximumScale = function (matrix) {
- Matrix4.getScale(matrix, scaleScratch3);
- return Cartesian3.maximumComponent(scaleScratch3);
- };
- const scaleScratch4 = new Cartesian3();
- /**
- * Sets the rotation assuming the matrix is an affine transformation.
- *
- * @param {Matrix4} matrix The matrix.
- * @param {Matrix4} rotation The rotation matrix.
- * @returns {Matrix4} The modified result parameter.
- *
- * @see Matrix4.fromRotation
- * @see Matrix4.getRotation
- */
- Matrix4.setRotation = function (matrix, rotation, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const scale = Matrix4.getScale(matrix, scaleScratch4);
- result[0] = rotation[0] * scale.x;
- result[1] = rotation[1] * scale.x;
- result[2] = rotation[2] * scale.x;
- result[3] = matrix[3];
- result[4] = rotation[3] * scale.y;
- result[5] = rotation[4] * scale.y;
- result[6] = rotation[5] * scale.y;
- result[7] = matrix[7];
- result[8] = rotation[6] * scale.z;
- result[9] = rotation[7] * scale.z;
- result[10] = rotation[8] * scale.z;
- result[11] = matrix[11];
- result[12] = matrix[12];
- result[13] = matrix[13];
- result[14] = matrix[14];
- result[15] = matrix[15];
- return result;
- };
- const scaleScratch5 = new Cartesian3();
- /**
- * Extracts the rotation matrix assuming the matrix is an affine transformation.
- *
- * @param {Matrix4} matrix The matrix.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @see Matrix4.setRotation
- * @see Matrix4.fromRotation
- */
- Matrix4.getRotation = function (matrix, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const scale = Matrix4.getScale(matrix, scaleScratch5);
- result[0] = matrix[0] / scale.x;
- result[1] = matrix[1] / scale.x;
- result[2] = matrix[2] / scale.x;
- result[3] = matrix[4] / scale.y;
- result[4] = matrix[5] / scale.y;
- result[5] = matrix[6] / scale.y;
- result[6] = matrix[8] / scale.z;
- result[7] = matrix[9] / scale.z;
- result[8] = matrix[10] / scale.z;
- return result;
- };
- /**
- * Computes the product of two matrices.
- *
- * @param {Matrix4} left The first matrix.
- * @param {Matrix4} right The second matrix.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- */
- Matrix4.multiply = function (left, right, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("left", left);
- Check.typeOf.object("right", right);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const left0 = left[0];
- const left1 = left[1];
- const left2 = left[2];
- const left3 = left[3];
- const left4 = left[4];
- const left5 = left[5];
- const left6 = left[6];
- const left7 = left[7];
- const left8 = left[8];
- const left9 = left[9];
- const left10 = left[10];
- const left11 = left[11];
- const left12 = left[12];
- const left13 = left[13];
- const left14 = left[14];
- const left15 = left[15];
- const right0 = right[0];
- const right1 = right[1];
- const right2 = right[2];
- const right3 = right[3];
- const right4 = right[4];
- const right5 = right[5];
- const right6 = right[6];
- const right7 = right[7];
- const right8 = right[8];
- const right9 = right[9];
- const right10 = right[10];
- const right11 = right[11];
- const right12 = right[12];
- const right13 = right[13];
- const right14 = right[14];
- const right15 = right[15];
- const column0Row0 =
- left0 * right0 + left4 * right1 + left8 * right2 + left12 * right3;
- const column0Row1 =
- left1 * right0 + left5 * right1 + left9 * right2 + left13 * right3;
- const column0Row2 =
- left2 * right0 + left6 * right1 + left10 * right2 + left14 * right3;
- const column0Row3 =
- left3 * right0 + left7 * right1 + left11 * right2 + left15 * right3;
- const column1Row0 =
- left0 * right4 + left4 * right5 + left8 * right6 + left12 * right7;
- const column1Row1 =
- left1 * right4 + left5 * right5 + left9 * right6 + left13 * right7;
- const column1Row2 =
- left2 * right4 + left6 * right5 + left10 * right6 + left14 * right7;
- const column1Row3 =
- left3 * right4 + left7 * right5 + left11 * right6 + left15 * right7;
- const column2Row0 =
- left0 * right8 + left4 * right9 + left8 * right10 + left12 * right11;
- const column2Row1 =
- left1 * right8 + left5 * right9 + left9 * right10 + left13 * right11;
- const column2Row2 =
- left2 * right8 + left6 * right9 + left10 * right10 + left14 * right11;
- const column2Row3 =
- left3 * right8 + left7 * right9 + left11 * right10 + left15 * right11;
- const column3Row0 =
- left0 * right12 + left4 * right13 + left8 * right14 + left12 * right15;
- const column3Row1 =
- left1 * right12 + left5 * right13 + left9 * right14 + left13 * right15;
- const column3Row2 =
- left2 * right12 + left6 * right13 + left10 * right14 + left14 * right15;
- const column3Row3 =
- left3 * right12 + left7 * right13 + left11 * right14 + left15 * right15;
- result[0] = column0Row0;
- result[1] = column0Row1;
- result[2] = column0Row2;
- result[3] = column0Row3;
- result[4] = column1Row0;
- result[5] = column1Row1;
- result[6] = column1Row2;
- result[7] = column1Row3;
- result[8] = column2Row0;
- result[9] = column2Row1;
- result[10] = column2Row2;
- result[11] = column2Row3;
- result[12] = column3Row0;
- result[13] = column3Row1;
- result[14] = column3Row2;
- result[15] = column3Row3;
- return result;
- };
- /**
- * Computes the sum of two matrices.
- *
- * @param {Matrix4} left The first matrix.
- * @param {Matrix4} right The second matrix.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- */
- Matrix4.add = function (left, right, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("left", left);
- Check.typeOf.object("right", right);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result[0] = left[0] + right[0];
- result[1] = left[1] + right[1];
- result[2] = left[2] + right[2];
- result[3] = left[3] + right[3];
- result[4] = left[4] + right[4];
- result[5] = left[5] + right[5];
- result[6] = left[6] + right[6];
- result[7] = left[7] + right[7];
- result[8] = left[8] + right[8];
- result[9] = left[9] + right[9];
- result[10] = left[10] + right[10];
- result[11] = left[11] + right[11];
- result[12] = left[12] + right[12];
- result[13] = left[13] + right[13];
- result[14] = left[14] + right[14];
- result[15] = left[15] + right[15];
- return result;
- };
- /**
- * Computes the difference of two matrices.
- *
- * @param {Matrix4} left The first matrix.
- * @param {Matrix4} right The second matrix.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- */
- Matrix4.subtract = function (left, right, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("left", left);
- Check.typeOf.object("right", right);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result[0] = left[0] - right[0];
- result[1] = left[1] - right[1];
- result[2] = left[2] - right[2];
- result[3] = left[3] - right[3];
- result[4] = left[4] - right[4];
- result[5] = left[5] - right[5];
- result[6] = left[6] - right[6];
- result[7] = left[7] - right[7];
- result[8] = left[8] - right[8];
- result[9] = left[9] - right[9];
- result[10] = left[10] - right[10];
- result[11] = left[11] - right[11];
- result[12] = left[12] - right[12];
- result[13] = left[13] - right[13];
- result[14] = left[14] - right[14];
- result[15] = left[15] - right[15];
- return result;
- };
- /**
- * Computes the product of two matrices assuming the matrices are affine transformation matrices,
- * where the upper left 3x3 elements are any matrix, and
- * the upper three elements in the fourth column are the translation.
- * The bottom row is assumed to be [0, 0, 0, 1].
- * The matrix is not verified to be in the proper form.
- * This method is faster than computing the product for general 4x4
- * matrices using {@link Matrix4.multiply}.
- *
- * @param {Matrix4} left The first matrix.
- * @param {Matrix4} right The second matrix.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @example
- * const m1 = new Cesium.Matrix4(1.0, 6.0, 7.0, 0.0, 2.0, 5.0, 8.0, 0.0, 3.0, 4.0, 9.0, 0.0, 0.0, 0.0, 0.0, 1.0);
- * const m2 = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3(1.0, 1.0, 1.0));
- * const m3 = Cesium.Matrix4.multiplyTransformation(m1, m2, new Cesium.Matrix4());
- */
- Matrix4.multiplyTransformation = function (left, right, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("left", left);
- Check.typeOf.object("right", right);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const left0 = left[0];
- const left1 = left[1];
- const left2 = left[2];
- const left4 = left[4];
- const left5 = left[5];
- const left6 = left[6];
- const left8 = left[8];
- const left9 = left[9];
- const left10 = left[10];
- const left12 = left[12];
- const left13 = left[13];
- const left14 = left[14];
- const right0 = right[0];
- const right1 = right[1];
- const right2 = right[2];
- const right4 = right[4];
- const right5 = right[5];
- const right6 = right[6];
- const right8 = right[8];
- const right9 = right[9];
- const right10 = right[10];
- const right12 = right[12];
- const right13 = right[13];
- const right14 = right[14];
- const column0Row0 = left0 * right0 + left4 * right1 + left8 * right2;
- const column0Row1 = left1 * right0 + left5 * right1 + left9 * right2;
- const column0Row2 = left2 * right0 + left6 * right1 + left10 * right2;
- const column1Row0 = left0 * right4 + left4 * right5 + left8 * right6;
- const column1Row1 = left1 * right4 + left5 * right5 + left9 * right6;
- const column1Row2 = left2 * right4 + left6 * right5 + left10 * right6;
- const column2Row0 = left0 * right8 + left4 * right9 + left8 * right10;
- const column2Row1 = left1 * right8 + left5 * right9 + left9 * right10;
- const column2Row2 = left2 * right8 + left6 * right9 + left10 * right10;
- const column3Row0 =
- left0 * right12 + left4 * right13 + left8 * right14 + left12;
- const column3Row1 =
- left1 * right12 + left5 * right13 + left9 * right14 + left13;
- const column3Row2 =
- left2 * right12 + left6 * right13 + left10 * right14 + left14;
- result[0] = column0Row0;
- result[1] = column0Row1;
- result[2] = column0Row2;
- result[3] = 0.0;
- result[4] = column1Row0;
- result[5] = column1Row1;
- result[6] = column1Row2;
- result[7] = 0.0;
- result[8] = column2Row0;
- result[9] = column2Row1;
- result[10] = column2Row2;
- result[11] = 0.0;
- result[12] = column3Row0;
- result[13] = column3Row1;
- result[14] = column3Row2;
- result[15] = 1.0;
- return result;
- };
- /**
- * Multiplies a transformation matrix (with a bottom row of <code>[0.0, 0.0, 0.0, 1.0]</code>)
- * by a 3x3 rotation matrix. This is an optimization
- * for <code>Matrix4.multiply(m, Matrix4.fromRotationTranslation(rotation), m);</code> with less allocations and arithmetic operations.
- *
- * @param {Matrix4} matrix The matrix on the left-hand side.
- * @param {Matrix3} rotation The 3x3 rotation matrix on the right-hand side.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @example
- * // Instead of Cesium.Matrix4.multiply(m, Cesium.Matrix4.fromRotationTranslation(rotation), m);
- * Cesium.Matrix4.multiplyByMatrix3(m, rotation, m);
- */
- Matrix4.multiplyByMatrix3 = function (matrix, rotation, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("rotation", rotation);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const left0 = matrix[0];
- const left1 = matrix[1];
- const left2 = matrix[2];
- const left4 = matrix[4];
- const left5 = matrix[5];
- const left6 = matrix[6];
- const left8 = matrix[8];
- const left9 = matrix[9];
- const left10 = matrix[10];
- const right0 = rotation[0];
- const right1 = rotation[1];
- const right2 = rotation[2];
- const right4 = rotation[3];
- const right5 = rotation[4];
- const right6 = rotation[5];
- const right8 = rotation[6];
- const right9 = rotation[7];
- const right10 = rotation[8];
- const column0Row0 = left0 * right0 + left4 * right1 + left8 * right2;
- const column0Row1 = left1 * right0 + left5 * right1 + left9 * right2;
- const column0Row2 = left2 * right0 + left6 * right1 + left10 * right2;
- const column1Row0 = left0 * right4 + left4 * right5 + left8 * right6;
- const column1Row1 = left1 * right4 + left5 * right5 + left9 * right6;
- const column1Row2 = left2 * right4 + left6 * right5 + left10 * right6;
- const column2Row0 = left0 * right8 + left4 * right9 + left8 * right10;
- const column2Row1 = left1 * right8 + left5 * right9 + left9 * right10;
- const column2Row2 = left2 * right8 + left6 * right9 + left10 * right10;
- result[0] = column0Row0;
- result[1] = column0Row1;
- result[2] = column0Row2;
- result[3] = 0.0;
- result[4] = column1Row0;
- result[5] = column1Row1;
- result[6] = column1Row2;
- result[7] = 0.0;
- result[8] = column2Row0;
- result[9] = column2Row1;
- result[10] = column2Row2;
- result[11] = 0.0;
- result[12] = matrix[12];
- result[13] = matrix[13];
- result[14] = matrix[14];
- result[15] = matrix[15];
- return result;
- };
- /**
- * Multiplies a transformation matrix (with a bottom row of <code>[0.0, 0.0, 0.0, 1.0]</code>)
- * by an implicit translation matrix defined by a {@link Cartesian3}. This is an optimization
- * for <code>Matrix4.multiply(m, Matrix4.fromTranslation(position), m);</code> with less allocations and arithmetic operations.
- *
- * @param {Matrix4} matrix The matrix on the left-hand side.
- * @param {Cartesian3} translation The translation on the right-hand side.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @example
- * // Instead of Cesium.Matrix4.multiply(m, Cesium.Matrix4.fromTranslation(position), m);
- * Cesium.Matrix4.multiplyByTranslation(m, position, m);
- */
- Matrix4.multiplyByTranslation = function (matrix, translation, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("translation", translation);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const x = translation.x;
- const y = translation.y;
- const z = translation.z;
- const tx = x * matrix[0] + y * matrix[4] + z * matrix[8] + matrix[12];
- const ty = x * matrix[1] + y * matrix[5] + z * matrix[9] + matrix[13];
- const tz = x * matrix[2] + y * matrix[6] + z * matrix[10] + matrix[14];
- result[0] = matrix[0];
- result[1] = matrix[1];
- result[2] = matrix[2];
- result[3] = matrix[3];
- result[4] = matrix[4];
- result[5] = matrix[5];
- result[6] = matrix[6];
- result[7] = matrix[7];
- result[8] = matrix[8];
- result[9] = matrix[9];
- result[10] = matrix[10];
- result[11] = matrix[11];
- result[12] = tx;
- result[13] = ty;
- result[14] = tz;
- result[15] = matrix[15];
- return result;
- };
- /**
- * Multiplies an affine transformation matrix (with a bottom row of <code>[0.0, 0.0, 0.0, 1.0]</code>)
- * by an implicit non-uniform scale matrix. This is an optimization
- * for <code>Matrix4.multiply(m, Matrix4.fromUniformScale(scale), m);</code>, where
- * <code>m</code> must be an affine matrix.
- * This function performs fewer allocations and arithmetic operations.
- *
- * @param {Matrix4} matrix The affine matrix on the left-hand side.
- * @param {Cartesian3} scale The non-uniform scale on the right-hand side.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- *
- * @example
- * // Instead of Cesium.Matrix4.multiply(m, Cesium.Matrix4.fromScale(scale), m);
- * Cesium.Matrix4.multiplyByScale(m, scale, m);
- *
- * @see Matrix4.multiplyByUniformScale
- * @see Matrix4.fromScale
- * @see Matrix4.fromUniformScale
- * @see Matrix4.setScale
- * @see Matrix4.setUniformScale
- * @see Matrix4.getScale
- */
- Matrix4.multiplyByScale = function (matrix, scale, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("scale", scale);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const scaleX = scale.x;
- const scaleY = scale.y;
- const scaleZ = scale.z;
- // Faster than Cartesian3.equals
- if (scaleX === 1.0 && scaleY === 1.0 && scaleZ === 1.0) {
- return Matrix4.clone(matrix, result);
- }
- result[0] = scaleX * matrix[0];
- result[1] = scaleX * matrix[1];
- result[2] = scaleX * matrix[2];
- result[3] = matrix[3];
- result[4] = scaleY * matrix[4];
- result[5] = scaleY * matrix[5];
- result[6] = scaleY * matrix[6];
- result[7] = matrix[7];
- result[8] = scaleZ * matrix[8];
- result[9] = scaleZ * matrix[9];
- result[10] = scaleZ * matrix[10];
- result[11] = matrix[11];
- result[12] = matrix[12];
- result[13] = matrix[13];
- result[14] = matrix[14];
- result[15] = matrix[15];
- return result;
- };
- /**
- * Computes the product of a matrix times a uniform scale, as if the scale were a scale matrix.
- *
- * @param {Matrix4} matrix The matrix on the left-hand side.
- * @param {Number} scale The uniform scale on the right-hand side.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @example
- * // Instead of Cesium.Matrix4.multiply(m, Cesium.Matrix4.fromUniformScale(scale), m);
- * Cesium.Matrix4.multiplyByUniformScale(m, scale, m);
- *
- * @see Matrix4.multiplyByScale
- * @see Matrix4.fromScale
- * @see Matrix4.fromUniformScale
- * @see Matrix4.setScale
- * @see Matrix4.setUniformScale
- * @see Matrix4.getScale
- */
- Matrix4.multiplyByUniformScale = function (matrix, scale, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.number("scale", scale);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result[0] = matrix[0] * scale;
- result[1] = matrix[1] * scale;
- result[2] = matrix[2] * scale;
- result[3] = matrix[3];
- result[4] = matrix[4] * scale;
- result[5] = matrix[5] * scale;
- result[6] = matrix[6] * scale;
- result[7] = matrix[7];
- result[8] = matrix[8] * scale;
- result[9] = matrix[9] * scale;
- result[10] = matrix[10] * scale;
- result[11] = matrix[11];
- result[12] = matrix[12];
- result[13] = matrix[13];
- result[14] = matrix[14];
- result[15] = matrix[15];
- return result;
- };
- /**
- * Computes the product of a matrix and a column vector.
- *
- * @param {Matrix4} matrix The matrix.
- * @param {Cartesian4} cartesian The vector.
- * @param {Cartesian4} result The object onto which to store the result.
- * @returns {Cartesian4} The modified result parameter.
- */
- Matrix4.multiplyByVector = function (matrix, cartesian, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("cartesian", cartesian);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const vX = cartesian.x;
- const vY = cartesian.y;
- const vZ = cartesian.z;
- const vW = cartesian.w;
- const x = matrix[0] * vX + matrix[4] * vY + matrix[8] * vZ + matrix[12] * vW;
- const y = matrix[1] * vX + matrix[5] * vY + matrix[9] * vZ + matrix[13] * vW;
- const z = matrix[2] * vX + matrix[6] * vY + matrix[10] * vZ + matrix[14] * vW;
- const w = matrix[3] * vX + matrix[7] * vY + matrix[11] * vZ + matrix[15] * vW;
- result.x = x;
- result.y = y;
- result.z = z;
- result.w = w;
- return result;
- };
- /**
- * Computes the product of a matrix and a {@link Cartesian3}. This is equivalent to calling {@link Matrix4.multiplyByVector}
- * with a {@link Cartesian4} with a <code>w</code> component of zero.
- *
- * @param {Matrix4} matrix The matrix.
- * @param {Cartesian3} cartesian The point.
- * @param {Cartesian3} result The object onto which to store the result.
- * @returns {Cartesian3} The modified result parameter.
- *
- * @example
- * const p = new Cesium.Cartesian3(1.0, 2.0, 3.0);
- * const result = Cesium.Matrix4.multiplyByPointAsVector(matrix, p, new Cesium.Cartesian3());
- * // A shortcut for
- * // Cartesian3 p = ...
- * // Cesium.Matrix4.multiplyByVector(matrix, new Cesium.Cartesian4(p.x, p.y, p.z, 0.0), result);
- */
- Matrix4.multiplyByPointAsVector = function (matrix, cartesian, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("cartesian", cartesian);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const vX = cartesian.x;
- const vY = cartesian.y;
- const vZ = cartesian.z;
- const x = matrix[0] * vX + matrix[4] * vY + matrix[8] * vZ;
- const y = matrix[1] * vX + matrix[5] * vY + matrix[9] * vZ;
- const z = matrix[2] * vX + matrix[6] * vY + matrix[10] * vZ;
- result.x = x;
- result.y = y;
- result.z = z;
- return result;
- };
- /**
- * Computes the product of a matrix and a {@link Cartesian3}. This is equivalent to calling {@link Matrix4.multiplyByVector}
- * with a {@link Cartesian4} with a <code>w</code> component of 1, but returns a {@link Cartesian3} instead of a {@link Cartesian4}.
- *
- * @param {Matrix4} matrix The matrix.
- * @param {Cartesian3} cartesian The point.
- * @param {Cartesian3} result The object onto which to store the result.
- * @returns {Cartesian3} The modified result parameter.
- *
- * @example
- * const p = new Cesium.Cartesian3(1.0, 2.0, 3.0);
- * const result = Cesium.Matrix4.multiplyByPoint(matrix, p, new Cesium.Cartesian3());
- */
- Matrix4.multiplyByPoint = function (matrix, cartesian, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("cartesian", cartesian);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const vX = cartesian.x;
- const vY = cartesian.y;
- const vZ = cartesian.z;
- const x = matrix[0] * vX + matrix[4] * vY + matrix[8] * vZ + matrix[12];
- const y = matrix[1] * vX + matrix[5] * vY + matrix[9] * vZ + matrix[13];
- const z = matrix[2] * vX + matrix[6] * vY + matrix[10] * vZ + matrix[14];
- result.x = x;
- result.y = y;
- result.z = z;
- return result;
- };
- /**
- * Computes the product of a matrix and a scalar.
- *
- * @param {Matrix4} matrix The matrix.
- * @param {Number} scalar The number to multiply by.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @example
- * //create a Matrix4 instance which is a scaled version of the supplied Matrix4
- * // m = [10.0, 11.0, 12.0, 13.0]
- * // [14.0, 15.0, 16.0, 17.0]
- * // [18.0, 19.0, 20.0, 21.0]
- * // [22.0, 23.0, 24.0, 25.0]
- *
- * const a = Cesium.Matrix4.multiplyByScalar(m, -2, new Cesium.Matrix4());
- *
- * // m remains the same
- * // a = [-20.0, -22.0, -24.0, -26.0]
- * // [-28.0, -30.0, -32.0, -34.0]
- * // [-36.0, -38.0, -40.0, -42.0]
- * // [-44.0, -46.0, -48.0, -50.0]
- */
- Matrix4.multiplyByScalar = function (matrix, scalar, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.number("scalar", scalar);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result[0] = matrix[0] * scalar;
- result[1] = matrix[1] * scalar;
- result[2] = matrix[2] * scalar;
- result[3] = matrix[3] * scalar;
- result[4] = matrix[4] * scalar;
- result[5] = matrix[5] * scalar;
- result[6] = matrix[6] * scalar;
- result[7] = matrix[7] * scalar;
- result[8] = matrix[8] * scalar;
- result[9] = matrix[9] * scalar;
- result[10] = matrix[10] * scalar;
- result[11] = matrix[11] * scalar;
- result[12] = matrix[12] * scalar;
- result[13] = matrix[13] * scalar;
- result[14] = matrix[14] * scalar;
- result[15] = matrix[15] * scalar;
- return result;
- };
- /**
- * Computes a negated copy of the provided matrix.
- *
- * @param {Matrix4} matrix The matrix to negate.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @example
- * //create a new Matrix4 instance which is a negation of a Matrix4
- * // m = [10.0, 11.0, 12.0, 13.0]
- * // [14.0, 15.0, 16.0, 17.0]
- * // [18.0, 19.0, 20.0, 21.0]
- * // [22.0, 23.0, 24.0, 25.0]
- *
- * const a = Cesium.Matrix4.negate(m, new Cesium.Matrix4());
- *
- * // m remains the same
- * // a = [-10.0, -11.0, -12.0, -13.0]
- * // [-14.0, -15.0, -16.0, -17.0]
- * // [-18.0, -19.0, -20.0, -21.0]
- * // [-22.0, -23.0, -24.0, -25.0]
- */
- Matrix4.negate = function (matrix, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result[0] = -matrix[0];
- result[1] = -matrix[1];
- result[2] = -matrix[2];
- result[3] = -matrix[3];
- result[4] = -matrix[4];
- result[5] = -matrix[5];
- result[6] = -matrix[6];
- result[7] = -matrix[7];
- result[8] = -matrix[8];
- result[9] = -matrix[9];
- result[10] = -matrix[10];
- result[11] = -matrix[11];
- result[12] = -matrix[12];
- result[13] = -matrix[13];
- result[14] = -matrix[14];
- result[15] = -matrix[15];
- return result;
- };
- /**
- * Computes the transpose of the provided matrix.
- *
- * @param {Matrix4} matrix The matrix to transpose.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @example
- * //returns transpose of a Matrix4
- * // m = [10.0, 11.0, 12.0, 13.0]
- * // [14.0, 15.0, 16.0, 17.0]
- * // [18.0, 19.0, 20.0, 21.0]
- * // [22.0, 23.0, 24.0, 25.0]
- *
- * const a = Cesium.Matrix4.transpose(m, new Cesium.Matrix4());
- *
- * // m remains the same
- * // a = [10.0, 14.0, 18.0, 22.0]
- * // [11.0, 15.0, 19.0, 23.0]
- * // [12.0, 16.0, 20.0, 24.0]
- * // [13.0, 17.0, 21.0, 25.0]
- */
- Matrix4.transpose = function (matrix, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- const matrix1 = matrix[1];
- const matrix2 = matrix[2];
- const matrix3 = matrix[3];
- const matrix6 = matrix[6];
- const matrix7 = matrix[7];
- const matrix11 = matrix[11];
- result[0] = matrix[0];
- result[1] = matrix[4];
- result[2] = matrix[8];
- result[3] = matrix[12];
- result[4] = matrix1;
- result[5] = matrix[5];
- result[6] = matrix[9];
- result[7] = matrix[13];
- result[8] = matrix2;
- result[9] = matrix6;
- result[10] = matrix[10];
- result[11] = matrix[14];
- result[12] = matrix3;
- result[13] = matrix7;
- result[14] = matrix11;
- result[15] = matrix[15];
- return result;
- };
- /**
- * Computes a matrix, which contains the absolute (unsigned) values of the provided matrix's elements.
- *
- * @param {Matrix4} matrix The matrix with signed elements.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- */
- Matrix4.abs = function (matrix, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result[0] = Math.abs(matrix[0]);
- result[1] = Math.abs(matrix[1]);
- result[2] = Math.abs(matrix[2]);
- result[3] = Math.abs(matrix[3]);
- result[4] = Math.abs(matrix[4]);
- result[5] = Math.abs(matrix[5]);
- result[6] = Math.abs(matrix[6]);
- result[7] = Math.abs(matrix[7]);
- result[8] = Math.abs(matrix[8]);
- result[9] = Math.abs(matrix[9]);
- result[10] = Math.abs(matrix[10]);
- result[11] = Math.abs(matrix[11]);
- result[12] = Math.abs(matrix[12]);
- result[13] = Math.abs(matrix[13]);
- result[14] = Math.abs(matrix[14]);
- result[15] = Math.abs(matrix[15]);
- return result;
- };
- /**
- * Compares the provided matrices componentwise and returns
- * <code>true</code> if they are equal, <code>false</code> otherwise.
- *
- * @param {Matrix4} [left] The first matrix.
- * @param {Matrix4} [right] The second matrix.
- * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise.
- *
- * @example
- * //compares two Matrix4 instances
- *
- * // a = [10.0, 14.0, 18.0, 22.0]
- * // [11.0, 15.0, 19.0, 23.0]
- * // [12.0, 16.0, 20.0, 24.0]
- * // [13.0, 17.0, 21.0, 25.0]
- *
- * // b = [10.0, 14.0, 18.0, 22.0]
- * // [11.0, 15.0, 19.0, 23.0]
- * // [12.0, 16.0, 20.0, 24.0]
- * // [13.0, 17.0, 21.0, 25.0]
- *
- * if(Cesium.Matrix4.equals(a,b)) {
- * console.log("Both matrices are equal");
- * } else {
- * console.log("They are not equal");
- * }
- *
- * //Prints "Both matrices are equal" on the console
- */
- Matrix4.equals = function (left, right) {
- // Given that most matrices will be transformation matrices, the elements
- // are tested in order such that the test is likely to fail as early
- // as possible. I _think_ this is just as friendly to the L1 cache
- // as testing in index order. It is certainty faster in practice.
- return (
- left === right ||
- (defined(left) &&
- defined(right) &&
- // Translation
- left[12] === right[12] &&
- left[13] === right[13] &&
- left[14] === right[14] &&
- // Rotation/scale
- left[0] === right[0] &&
- left[1] === right[1] &&
- left[2] === right[2] &&
- left[4] === right[4] &&
- left[5] === right[5] &&
- left[6] === right[6] &&
- left[8] === right[8] &&
- left[9] === right[9] &&
- left[10] === right[10] &&
- // Bottom row
- left[3] === right[3] &&
- left[7] === right[7] &&
- left[11] === right[11] &&
- left[15] === right[15])
- );
- };
- /**
- * Compares the provided matrices componentwise and returns
- * <code>true</code> if they are within the provided epsilon,
- * <code>false</code> otherwise.
- *
- * @param {Matrix4} [left] The first matrix.
- * @param {Matrix4} [right] The second matrix.
- * @param {Number} [epsilon=0] The epsilon to use for equality testing.
- * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise.
- *
- * @example
- * //compares two Matrix4 instances
- *
- * // a = [10.5, 14.5, 18.5, 22.5]
- * // [11.5, 15.5, 19.5, 23.5]
- * // [12.5, 16.5, 20.5, 24.5]
- * // [13.5, 17.5, 21.5, 25.5]
- *
- * // b = [10.0, 14.0, 18.0, 22.0]
- * // [11.0, 15.0, 19.0, 23.0]
- * // [12.0, 16.0, 20.0, 24.0]
- * // [13.0, 17.0, 21.0, 25.0]
- *
- * if(Cesium.Matrix4.equalsEpsilon(a,b,0.1)){
- * console.log("Difference between both the matrices is less than 0.1");
- * } else {
- * console.log("Difference between both the matrices is not less than 0.1");
- * }
- *
- * //Prints "Difference between both the matrices is not less than 0.1" on the console
- */
- Matrix4.equalsEpsilon = function (left, right, epsilon) {
- epsilon = defaultValue(epsilon, 0);
- return (
- left === right ||
- (defined(left) &&
- defined(right) &&
- Math.abs(left[0] - right[0]) <= epsilon &&
- Math.abs(left[1] - right[1]) <= epsilon &&
- Math.abs(left[2] - right[2]) <= epsilon &&
- Math.abs(left[3] - right[3]) <= epsilon &&
- Math.abs(left[4] - right[4]) <= epsilon &&
- Math.abs(left[5] - right[5]) <= epsilon &&
- Math.abs(left[6] - right[6]) <= epsilon &&
- Math.abs(left[7] - right[7]) <= epsilon &&
- Math.abs(left[8] - right[8]) <= epsilon &&
- Math.abs(left[9] - right[9]) <= epsilon &&
- Math.abs(left[10] - right[10]) <= epsilon &&
- Math.abs(left[11] - right[11]) <= epsilon &&
- Math.abs(left[12] - right[12]) <= epsilon &&
- Math.abs(left[13] - right[13]) <= epsilon &&
- Math.abs(left[14] - right[14]) <= epsilon &&
- Math.abs(left[15] - right[15]) <= epsilon)
- );
- };
- /**
- * Gets the translation portion of the provided matrix, assuming the matrix is an affine transformation matrix.
- *
- * @param {Matrix4} matrix The matrix to use.
- * @param {Cartesian3} result The object onto which to store the result.
- * @returns {Cartesian3} The modified result parameter.
- */
- Matrix4.getTranslation = function (matrix, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result.x = matrix[12];
- result.y = matrix[13];
- result.z = matrix[14];
- return result;
- };
- /**
- * Gets the upper left 3x3 matrix of the provided matrix.
- *
- * @param {Matrix4} matrix The matrix to use.
- * @param {Matrix3} result The object onto which to store the result.
- * @returns {Matrix3} The modified result parameter.
- *
- * @example
- * // returns a Matrix3 instance from a Matrix4 instance
- *
- * // m = [10.0, 14.0, 18.0, 22.0]
- * // [11.0, 15.0, 19.0, 23.0]
- * // [12.0, 16.0, 20.0, 24.0]
- * // [13.0, 17.0, 21.0, 25.0]
- *
- * const b = new Cesium.Matrix3();
- * Cesium.Matrix4.getMatrix3(m,b);
- *
- * // b = [10.0, 14.0, 18.0]
- * // [11.0, 15.0, 19.0]
- * // [12.0, 16.0, 20.0]
- */
- Matrix4.getMatrix3 = function (matrix, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- result[0] = matrix[0];
- result[1] = matrix[1];
- result[2] = matrix[2];
- result[3] = matrix[4];
- result[4] = matrix[5];
- result[5] = matrix[6];
- result[6] = matrix[8];
- result[7] = matrix[9];
- result[8] = matrix[10];
- return result;
- };
- const scratchInverseRotation = new Matrix3();
- const scratchMatrix3Zero = new Matrix3();
- const scratchBottomRow = new Cartesian4();
- const scratchExpectedBottomRow = new Cartesian4(0.0, 0.0, 0.0, 1.0);
- /**
- * Computes the inverse of the provided matrix using Cramers Rule.
- * If the determinant is zero, the matrix can not be inverted, and an exception is thrown.
- * If the matrix is a proper rigid transformation, it is more efficient
- * to invert it with {@link Matrix4.inverseTransformation}.
- *
- * @param {Matrix4} matrix The matrix to invert.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- *
- * @exception {RuntimeError} matrix is not invertible because its determinate is zero.
- */
- Matrix4.inverse = function (matrix, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- //
- // Ported from:
- // ftp://download.intel.com/design/PentiumIII/sml/24504301.pdf
- //
- const src0 = matrix[0];
- const src1 = matrix[4];
- const src2 = matrix[8];
- const src3 = matrix[12];
- const src4 = matrix[1];
- const src5 = matrix[5];
- const src6 = matrix[9];
- const src7 = matrix[13];
- const src8 = matrix[2];
- const src9 = matrix[6];
- const src10 = matrix[10];
- const src11 = matrix[14];
- const src12 = matrix[3];
- const src13 = matrix[7];
- const src14 = matrix[11];
- const src15 = matrix[15];
- // calculate pairs for first 8 elements (cofactors)
- let tmp0 = src10 * src15;
- let tmp1 = src11 * src14;
- let tmp2 = src9 * src15;
- let tmp3 = src11 * src13;
- let tmp4 = src9 * src14;
- let tmp5 = src10 * src13;
- let tmp6 = src8 * src15;
- let tmp7 = src11 * src12;
- let tmp8 = src8 * src14;
- let tmp9 = src10 * src12;
- let tmp10 = src8 * src13;
- let tmp11 = src9 * src12;
- // calculate first 8 elements (cofactors)
- const dst0 =
- tmp0 * src5 +
- tmp3 * src6 +
- tmp4 * src7 -
- (tmp1 * src5 + tmp2 * src6 + tmp5 * src7);
- const dst1 =
- tmp1 * src4 +
- tmp6 * src6 +
- tmp9 * src7 -
- (tmp0 * src4 + tmp7 * src6 + tmp8 * src7);
- const dst2 =
- tmp2 * src4 +
- tmp7 * src5 +
- tmp10 * src7 -
- (tmp3 * src4 + tmp6 * src5 + tmp11 * src7);
- const dst3 =
- tmp5 * src4 +
- tmp8 * src5 +
- tmp11 * src6 -
- (tmp4 * src4 + tmp9 * src5 + tmp10 * src6);
- const dst4 =
- tmp1 * src1 +
- tmp2 * src2 +
- tmp5 * src3 -
- (tmp0 * src1 + tmp3 * src2 + tmp4 * src3);
- const dst5 =
- tmp0 * src0 +
- tmp7 * src2 +
- tmp8 * src3 -
- (tmp1 * src0 + tmp6 * src2 + tmp9 * src3);
- const dst6 =
- tmp3 * src0 +
- tmp6 * src1 +
- tmp11 * src3 -
- (tmp2 * src0 + tmp7 * src1 + tmp10 * src3);
- const dst7 =
- tmp4 * src0 +
- tmp9 * src1 +
- tmp10 * src2 -
- (tmp5 * src0 + tmp8 * src1 + tmp11 * src2);
- // calculate pairs for second 8 elements (cofactors)
- tmp0 = src2 * src7;
- tmp1 = src3 * src6;
- tmp2 = src1 * src7;
- tmp3 = src3 * src5;
- tmp4 = src1 * src6;
- tmp5 = src2 * src5;
- tmp6 = src0 * src7;
- tmp7 = src3 * src4;
- tmp8 = src0 * src6;
- tmp9 = src2 * src4;
- tmp10 = src0 * src5;
- tmp11 = src1 * src4;
- // calculate second 8 elements (cofactors)
- const dst8 =
- tmp0 * src13 +
- tmp3 * src14 +
- tmp4 * src15 -
- (tmp1 * src13 + tmp2 * src14 + tmp5 * src15);
- const dst9 =
- tmp1 * src12 +
- tmp6 * src14 +
- tmp9 * src15 -
- (tmp0 * src12 + tmp7 * src14 + tmp8 * src15);
- const dst10 =
- tmp2 * src12 +
- tmp7 * src13 +
- tmp10 * src15 -
- (tmp3 * src12 + tmp6 * src13 + tmp11 * src15);
- const dst11 =
- tmp5 * src12 +
- tmp8 * src13 +
- tmp11 * src14 -
- (tmp4 * src12 + tmp9 * src13 + tmp10 * src14);
- const dst12 =
- tmp2 * src10 +
- tmp5 * src11 +
- tmp1 * src9 -
- (tmp4 * src11 + tmp0 * src9 + tmp3 * src10);
- const dst13 =
- tmp8 * src11 +
- tmp0 * src8 +
- tmp7 * src10 -
- (tmp6 * src10 + tmp9 * src11 + tmp1 * src8);
- const dst14 =
- tmp6 * src9 +
- tmp11 * src11 +
- tmp3 * src8 -
- (tmp10 * src11 + tmp2 * src8 + tmp7 * src9);
- const dst15 =
- tmp10 * src10 +
- tmp4 * src8 +
- tmp9 * src9 -
- (tmp8 * src9 + tmp11 * src10 + tmp5 * src8);
- // calculate determinant
- let det = src0 * dst0 + src1 * dst1 + src2 * dst2 + src3 * dst3;
- if (Math.abs(det) < CesiumMath.EPSILON21) {
- // Special case for a zero scale matrix that can occur, for example,
- // when a model's node has a [0, 0, 0] scale.
- if (
- Matrix3.equalsEpsilon(
- Matrix4.getMatrix3(matrix, scratchInverseRotation),
- scratchMatrix3Zero,
- CesiumMath.EPSILON7
- ) &&
- Cartesian4.equals(
- Matrix4.getRow(matrix, 3, scratchBottomRow),
- scratchExpectedBottomRow
- )
- ) {
- result[0] = 0.0;
- result[1] = 0.0;
- result[2] = 0.0;
- result[3] = 0.0;
- result[4] = 0.0;
- result[5] = 0.0;
- result[6] = 0.0;
- result[7] = 0.0;
- result[8] = 0.0;
- result[9] = 0.0;
- result[10] = 0.0;
- result[11] = 0.0;
- result[12] = -matrix[12];
- result[13] = -matrix[13];
- result[14] = -matrix[14];
- result[15] = 1.0;
- return result;
- }
- throw new RuntimeError(
- "matrix is not invertible because its determinate is zero."
- );
- }
- // calculate matrix inverse
- det = 1.0 / det;
- result[0] = dst0 * det;
- result[1] = dst1 * det;
- result[2] = dst2 * det;
- result[3] = dst3 * det;
- result[4] = dst4 * det;
- result[5] = dst5 * det;
- result[6] = dst6 * det;
- result[7] = dst7 * det;
- result[8] = dst8 * det;
- result[9] = dst9 * det;
- result[10] = dst10 * det;
- result[11] = dst11 * det;
- result[12] = dst12 * det;
- result[13] = dst13 * det;
- result[14] = dst14 * det;
- result[15] = dst15 * det;
- return result;
- };
- /**
- * Computes the inverse of the provided matrix assuming it is a proper rigid matrix,
- * where the upper left 3x3 elements are a rotation matrix,
- * and the upper three elements in the fourth column are the translation.
- * The bottom row is assumed to be [0, 0, 0, 1].
- * The matrix is not verified to be in the proper form.
- * This method is faster than computing the inverse for a general 4x4
- * matrix using {@link Matrix4.inverse}.
- *
- * @param {Matrix4} matrix The matrix to invert.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- */
- Matrix4.inverseTransformation = function (matrix, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- //This function is an optimized version of the below 4 lines.
- //const rT = Matrix3.transpose(Matrix4.getMatrix3(matrix));
- //const rTN = Matrix3.negate(rT);
- //const rTT = Matrix3.multiplyByVector(rTN, Matrix4.getTranslation(matrix));
- //return Matrix4.fromRotationTranslation(rT, rTT, result);
- const matrix0 = matrix[0];
- const matrix1 = matrix[1];
- const matrix2 = matrix[2];
- const matrix4 = matrix[4];
- const matrix5 = matrix[5];
- const matrix6 = matrix[6];
- const matrix8 = matrix[8];
- const matrix9 = matrix[9];
- const matrix10 = matrix[10];
- const vX = matrix[12];
- const vY = matrix[13];
- const vZ = matrix[14];
- const x = -matrix0 * vX - matrix1 * vY - matrix2 * vZ;
- const y = -matrix4 * vX - matrix5 * vY - matrix6 * vZ;
- const z = -matrix8 * vX - matrix9 * vY - matrix10 * vZ;
- result[0] = matrix0;
- result[1] = matrix4;
- result[2] = matrix8;
- result[3] = 0.0;
- result[4] = matrix1;
- result[5] = matrix5;
- result[6] = matrix9;
- result[7] = 0.0;
- result[8] = matrix2;
- result[9] = matrix6;
- result[10] = matrix10;
- result[11] = 0.0;
- result[12] = x;
- result[13] = y;
- result[14] = z;
- result[15] = 1.0;
- return result;
- };
- const scratchTransposeMatrix = new Matrix4();
- /**
- * Computes the inverse transpose of a matrix.
- *
- * @param {Matrix4} matrix The matrix to transpose and invert.
- * @param {Matrix4} result The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter.
- */
- Matrix4.inverseTranspose = function (matrix, result) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("matrix", matrix);
- Check.typeOf.object("result", result);
- //>>includeEnd('debug');
- return Matrix4.inverse(
- Matrix4.transpose(matrix, scratchTransposeMatrix),
- result
- );
- };
- /**
- * An immutable Matrix4 instance initialized to the identity matrix.
- *
- * @type {Matrix4}
- * @constant
- */
- Matrix4.IDENTITY = Object.freeze(
- new Matrix4(
- 1.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 1.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 1.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 1.0
- )
- );
- /**
- * An immutable Matrix4 instance initialized to the zero matrix.
- *
- * @type {Matrix4}
- * @constant
- */
- Matrix4.ZERO = Object.freeze(
- new Matrix4(
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- )
- );
- /**
- * The index into Matrix4 for column 0, row 0.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN0ROW0 = 0;
- /**
- * The index into Matrix4 for column 0, row 1.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN0ROW1 = 1;
- /**
- * The index into Matrix4 for column 0, row 2.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN0ROW2 = 2;
- /**
- * The index into Matrix4 for column 0, row 3.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN0ROW3 = 3;
- /**
- * The index into Matrix4 for column 1, row 0.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN1ROW0 = 4;
- /**
- * The index into Matrix4 for column 1, row 1.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN1ROW1 = 5;
- /**
- * The index into Matrix4 for column 1, row 2.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN1ROW2 = 6;
- /**
- * The index into Matrix4 for column 1, row 3.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN1ROW3 = 7;
- /**
- * The index into Matrix4 for column 2, row 0.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN2ROW0 = 8;
- /**
- * The index into Matrix4 for column 2, row 1.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN2ROW1 = 9;
- /**
- * The index into Matrix4 for column 2, row 2.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN2ROW2 = 10;
- /**
- * The index into Matrix4 for column 2, row 3.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN2ROW3 = 11;
- /**
- * The index into Matrix4 for column 3, row 0.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN3ROW0 = 12;
- /**
- * The index into Matrix4 for column 3, row 1.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN3ROW1 = 13;
- /**
- * The index into Matrix4 for column 3, row 2.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN3ROW2 = 14;
- /**
- * The index into Matrix4 for column 3, row 3.
- *
- * @type {Number}
- * @constant
- */
- Matrix4.COLUMN3ROW3 = 15;
- Object.defineProperties(Matrix4.prototype, {
- /**
- * Gets the number of items in the collection.
- * @memberof Matrix4.prototype
- *
- * @type {Number}
- */
- length: {
- get: function () {
- return Matrix4.packedLength;
- },
- },
- });
- /**
- * Duplicates the provided Matrix4 instance.
- *
- * @param {Matrix4} [result] The object onto which to store the result.
- * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided.
- */
- Matrix4.prototype.clone = function (result) {
- return Matrix4.clone(this, result);
- };
- /**
- * Compares this matrix to the provided matrix componentwise and returns
- * <code>true</code> if they are equal, <code>false</code> otherwise.
- *
- * @param {Matrix4} [right] The right hand side matrix.
- * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise.
- */
- Matrix4.prototype.equals = function (right) {
- return Matrix4.equals(this, right);
- };
- /**
- * @private
- */
- Matrix4.equalsArray = function (matrix, array, offset) {
- return (
- matrix[0] === array[offset] &&
- matrix[1] === array[offset + 1] &&
- matrix[2] === array[offset + 2] &&
- matrix[3] === array[offset + 3] &&
- matrix[4] === array[offset + 4] &&
- matrix[5] === array[offset + 5] &&
- matrix[6] === array[offset + 6] &&
- matrix[7] === array[offset + 7] &&
- matrix[8] === array[offset + 8] &&
- matrix[9] === array[offset + 9] &&
- matrix[10] === array[offset + 10] &&
- matrix[11] === array[offset + 11] &&
- matrix[12] === array[offset + 12] &&
- matrix[13] === array[offset + 13] &&
- matrix[14] === array[offset + 14] &&
- matrix[15] === array[offset + 15]
- );
- };
- /**
- * Compares this matrix to the provided matrix componentwise and returns
- * <code>true</code> if they are within the provided epsilon,
- * <code>false</code> otherwise.
- *
- * @param {Matrix4} [right] The right hand side matrix.
- * @param {Number} [epsilon=0] The epsilon to use for equality testing.
- * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise.
- */
- Matrix4.prototype.equalsEpsilon = function (right, epsilon) {
- return Matrix4.equalsEpsilon(this, right, epsilon);
- };
- /**
- * Computes a string representing this Matrix with each row being
- * on a separate line and in the format '(column0, column1, column2, column3)'.
- *
- * @returns {String} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1, column2, column3)'.
- */
- Matrix4.prototype.toString = function () {
- return (
- `(${this[0]}, ${this[4]}, ${this[8]}, ${this[12]})\n` +
- `(${this[1]}, ${this[5]}, ${this[9]}, ${this[13]})\n` +
- `(${this[2]}, ${this[6]}, ${this[10]}, ${this[14]})\n` +
- `(${this[3]}, ${this[7]}, ${this[11]}, ${this[15]})`
- );
- };
- export default Matrix4;
|