three-player-controller 0.3.4 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +215 -81
- package/dist/index.d.mts +25 -4
- package/dist/index.d.ts +25 -4
- package/dist/index.js +1024 -5330
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +844 -196
- package/dist/index.mjs.map +1 -1
- package/package.json +18 -9
- package/dist/rapier.es-XQHNYU2P.mjs +0 -4966
- package/dist/rapier.es-XQHNYU2P.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -6,12 +6,18 @@ import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
|
|
|
6
6
|
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
7
7
|
import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js";
|
|
8
8
|
|
|
9
|
+
// assets/imgs/break.png
|
|
10
|
+
var break_default = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAQAElEQVR4AeydibnruJGFxUnEdiTTHUm7I+l2JLYjsScS90RyfX5eQI+iSBCFjSCF97EuN6A21EEVSEnvfx7j3/DA8MCuBwZAdl0zbgwPPB4DICMKhgcCHhgACThn3BoeGAAZMTA8EPBARYAEpI5bwwMX8cAAyEUGaqh5jgcGQM7x+5B6EQ8MgFxkoIaa53hgAOQcvw+pF/HANQFyEecONa/vgQGQ64/hsKCiBwZAKjp3sL6+BwZArj+Gw4KKHhgAqejcwfr6HhgAWY3hOB0eWHpgAGTpjXE8PLDywADIyiHjdHhg6YEBkKU3xvHwwMoDAyArh4zT4YGlBwZAlt6oezy4X9ADAyAXHLShcjsPDIC08/WQdEEPDIBccNCGyu08MADSztdD0gU9MACyMWhfX19/dvRX7X8T/V30L2ijefIl8ZvlJDN4dhwHtTwwACLPukAFCNCXLv3H0d+1/130k+hv0zT9rL15E3+ABgG0/+gcesrROeBD9k86/rNZwOhQzQMfCRCCUERAEpg+UAECtHb2v6dp+ss0Tf9e3widiz+A8EAAaNBf1QcAQDp8bgAQ2f/SlbmP+qPbAIwccub2MQBRwFHOAAqfHQhIAjPk/98FjOisIRmAgsAGdABiDYSQrPU9dPOAgSe65/Bb8x/nER64NUAUsFugiA2yXwWOv0X48CE5BK8HBYEd083SBp4AmuwCWABirB0WOaPtygO3BIgCdgaGbCVbEFjWYPpZ4PiH+gc3yaEEYpZHRrBtwZuAhewEWFjTWG2zqfLhrW8FEBewgAJKDVrAcbjekCyCFHAQsGeFEWsagEJWOVOPs+yvLvcWAFGwUuIACgI2Z0Y9BIdkkTUopwjO6gMUKQBwABKI48huo9mRBy4NEBesAINskQMM/MSCPJg5JA9QAELa90iAA5BAHPeo46V0uiRAFKisMQhUKBcYDBiPcoMLcsn8TQ0pq7TrfgMcgAQq4Z/uDa6l4KUAoiAFGAQpWYMgKOGXP7QgDz7KlVxkkqVKyGvJAx+xRqEE7Q4oLR2RKusyAFGQMoMDDMqcVHu3+v26ddFfk1yyVGmZnn2rPeAmm1zdjlb+esrpHiAKULIGQcogPxUvdBBcd0g2oGQWLiTuVDZkEB4LAxSOT1XmKsK7BogClBmPrFEjSIPrDslGZg1Qnh0b2AVI2J+tS/fyuwSIgtNnDWr/Wk7cXZQjX0LJWtrdciODAJKxNjkY3u4AsgjOmjMc2SP0SLcmMA+GpOltMiRlF4BpKriysGLsuwKIwAEoKKlqD1goe9xp3RETKPicbFLb5zG6dNemG4AIHARmi7JmN3tIB4KEWbW7gaqsEHbzOJg1X2VR12LfBUAUmACjVWDuZg8N3S+iT94ot8a6ZBEBpwPEgYM0v1Cr2uHIHseuZaL6ReNCVjluffMWpwJEg0DmaAUOhjK0MP/07IF/PA2QOE+8A8TdqL07ARyY9E/+rEm6MFsSFOtbn3yOPz4+k5wCEAVk68wxB/o0TX/MB+9/RvZ49wlXAAnrEiYQzj+OmgJEwPAvAFuWVX5QQ98QPEMfr1fve3zzsSBpChBFAi/gcLgOm2//tyUR0Or6WTpJ9CU2/PORWbYZQBSIp5RVPvxUXu1lEAbfN4vZwwei/OCTwJ74yDzEOfcg2vFgANor72Jk9tDmd40h76p60KWZDk0A4hz7UzOr3gURoO9Xv6/86Xu3+ZcAJ+D5XSxhbN74tROIH5L7h654mh8hu3PuQbTja7zQzENSABHgQaergebjQFIdIAIHMzQBodg4bQsFIvp5xdaAIMABQKi/7xu1F4AAEuCZQaNOHjDFZIhnzQ2QfMyivSpAHDgorWoOWC5vAOKzRHFAHCm3AMxf1BawANLewcLHUj4CJFUBogFnUa7d6dvmAh2tFKBsRbMEfFNIipBdAKkHC2VYCqsWfT7iA47VAKLsQeb4iFmmRjQ6sJBRoB4zCmN7+ydbVQAicFC2QDViZ4vn0bWeZ+Kg7g4oZBTKwN6Acvv1SHGACBzMLGSP4MA3vNlbUCWZLqBQBgIUHnj0ZNOtS63iANHo97LukCoPanoer/YUUI+cfwIKT8AACov5HFal+jIh3rbUKgoQZQ9eJPVSWvGLJdTvpQKhKz4CCiVXL9mEUuuWX7YqChBFEAOm3akb2YJ3DKEvRp2qYCnhAgk2AhRsLsU2lc8tv2hVDCDKHj2UVr6kKrgoD8eL7OYDmAQHxIf6mv7fHQLJbLO0bGazZG1ttyy1igBEQUJZdXaKZRHbtKSS3ZSU/MgEmRPCB0wULFy5txVIVa4JKNiODlX4RzKl1AIokc37b1YEIDKzaTBI3npjvUGpsb5e7Vzg4EndXkASJAQLbarpsGYskFBy7em0bl7r/OxYKGpXNkAUKMyaZJCiihmY8eaZwDB0yWsqmwmCGJv5v0RomyfQ0LsDkDQtMQ2uSWqaDRBJbRoAkrfcWIyf8bjTMkszgSx1rn7cAUgoM6vb2UJAFkA0kzL4lBMtdF3LIHM0X5jK5pjMsdSVRfx2n2Wrwscng4TMeVZcFPVkFkCkyVnZgwX5GZlDJj8uM/Ang+QWWSQZIJpJz8oePNZsuiB/vP5LeeeQ0udVauKZA8kZ8m+RRZIBovE64+MFgIPHmRJ/2mYONgWpuU9h6/DZGTpcPoskAUTZg5oaKjyOh+yyMof0zl4PuGC3rH2ySkGvs/bJ/nY686SvNUgun0WSAKIwPiN7sCg3D7ACC1Dwlpv/upmXerzE0+UvvhWXGnQWoBKYcplt+/r6IrieOqs3eqNz1LpP7V82gQSgQi/XG5ycESvFzEoFCOuPYkpEMKK0Mg8uQSbegOJ37dcbi22CzhxwCjaAelS2zG1c27Xs4Ln0Rqetl4zozAtIgMJxkM/6pnQBrOi1vlXz/NLvRcwA0eC1BgeDZ5mxae8ppgYm4Mw2KdgoswAJ4OPYyyQAebPPx+yX1/394F7+BRzwDLUDHFsACvXx99AZHf157T26pmbq2rod8jcDRBxbp8zU0gpwMDhS+XCjBItt+2QmkPwh4vsZBB2A0OnEnpn62c54cAQOz47SERv9edR++v75VXM2jmK+3+h/92/1fScFIC1ng6TSyrncoifggFxX+84Fnr3jooeyhzWTWWxcSHrwI94ts8hlyywTQBIGcDkoKcc5M7E14HuY5Zro4MCcmkVSxpE+qWCm72lkAoi0pD7WrslG9jDX8GgmIFvBQbeUPvQrSVYdKLOsfWZ9BRImn5ZZpAn4Z+MK/rECJGkwEvVlAJO6avBTBn73t7OSlEjrZJ4QEm312pFF8BXkr9XaX7LMigaIZmVrfZzj6OTssRBqDTZr+4WoYodWkBLgycIFLh4w8FABmsSIhw0QTw15WFAaOC0nWJmTv0UDRKJapsjk7CE9/cYg++OjPR9+LB0MRzLf7itgAakl6Ev46akH8h3hjxk8uukBg265PmoZQ1I9f7MApNkii0HKNU08GMwYkPCoNqZdrkqx/Ql6dD9qz3dhYtod8Qnelx/J5gAGefzcEIABLMF+OzcPYmin14mXLQBplR4tM2jQdRpceDGoe4E0v9ALMgncVNnJIpmPhFBf8y6FPZQcCNIZXQlCSpwt6fN9tUsN0i2e0deQK0I/CB3QJ7Y/vmoVR7E6BdtFAUSB0HL9wTP6oNKWmxpMBpDBhMgUBB6zoW5NzNYWdg/5AlAABj7CAvFGmxd28GUP8REWNf3iIyG0NQFm0ss8EboBbnSG4I/erBcITJPepRtLPzKL9ykTEX6OEXM/gMjqZrUjjpe8opt4UkYxoJQK1NbmAPv6+gIYgAFQ/C4FYwaaNrQFMPwkEOfqGrc5vdEZStI7TlJ6K+mIXwEwFAMSkw/SNSvTMyqDSJRpBlT71I2ZKLVvtX4CB1kBYOT4gSwMUFq+S4r2iWykNJyznY7NQeyAQsZjQggBpdlkG218oGEsQMwOC8gM3SpaXoUExdwjUERkDYI7pstRG/zIhyMpvTg+at/6PsGNvegHAWjTukFAoTQMZZNSvrT5JrH1IUAUIM0GUs41lz6Jdh92k91ki9yssScHnxJ87PfaNL0u36+zN7rhAw8YSkTOD/USL8oussma59xXvoX3fNz7n0OAyIAop6hd7rbpzFymKf3dABIYKd1j+xAkXYFEiodKI2Z+9IWiYkJAIZOQlcT6ZcP2lwu9nsQApFfda+rFmqMmf8+bQKkNRC8rZh+TwQEHIIHQP8hXIKHkAiRL8B32CzJteDMGIK0WVdaPWVRxk7IH4CAIqvDfYMrTMWRu3Gp+yTIG+Ih1Cgv7YMA7kFAhLEHS3LgUgTEACRqfInSnT8zstdO1zGWBA1spJcowjOdiWgjHszW3TAlgsgPrE3y3K3ABEtq0mnSRlUUxAAkaniV90VkOTBmcBYcih2fN5Pj49Me/GgMmqZRx8NkkOLmIvy+3sLfIgNVm0gtAGJgkW5n1RczApHqe5TNYSbzUKaevumdt2GCWL9sp0aAS9mcZoM5kkiDQHUgAipr3v8UApIUVKbMWH/tgMHgUy0J3TvVSlsUjtbEp2BRowdlPfGtvzKpQtBzpjI3YD63txzfRvAo25D1PULZAkjwhFtQzilUvAIlSdtlIweFBsbzsjwk0gBIcKN/Y7Vv/GIUT+7KL1kH2A2h88MLAnWA/gQpw3KXoXdJkteKObDIaeqxuXes0CBANQpcGSi8Cn9nzyNuWkiuG35G83PtR/pb96BqzXppLL6NSJQCCSDJaNODp0CMFAVJf4acE66Dg/GfnwAEBB5gCTR6UarQLtml0k4CO0SUGHF5lMo0/br0nkwDm1nKLyTsCSMxglVDm/2OZaPa0DniMDTFtYlXMbRejS0wbrwegswSpdbLycvb2lLoWfff4nHL9CCCnKHUg1PoMPSZALjOAmiAswe5dafFZ9GTlmUfsLwuSKwIkZYY76nN0PyIGmjVJ0dUS9H+qYAkT0CXXI0cAYTCgCj57YWkZFMvHIWYheqzYwoZZVoE/NXTt4bEq6xGAUsBF7VgEAeICi09kttPoWBIBBIVb/rjLZ4B+nG0fWfhtc2h01Y2JJeD5NqXFvppBfLksEgQIY64BYTAgTk8n6cNgR7+JVfveAB70ofTFvmAb3bTYZGkr1o+aALlcFjkEyOP7n9XJ373i/5oGRUFEVjh61Eug8aMCh1qIH217mASwK1bfmDHhl/GtdpnG4lDZ9waXyiJRAHEBdBSQ766Iv2IeFOlEFuFba+sAmINd962//gG/eI3rtIxeX8k+wIT9W+OCD/gFFNpYNTWPhVHApbJIFECcA/i+OI53p0V3SYOiIKG+JksQKOwJCoDBsVXBWrZF6yF7TAGt9tjPr53ws6GzD3SNDR+sJ45DPfQIOWkcDhm/N0h5VP3OpcGVaIDI6wRQSuDFmJE1MOgm4nvQ5qDwyqk/9m3Nxr7Jc1/pIEs2+ouS7a9k0x7by5RZ0QDBce7meQAAEABJREFUUg0AQRRT+9LcRJq9ephVyJImvUs1lm97KPGyJiqDL4gjQ/PzmpoAgpoaSMqAKiCB/5kk2xi4M2yrlZmt7hwAWXnMDBD6K5BqgMTycQjUqELOtqxyx6gYv5rYS2lkeWFrNPOazZMAgqkVAsn6IUTUqEWUWi2ClnXTGRlrz2+tJobop3V7ira6ngwQFBRIqJtLObVVekf1IMkuX2qRKYNtM24CjnVplcEur6vWgM38L/+2mHzyHOJ6ZwEEHjIWkPCIkaDiUjJpkHpYqM/6yy7swbZSE8DM1/2hrOoGHE6nVk+W8KsT2f8uCiBHgeuCiQHPDabfenIZdokACWVQiYGFB2+34deTqejSU4mLPl1QFECk6S8CSTB4FUjzSyu1zckmzdK89IzeZBulVs4EADDm/6zH8YqW3aKhxha/Qy3E4csWcorIiAUIiyo+IhAECRopAAgGgolZ0lprxny5CTEmIgBE/IgAP0vDl3fYm2ZM7BKRTZgAsI9sGbIPP9DGv92nr1VvdIaeOsuOGoHcqrzCfmKJ/SUoCiAKDI/6GSRHg6T2ZBNfZxNQvn+MUw5BGMPEt5Gu8OPXPQhWQME6hz0g4eeBTAHnbGOBzUc8CH7/MQ/snM/Vho2Pe9AmBCKv5steOjNR8Isl6Aw9dVZDwIJNOrRswbbwDzYodVOOMfujlOwUPlEAcYyZETlkwAiuqMCSQwAL2YQAYn8EFoIjijfKhEiBxo8boO9eM+QQcOz32hxedzZiZ/bgS2d0AdB7Qct9JipsO9TtqIGTtyfrqLv1vo8ha7/T2lsAshx8HMrsS/pnwA4NcEFEVmGR6mddDxhAA38IXtkpXwOPjmQK+IUI/YsEW0iI4V6sLkm/xLihR7avN3juXWKc9+51ed0CkK3akdk5OpssPbACDKChPIHm0mTZNvE4NtBgXyrY4JVMAjWABtgxPAB2VqklefBgDGPklWhj+W58CXnZPKIBooAG/VspkgElm/AjbTg8W6lCDKy69PBRF+tHPaw2rl3bMntQghJDax2izgVmy4QXxTOmUTRAHDNfArnTlx0GAJSkjPLCKfNEzkwJnJQ+mZq+dbfqkLxecz4qkz3ezNi8sDW5bjZcX5SuxFZy/zU/y7kVIFtl1loeZUIXQFkrdnB+ygCsdDLroMxu7uNktsweiAxNrtzfJIGDMvIn2Wl+TL7J0HjRBBApSYqMHRAPFJ4SRS/mjfpvNpee6GgdkB7q45gJaGkz47E8jzpW0JGpWmaPh8bEHODSkxhCzyQ7o5xx0MgEEMfLGnisUTCSrCKbvwBMi/UKn8h1Kh/ucutjSh0W+rl2AWzoUGHXwGKj6zLvKFnmg0Z/rDHD7yUTN17PVDuzzUsBiHWWWyvpDfeAYQ9oINYvZJslcY0Zb80neK4Zi1kndmB43Bzkt3Xz6+sLUPDOAuLFHgOKPRB2bnXbvSadAUesLrysjLXvKVM640uzbk8GaQcmPZ2O+BNp2IlfOG5OZoBoEAm8kgr7AWPQfEr9XZ7wxDXAQztdNm0EG3z2OmEHj5ZNAwgzDeKsl4639OIawKZ+VpP4Tf5Fl5DOMCNo+LgLx1YCxNY+Oe3JztHllfyK75hwZpn6c1r2kOyHGSB0EgES7ZptOM28qFSw+cEBKOgMIFCavf/wIAHJtWjSIALmo0BDZ0ou2kbzpqH0JqD45AFA8fqhM8cAOgkc0ptZ2awPOmUQfrd0X/qV8bP2t8g6bJsKEFDNgB0KKNiAj1eYZ2TkK+D8G3xeQup0Yk8QcjuFloMY6g9IYtu+8JmmieDgs1wAQqcTOnMMSF7axpwIHPiuNThMi3PpuAbwqeDAr0kAmTR46pw0UOqXswESgi6HR4m+Fh1YwFval9DvhYcCD2CQjV6uNziJlikd1+CYJ4gGOgZFJAHEcSSLuMOmu9T1SBElNZCsPay8TgOI9EU2wWfVuUT7qBiRjlvZ7fTsgQOSAaIsQgZpXWahMwPOApg9560pxeZTdFXgIfcscJABDn0lHZlwtjJNFLgyBj+qazJAHHcWv+6w6Y6SgW85EgBNBUvY4aCrzXpjMllfa3HO+ucMH2HbYWwIHIwjOtJ+SVHgWnaodZwFEJdFzkqFzDrmJ1u5jpTNAASKZXXKYCv4tsqWWJ1z2/EYOjgpSD/AsZfdch6g5Or+0j8LII4TxlgCxnUrsmPRTiAUYWZgcjg7LnhZ2i66pR8q+JiVmUDSmeT1DNos/chqe+BgQjlr0n2zOhsgbkYNzhZvUstemEHinF6W8w432Yy9MQHI91xou8Op/GX5gcCjri/PPI4j2WN3wpR+gAMA73HrBhwomA0QmIjOzCIS/yBYmy7cBRJs5oXdVjBwjXcWzQabwBMBDkqXx4n/gtlDegGOXR2dX9Wsjy0NICvdZRQB0SwYVuL9KU5v+ghYdjNb8sYbIjDIGLo88VKvWeYQMJiV+XgGPvD+OGPPpxOIhU3Z0vMIwEx0m33PulgEICg/TRMz6q5zaNOA5kDRQDQtMSa9OBXxtr75JCFbAQXgaODeoAjWDsTAZiPpGcwcrlMXj3adLvOuGEBmbo8Hs+jZIEEVyi0IwHB+S3JBx6zcg32M/aYe0pMJC9q87y4CsB5ix6nzvSsKEM2ilBXNZ9FvU97+MiCUXOzfbl75AgEn+pINvdhGacXYS6XXTXqS4cgerzfez3azz3vTdleKAgS1BRIM7WUmIIOQSSCOUfGypGDjc11kjJiAa2UnMz9j/iZP+gIO9H27t7oAj+oTq/Qxx0BxgDjD957uuNv7u0p3mGn5EhMfPzc7qZJOJrYa3NkGdSLotOtm2yytpC9+jgEHhlQFh3Thi23ogk7Ii6YqAFEWIYNUNTrawteGzLwAhW8smp31yqr5Gbo3F3ogcLO0UkDi2+gHB4qXzQx0IPvwtvTwwAAcfHVgswwMMaoCEAQ6o7t7bIduIvQCKLcovWTPGRuPuPcC2wJmxqKo/itgkHF5/G4GB0pVAwjMHUjIJpz2SHPZIofOi3ntmflO0/Ns+QbDWTNQRr91kQ3M1gTl272dC8Ue7Ur2MmN4HbIev1cFiHMIjuwZJKiJM5n1yCrNwKIBZU1EFkMuT6U2P3ypdqcCFwetaG/dgQ/x5ar57ilAy44N+WcLGAgly23qys0Yqg4QZREcwHqEfYxOtdrE8mWAGeg5aOV8AMOahUFIDlTx4QnUGhDIIYt5vj38NteRn37WmL6VK7KPD41iy1H/5X3iYnluOpZMxoSMBTFuy/6Aj8l5ec18XB0gaCSHUqtmOQM+JxGOp05mEDxo2AMcT2QBQMQe4jptII3jF9mBResaEGuTep9ENmt5GQgw8NHantA5AUxchNps3pO8EDDogx+zwQGjJgBBkAOJ1Yl07ZGY8QGOJx8g7CGu0waK1l8+epuZXWf4ucPTdjyxepvkCFZpBPC1M21vvI56SxZZmIkKCvkEIAOSI5aH95sBBE0UAMwYdwEJJpWk0IBaf/W9pF7wYqHL2HH8JAJWJwSrdrbNxUJUJ+SIACFZOAQM+G2WgNxIoaYAQUHnGPPsQd+b0172wOyjoKBNLdpc6CpgyY4EbIrckK1PfsgQeWCQmZ/3dg7IclG8d/q/XW4OEDQQSHiycKNMglXZFMogZwEEcLzV8gpawEHgphodfLQLfxH8AWAMMNADXd+yHDdy6BSAoLBAgjEDJDjjmzZ/81iBQjB+t2j7l7LqDRxOBYI3FbQszjcrCGwVwdsCDFQCHHu6cj+ZTgMIGg+Q4IWZCJq90mDz3cjcq94fShWy/JsEBTBrjlRwwG8PHCnAgB++qwIOmJ8KEBRYgCRUYtD0zrQZNM7g1hmEJ0Bkdyf+x07g4F1HDjgI5hfe4sljcR6Dx5ZSPxT6PtoE8vet/L+nAwQTHEgw9FNBslmTK3gAR2rg4For8QRoE6zSBT1yS+Inb/HLBQa2oe9e5uV+NnUBEKwQSDCUVPlpIGFW3bP5lwfOqU/I3w02BTNZgxIoV5N/ilcJYKAHmY6Y4bgadQMQLBRICBZ+AOE503D95kTm3DORwNy7V+o6C9zdH5lQQKMD644S8qyL7z2ZPEBoEiNdAcR7Q0AhaEjnzGz+8h33BOfmLKjApLwiOGvazWKcrL0pw+lQChybMhIu4jPiI6GrvUuXAMEMgYTFHI64M0iwD3O3qObTK3xKSYWPt2TzfwQC0BJl1Sb/xItUGLuATuQZ7NYtQNBaIGG2oOS6YzZh9iZQMfWF3MyNzS/XC50gd7ekWsgAHLUz2ELc4SG+agoONOoaICgICSjMdMy2OIlLVydmQmzas4PHqXv3Uq9Tyr1kjT1GAihlVU/gQFUW5c3H/xIAwTsCic8mdwAKNmDWGyk4KW14pPp2L+MCWQNwAJIgG8nvLXOgb5TuNCxNlwGIN1xA4QkGZRdPMZrPKF6PjD3BGgpUAjSD/UtXfEQ5FcpWzw4CB5mrNDif/DMOzvq/YJL/l9sMW8t0FVCYhalJCYKrAIUsuBusClDKGijXSfgEYESXJU52rXVPrj2Ali+f8UU0vpVJls3lGdX/chlkaZVAQi0PUCCComegAA4AvTTheawAZdCp/Z/XEg7wAeVINDCQIdmAMlc2rGoTepJhAQsvHDmvKvPSAPGeEVAIPkBCABIkvQEF/dDNq7y1Z+C3rsdcw2afMULl2xsvgaMEMNd8W5yTVcgoULWscguA+NEQUOaMoj1rFADTA1AOwaEgpfZPmQ3JFDJ3Ym+2VXIBB2+3vQuvuMdvTC5kFcDCeTE7bgWQpVemafKLeWZuamtzAC35JR6zIEf+bncFKQOKfrttVjfIFpRRMnHieHXbdEpgmTp03hhfAhKIH9FgAshS+bYA8V5RFDGD87OTZBWClaBqARaCeHdBjn4OHDG1PzrDT+ZMZAtTGYWsNUk2cgmo9a07nGMXk84zq8jeJLDcHiDL0Z6mCbD8qr0HC04k2EoCBn6sB9gvxb8ca8AYRIL05bo7ARCUiPCRuhM6B/m5flE7ySZzID+q/cUbYSd+BizmrPJRAFkO9DTNYCGzMDMvAZMKGkAGL4jjpbiXYwWoHzSuAwZoDQhKxCAfOltJslnvsMC1du2kfZYajC1AoQSLWth/LEDWbl4AZgmaNXAIZGZyiOCFYPWr+jPbc53zIyLd017dJvpCVQCxoQjffafU/GSi9GXsGIcNF/24NADywxdvR9P3/z1IWQZoIAKZDAER4JCaTQDnrf/eBXVoBYY3FSQbewZN0+yDNwetLgyArBwyTocHlh4YAFl6YxwPD6w8MACycsg4/WAPbJg+ALLhlHFpeMB7YADEe2Lshwc2PDAAsuGUcWl4wHtgAMR7YuyHBzY8MACy4ZRxaXjAe6AUQDy/sR8euJUHBkBuNZzDmNIeGAAp7dHB71YeGAC51XAOY0p7YACktEcHv1t54AIAuZW/hzEX88AAyMUGbKjb1gMDIG39PaRdzAMDIBcbsL/FsHoAAABLSURBVKFuWw8MgLT195B2MQ98NkAuNlhD3fYeGABp7/Mh8UIeGAC50GANVdt7YACkvc+HxAt5YADkQoM1VG3vgQGQSj4fbO/hgf8CAAD//8UYdAMAAAAGSURBVAMAHhy7NtsT8zwAAAAASUVORK5CYII=";
|
|
11
|
+
|
|
9
12
|
// assets/imgs/fly.png
|
|
10
13
|
var fly_default = "data:image/png;base64,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";
|
|
11
14
|
|
|
12
15
|
// assets/imgs/jump.png
|
|
13
16
|
var jump_default = "data:image/png;base64,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";
|
|
14
17
|
|
|
18
|
+
// assets/imgs/vehicle.png
|
|
19
|
+
var vehicle_default = "data:image/png;base64,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";
|
|
20
|
+
|
|
15
21
|
// assets/imgs/view.png
|
|
16
22
|
var view_default = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAQAElEQVR4AeydC3qkthKFm7uxZFY2npVNsrK+5+9IHoyhKYEEetR8VKBpocep+lUCY+d/D//nCrgCmwo4IJvS+BeuwOPhgHgUuAJvFHBA3ohz5qvn8/l3sA/tsd/aL43zc/v7TJt+bX4FHJAMmirwgYFABwB9fD5V7e9gP7XHCP6lcX5un9erEo4/tP/Q9b7dpEBBQG4a0UXNKnCBgiCOMBDoAJCrB9RFnT/VFhttOSy51DXW44AYhaKYonQJBUHMV1cYbTksVyg9a8MBmYmxdRjB0PcsmwhUHd660YcIi2eVgq5wQN6IWyEYa711UNZUyXTOAVkRshEwlj13UJaKZPjcJiAZBr5VheBgGYWxjNkqVvN5ByWjdxyQIKbA4JEqT6RaBSOM5HMHKH5/8inHsQMHRLoBh3Y8UtUu6/aPasN+aR/th46x+DnuKaevsm5AwuPhXqDPKo6lsqEBERivx7YSKgccBDhG8P+Y/vvHHvvQx2j/6BiLn+OecvpqmtSfnNAAB5B4NpGwqduwgACHxMpxr/GCYpomAhwj+Dmn6o9t0zR9gUa1AMypOlUH2cQhkRAp25CACA4CBTi+aWU8QbD+UCCzseez8dL0YmoEYF6ZSVcDi3aHNockUbbhAAlwHF1SAQJAYBwnyn2uuEAhOwHLpJqOguKQSDzrNhQgJ+AABqDAOLbqW6ycYDkDCpCcyaDFxlVbxcMAcgKOXwrGasBYBpD6xnLxSDbhAQXXLqv0zzMFhgBEcPAk58iyCjCqDyIgkR1ZdpFJqh/fLF4vPxwCEKmaupxgrU/M5VxOqRtlN3WYYE/NJg7JG7d0D4iyRyocryXVG82q/uoEJGTZqsd2R+e6BkRwMKOmOB44uOYOX2RrM0DCY+GUOo8sQVPqb7Jst4AEOFKc3gUcMQoFCcvDFEi4aU/NtrG5bvfdAiKPDQuHxv7aDkKSknFf7fT8ny4BCdnD6rcOMsf2UA9AkjKxbDfcyTfdASI4mAGtTu4ajhijARLr0y2WWs3fh8Wxn913B4gEscLxUOAMEwhhrNyXSKLdjUe/TDS7BXsv0BUgyh4EvNWx1hm1mxgQJNy0myHpZuAnBtIVIAk6DLG02tDDOjGw1LJONhtNtX+6G0BC9jAtrzSTkmna996BEWjsZBDMcvXPh6VUx2W6ASTBR9YZNKHK5opaNRg+i/QEiGcPI6chi1ghMelqbLq5Yl0AEpZXFvGtQWGpq+kygmTYZWaK47oARAM2zXIeFFLq62a5Fxl6mdU8IJ49vkZ84idrRjVNQIltP1oo3zwgVpE9e3xXSpqQQbDvX349M+zj3h4A+eurL1c/WWfK1Ys7P2nSRpl6SEh6AGRIx+WCNmSRXNV1V0/TgGhWMz2JURCYynXnXfuALMusIe9DmgbE6H+L841VdVvMssxqKVNnc1TrgFjuP/7NptbgFSljDwdJ64AM57ASjGoJ6ll2Q9jWAdkY1p/Tcr7ff/yR492RQ7KiTrOAjJjuV/x39anhbtSbBcQYGT4rGoVSMb9XkwjL7TsgyxL1fvb7j7y+8clkRc+WAVkZzrdTPit+k8RPpCjQOyApWnhZV+CbAg7IN0n8xBsFhlvWOiBvosG/cgUuBcTlbl6B4W7kewfE8ipK81HrAyinQO+AlFOuv5qHu7+wuLBlQIZL9xaHepm8CrQMiEUJnxUtKtnLDPdzpWYBmaZpnkHsLvaSWwr4/dqKMs0CsjKW1VP+UuOqLGsnLdl2uEmpdUAsDrM4fi1ghjlnnURGzNqtA2IJYl867Kvkk8iGRq0D4r9LveHYAqctWhdo9t4qmwbEmvKtS4h1VwxxdrhfhLJ6tWlAwiAt9yEeAEGs5U6Th/VXki06L6tv/nMPgFic4Gtsi0pvyliz9ZsqmvyqB0BMa2PNlA7JeohasqtJ4/Xq2z7bPCBhZrOkf0sgtO3NxN5r0rAurxJr7qd484AkuKK+/89FQucLFTVNGpqEhgWpF0CsSwBTQBQKxqqqTcgeVm2rGl+uznQBiGY4lljYni5kkWFnw4U4pslC2g6tVxeABMdbZzpTYIQ6u9x59rC7tRtANNORQbDd0ScEyG5drRUIYzdNEtJ06OyBb7sBhMHIzFlEgdL1Y19psbWZ4NDFVi1VtN+tK0A045FBMIvHfo8GicZrzgjS0lzWInarZboCJDghZeazzqah6nZ3AQ7reFM0bFcUQ8+7A0QzHxnE6uAhnmolwvGQhp49AjzdAcK4Eh38MwQQl3ZnGhv3WtbMwfitkwtlu7cuAQle+xH2ll2XkAQ4flsECGV+GSaXUHSMXbeAyNEpSy283RUkB+DwpRVRsLBuAWGcgoS1NKDw0WJdQHIEDomTknFVfIyta0CCC1PX1E1DIjiYFFKWVcjE0iplIuGaIax7QJRFcHzq7AgkirUnwdZMIKjDgJFyQ87YgKOpcdLpq6x7QBAyQJKaSbgUUKoPHoHB4+qnOswTK+3MW2VwmPt9WcEhAEFNQUKgH4VEMfjkeqqqxtQpwCBrYKn9cjgMig0DCFqcgITLX9lEQXk7KOrDHIzUrMFY/glacOz2RoGhAEGHEBhHMgmXs74HFN7juhyUDGAwBjJH6j0Z1w1pwwGClwMkZ4KEWRtQFLPPD/2Hz1Sd3ag7GMso7ExbwPGRvZMdVzgkIPhTkMSnW+w5ddTIKmQUxfETWLAzQfxQRa8llPYAEe1UnRrc2HBIgCPbsIAgFpDIyCRHl1xUMzdgwSIw7AFmaQCAxfOUi/ZUhUABEJg+ntqYAH5onB+nahn04qEBiT4PwZMLklgtewIcYJYGAFg8T7loXJfLyBrAASS56hyqHgckuBtIZJM+lgBF1V66AQRgeNY4KbsDshBQkBBULUPiWWPh0zMfHZAV9YBE1lo28ayx4suzpyyAnG2j2esFyYesdlDIGHSTJRWQNKt3jR13QAxeUfTNQalh+QUIAKGuTSwJDaPwIkcUcEASVFM0Ago26TJAwXR4yQYUtAcYGJ8vaXjkRhyQg95fwBJ/lpIzaKkLAwY1N7EHTs4d7LVflqqAA5Kq2Er5aZpeL/9pTxBrN00qFqFh1o9GcC8tfkf5l03//aMujPKqzrc7FLgZkDuGfE2bivEIDbN+NAJ+afE7yr/smh56KxYFHBCLSl5mWAUckGFd7wO3KOCAWFQylHk+n7x8iPECYnzxcLlXsS/b/Huumxt18X6WoXUvUkoBB+SAsgpxgpdgjgEe38CNLyAS2Gu2bG1eJr64GPfURf1q7rXRHsY1y3r8cyEF+gUko2AKT4AgWLEIA4FMsGIZW9usivawVx/UJ/YA87F5hX9xWgEHZEVCBR9AYARhBAIQsJUrbjlFXwAm/majuv10WDK7wgGZCaoIe0GhU6/ljfYEoXbNbBEWwHZYMrhteEAiFNo/pSdgtAaFuv1tYwwRFl+GfZPHfmJYQATEPFsQUHbV2io5X4Z5Vkn03XCA5AAjUeOain9mlZo6VXNfhgFkcDCWMeigLBXZ+Nw9IBeDwYuF0XgJ8fXyobT/sp/0b3GOsnOLdahY0c1B2ZG3W0AuACMG8Sv4FfNs8xcReQnx9fKhvviyxyeLc5SdW6xn+VYwbXJ5bnNQNhTtEhDBwc1o7idSBCdG8Cq+J/bYK/g39D19evrzKj0A0d4SmtNtzCoAFJ569fzQYjbc/cOuABEY8ckUT272R79f4gWEihGY0TinU0U2U6ULaACG5VmufqEdP0dxSOSNbgARHDmzBsH2CQQBKa2q3dS/eXYBlhx9BZQc9TRdR/OACIxcWSNCoXibgIPPzTl3miZgmdRxQMF0eGhD1+GzSNOAAIdcf/ZeAxB+KLAwjlVl+5vGAyhYhKXaQeFHGcs6jHsgVgNV9LdZQCQoIgLHUSGBASgwjo/WU/11AZYqQZEf8SFGtsJY2r0eFtQgbJOABFER8oiGwAAUGMdH6mjwmscDUB6PB8suTIfvN5Uvqo/8yCT390YvgGTru41L8p9uDhCJGmebI2rwVwiHA2MulIKeZReBuQcJP9+ZX1rieG+Sw9cl2jXX2QwgAoObRgQ7MqswEwIGgWEWp+eCAZS47EKfOFyO0Yp9PHfbXn7H57e13wQgEgkoEIp9qlg4G6vC4amdL10+gII+OnxtHNekFRPjEb9nka56QGZwpA4YJ9fm7NQx9F4eH1nGyORoKZe9TNWAnIBj+HuN7JHyrsLj3+3dB33WrFi4BZJqAZEgpNUjopA1/F7jM7TqPdCCjgxiheSWpVa1gMitqXAgNnCw1+W+taCAIGEys/osNSZOS1AlIMoeqULwRq3DcTocbqvAmkUeB2Lj1KCqAyQIwPLKOrAXHNbCXq4+BZRFyCBWSC5dalUFiOAg3abA8boZr8/l3qNUBQQJvgeUL5dufNj7AePGZemnqwEkwJEycOBA1PRR+xW1KpCSRS7xfRWACA6yhsNRa9he1C9lETKIFZJL3tWqAhDpn3JTzj3HJbOH+uXbxQoIEnwLKJaWUyZVS33fytwOiLIHgnzr2MYJ4LjiJbqN5v30RQpYswg37Cnxk9z9WwEJcJhnAc0uDkeyi9u7QH4mg2CWzh9dalnqftwKiHpohkNlHQ6JMMomSFL8nRJHSRLeBkjIHtbO8sTKOqNY6/Ry9StghaTYUusWQAIcVuqBo+g6s/44GbOHyiJMiphFgCJLrVsA0WitcDwkksMhwUbd5H9rFkEic1xR2GKXAxKyh6VvlEkRh/JufSpgjYPsS61jgJxzgpVyllbW9HquR3511QooixAHmKWfWZdalwKSkj0kii+tLOEwSBnFgzWLoIh1EqbsW7sUEPXE2nHrD4pUpW8DKWCNC15dyiLLZYAkZA+WVp49sri3r0qURYgL01JL8ZYFkssAkatM2SOIoOK+uQKrClyaRS4BRDRD/upoFyd/LT4391Fj5UkKf2PW7fnMroECwjTRqlyW7RJA1FPToFrPHk8FhMbKm8mkd7fHo5QGD8M/01Jsr57igChohsgeYZwExJ7m/v0FCmiybQMQaTFE9rCOU+V8K69AFjjoZtEMEmZV2tkz643XXj3+vSuAAv/ynxxWFBBrB5UOrcswa5Vr5fzcGApk/TFBaUAsy6teske2tD5GHBcZJb9xmnWyLQZIwvKqiFI3VNoL6DdIl6VJMkfK6yimRosBotb/ku1uvSyvNA4yCA5ivztuL5BNAfTmr2pmzRyxdyUBsTzy7GrWBRIZzuJ/TAMsbo9HMQ2kNRt6A0mM6az7IoBYl1caXRHqsypkqux7IY2N9bDbNBXT4Lvq+c8UAcTYzWLUG9v3Yq7ArgKlALE8vcr2rHp3lF7AFTioQHZAtLyy3HvQXc8gqOBWtQLZAdFoTYCwRldZ31yBqhUoAYhlwF09vbIM+HAZv/BWBUoAYrn/uHXQ3rgrYFWgBCCWtoe5/+CebGYfOnZ7PotoYAm81DJZAZHz/f4jeAAtZPzy1NzIrm6PRxEN3xxFmgAAAvRJREFUpDfbR3BBll1WQNQjCyDdZw95CScBhkUPyeZbRgV+Bv2zVJkbEEunuv75R3AOM6RFi1vLdNw4kGSZnHID8lfHou8OzeHYlai5ArkBsVDb8xLLM0c9CFhicbe3uQHZbbDXAiF79Dq8FseVZSLOBogCxERsxz9B9+xRD0b88lRdgNSjjfekAgXu7AKv1/MUMUsfsmUQY2+yUG1sq8ZijN/t8SihAa8v8ctT/ILWI9e/qwHJ1e9W6/lXS8yXE30/5dbhY5omwMsaGw5IVjl3K8v2fH63JS+QRYGcgJhu0rP0us5KrLOX38zX6b/VXuUEZLWBgU6yBrYMl7/+nu0m0tJgX2WuHc3VgHT7mklY/5qziPWx+LXh4K0tFcgJiDU4ln3o6bM1izBmX2qhQuWWE5DdoWqW7XppofExSVgh8aXWbsTcXyAbIIbgsAbO/aqc6IF0YBIAFEst/lTLotKNZbIBwhhCcKyBwI/+CRyKjWBrGmyN25daW8pcfX6lvayAUD+QyF6bPvPDII5HguOhAZNBrJD4UkuBUuuWHZD5QEOgzE8Nc6yxMykAimXMvtSyqHRDmaKA3DCe2pq0ZhH67UstVKjMHJCCDlEWIYNYIWGpNfrbCAW9caxqB+SYbuarBEnKUos/9GCu2wuWVyAXIOV72nYL1izy0E/YHZKKfO2AXOAMZRFfal2gc4kmHJASqq7UKUh8qbWiS+2nHJBrPeRLrWv1Pt2aA3JaQnsFyiK+1LLLVUXJBgCpQqdsnRAkvtTKpmb5ihyQ8hqvtZCy1AKotTr83AUKOCAXiLxsQlkkZanlr6EsBbzwswNyodjzpgQJmQFQ5qf9uDIFHJB7HWJdavkrKDf5aWxAbhI9NqssQgbB4infV6aAA3KzQwTJ7l8CVBmWYzf3dMzmHZA6/P4Oknff1dH7jnvhgFTgXGUI/uDypK5wT8KSC4u/jcmxvvLtDgUckDtU32hToPD3ZQEDczA2dLrytANSSG2vtg8F/g8AAP//r/s6dQAAAAZJREFUAwCqeBInE6huXwAAAABJRU5ErkJggg==";
|
|
17
23
|
|
|
@@ -291,6 +297,7 @@ var PlayerController = class {
|
|
|
291
297
|
this.loader = new GLTFLoader();
|
|
292
298
|
this.controllerMode = 0;
|
|
293
299
|
// 0: 人物 1: 车辆
|
|
300
|
+
this.enableOverShoulderView = false;
|
|
294
301
|
this.isChangeControllerTransitionTimer = null;
|
|
295
302
|
// ==================== 玩家基本属性 ====================
|
|
296
303
|
this.playerRadius = 45;
|
|
@@ -324,7 +331,7 @@ var PlayerController = class {
|
|
|
324
331
|
// 全局车辆共享参数
|
|
325
332
|
this.vehicleParams = {
|
|
326
333
|
debug: {
|
|
327
|
-
showPhysicsBox:
|
|
334
|
+
showPhysicsBox: true
|
|
328
335
|
},
|
|
329
336
|
chassis: {
|
|
330
337
|
linearDamping: 0.5,
|
|
@@ -345,7 +352,8 @@ var PlayerController = class {
|
|
|
345
352
|
maxSteerAngle: Math.PI / 4,
|
|
346
353
|
steerSpeed: 0.5,
|
|
347
354
|
steerReturnSpeed: 1
|
|
348
|
-
}
|
|
355
|
+
},
|
|
356
|
+
followVehicleDirection: true
|
|
349
357
|
};
|
|
350
358
|
this.camBehindDir = new THREE3.Vector3(0, 0, 1);
|
|
351
359
|
// ==================== 上车相关 ====================
|
|
@@ -355,10 +363,16 @@ var PlayerController = class {
|
|
|
355
363
|
this.boardingTargetDir = null;
|
|
356
364
|
this.boardingMoveSpeed = 300;
|
|
357
365
|
this.boardingRotateSpeed = 10;
|
|
358
|
-
this.flip180Quat = new THREE3.Quaternion().setFromAxisAngle(
|
|
359
|
-
|
|
366
|
+
this.flip180Quat = new THREE3.Quaternion().setFromAxisAngle(
|
|
367
|
+
new THREE3.Vector3(0, 1, 0),
|
|
368
|
+
Math.PI
|
|
369
|
+
);
|
|
360
370
|
this.closeVehicleDoorTimer = null;
|
|
361
371
|
this.boardingPointWorld = null;
|
|
372
|
+
this.isBoardingAnimPlaying = false;
|
|
373
|
+
this.closeDoorTriggered = false;
|
|
374
|
+
this.isExitAnimPlaying = false;
|
|
375
|
+
this.closeExitDoorTriggered = false;
|
|
362
376
|
// ==================== 状态开关 ====================
|
|
363
377
|
this.playerIsOnGround = false;
|
|
364
378
|
this.isupdate = true;
|
|
@@ -380,15 +394,19 @@ var PlayerController = class {
|
|
|
380
394
|
this.jumpBtnEl = null;
|
|
381
395
|
this.flyBtnEl = null;
|
|
382
396
|
this.viewBtnEl = null;
|
|
397
|
+
this.vehicleBtnEl = null;
|
|
383
398
|
this.lookPointerId = null;
|
|
384
399
|
this.isLookDown = false;
|
|
385
400
|
this.lastTouchX = 0;
|
|
386
401
|
this.lastTouchY = 0;
|
|
402
|
+
this.nearCheckLocal = new THREE3.Vector3();
|
|
403
|
+
this.nearCheckWorld = new THREE3.Vector3();
|
|
404
|
+
this.isNearVehicle = false;
|
|
387
405
|
// ==================== 第三人称相机参数 ====================
|
|
388
406
|
this._camCollisionLerp = 0.18;
|
|
389
407
|
this._camEpsilon = 0.35;
|
|
390
|
-
this.
|
|
391
|
-
this.
|
|
408
|
+
this.minCamDistance = 1;
|
|
409
|
+
this.maxCamDistance = 4.4;
|
|
392
410
|
this.orginMaxCamDistance = 4.4;
|
|
393
411
|
// ==================== 物理/运动 ====================
|
|
394
412
|
this.playerVelocity = new THREE3.Vector3();
|
|
@@ -414,8 +432,16 @@ var PlayerController = class {
|
|
|
414
432
|
// ==================== 射线检测 ====================
|
|
415
433
|
this._personToCam = new THREE3.Vector3();
|
|
416
434
|
this._originTmp = new THREE3.Vector3();
|
|
417
|
-
this._raycaster = new THREE3.Raycaster(
|
|
418
|
-
|
|
435
|
+
this._raycaster = new THREE3.Raycaster(
|
|
436
|
+
new THREE3.Vector3(),
|
|
437
|
+
new THREE3.Vector3(0, -1, 0)
|
|
438
|
+
);
|
|
439
|
+
this._raycasterPersonToCam = new THREE3.Raycaster(
|
|
440
|
+
new THREE3.Vector3(),
|
|
441
|
+
new THREE3.Vector3()
|
|
442
|
+
);
|
|
443
|
+
this.centerRay = new THREE3.Raycaster();
|
|
444
|
+
this.centerMouse = new THREE3.Vector2();
|
|
419
445
|
// ==================== 物理与碰撞检测 ====================
|
|
420
446
|
this.ensureAttributesMinimal = (geom) => {
|
|
421
447
|
if (!geom.attributes.position) return null;
|
|
@@ -428,16 +454,20 @@ var PlayerController = class {
|
|
|
428
454
|
return geom;
|
|
429
455
|
};
|
|
430
456
|
this.setAnimationByPressed = () => {
|
|
431
|
-
this.
|
|
457
|
+
this.maxCamDistance = this.orginMaxCamDistance;
|
|
432
458
|
if (this.isMovingToBoardingPoint) {
|
|
433
459
|
this.isMovingToBoardingPoint = false;
|
|
434
460
|
this.boardingWaypoints = [];
|
|
435
461
|
this.currentWaypointIndex = 0;
|
|
436
462
|
this.boardingTargetDir = null;
|
|
437
463
|
}
|
|
438
|
-
if (this.
|
|
439
|
-
|
|
440
|
-
this.
|
|
464
|
+
if (this.isExitAnimPlaying) {
|
|
465
|
+
this.isExitAnimPlaying = false;
|
|
466
|
+
this.closeExitDoorTriggered = false;
|
|
467
|
+
}
|
|
468
|
+
if (this.isBoardingAnimPlaying) {
|
|
469
|
+
this.isBoardingAnimPlaying = false;
|
|
470
|
+
this.closeDoorTriggered = false;
|
|
441
471
|
}
|
|
442
472
|
if (this.closeVehicleDoorTimer) {
|
|
443
473
|
clearTimeout(this.closeVehicleDoorTimer);
|
|
@@ -449,7 +479,7 @@ var PlayerController = class {
|
|
|
449
479
|
return;
|
|
450
480
|
}
|
|
451
481
|
this.playPersonAnimationByName("flying");
|
|
452
|
-
this.
|
|
482
|
+
this.maxCamDistance = this.orginMaxCamDistance * 2;
|
|
453
483
|
return;
|
|
454
484
|
}
|
|
455
485
|
if (this.playerIsOnGround) {
|
|
@@ -458,11 +488,15 @@ var PlayerController = class {
|
|
|
458
488
|
return;
|
|
459
489
|
}
|
|
460
490
|
if (this.fwdPressed) {
|
|
461
|
-
this.playPersonAnimationByName(
|
|
491
|
+
this.playPersonAnimationByName(
|
|
492
|
+
this.shiftPressed ? "running" : "walking"
|
|
493
|
+
);
|
|
462
494
|
return;
|
|
463
495
|
}
|
|
464
496
|
if (!this.isFirstPerson && (this.lftPressed || this.rgtPressed || this.bkdPressed)) {
|
|
465
|
-
this.playPersonAnimationByName(
|
|
497
|
+
this.playPersonAnimationByName(
|
|
498
|
+
this.shiftPressed ? "running" : "walking"
|
|
499
|
+
);
|
|
466
500
|
return;
|
|
467
501
|
}
|
|
468
502
|
if (this.lftPressed) {
|
|
@@ -519,7 +553,14 @@ var PlayerController = class {
|
|
|
519
553
|
this.controls.mouseButtons = { LEFT: 2, MIDDLE: 1, RIGHT: 0 };
|
|
520
554
|
break;
|
|
521
555
|
case "Space":
|
|
556
|
+
if (this.isMovingToBoardingPoint) {
|
|
557
|
+
this.isMovingToBoardingPoint = false;
|
|
558
|
+
this.boardingWaypoints = [];
|
|
559
|
+
this.currentWaypointIndex = 0;
|
|
560
|
+
this.boardingTargetDir = null;
|
|
561
|
+
}
|
|
522
562
|
this.spacePressed = true;
|
|
563
|
+
if (this.controllerMode == 1) return;
|
|
523
564
|
if (!this.playerIsOnGround || this.isFlying) return;
|
|
524
565
|
const next = this.personActions?.get("jumping");
|
|
525
566
|
if (next && this.actionState === next) return;
|
|
@@ -534,11 +575,12 @@ var PlayerController = class {
|
|
|
534
575
|
this.changeView();
|
|
535
576
|
break;
|
|
536
577
|
case "KeyF":
|
|
537
|
-
if (this.controllerMode ==
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
578
|
+
if (this.controllerMode == 0 && this.playerFlyEnabled) {
|
|
579
|
+
this.isFlying = !this.isFlying;
|
|
580
|
+
this.setAnimationByPressed();
|
|
581
|
+
if (!this.isFlying && !this.playerIsOnGround) {
|
|
582
|
+
this.playPersonAnimationByName("jumping");
|
|
583
|
+
}
|
|
542
584
|
}
|
|
543
585
|
break;
|
|
544
586
|
case "KeyE":
|
|
@@ -633,15 +675,17 @@ var PlayerController = class {
|
|
|
633
675
|
this.mouseSensity = opts.mouseSensity ?? 5;
|
|
634
676
|
const s = this.playerModel.scale;
|
|
635
677
|
this.gravity = (opts.playerModel.gravity ?? -2400) * s;
|
|
636
|
-
this.jumpHeight = (opts.playerModel.jumpHeight ??
|
|
637
|
-
this.
|
|
638
|
-
this.
|
|
678
|
+
this.jumpHeight = (opts.playerModel.jumpHeight ?? 600) * s;
|
|
679
|
+
this.playerSpeed = (opts.playerModel.speed ?? 300) * s;
|
|
680
|
+
this.playerFlySpeed = (opts.playerModel.playerFlySpeed ?? 2100) * s;
|
|
681
|
+
this.curPlayerSpeed = this.playerSpeed;
|
|
639
682
|
this.playerModel.rotateY = opts.playerModel.rotateY ?? 0;
|
|
683
|
+
this.playerFlyEnabled = opts.playerModel.flyEnabled ?? true;
|
|
640
684
|
this._camCollisionLerp = 0.18;
|
|
641
685
|
this._camEpsilon = 35 * s;
|
|
642
|
-
this.
|
|
643
|
-
this.
|
|
644
|
-
this.orginMaxCamDistance = this.
|
|
686
|
+
this.minCamDistance = (opts.minCamDistance ?? 100) * s;
|
|
687
|
+
this.maxCamDistance = (opts.maxCamDistance ?? 440) * s;
|
|
688
|
+
this.orginMaxCamDistance = this.maxCamDistance;
|
|
645
689
|
this.thirdMouseMode = opts.thirdMouseMode ?? 1;
|
|
646
690
|
this.enableZoom = opts.enableZoom ?? false;
|
|
647
691
|
const isMobileDevice = () => navigator.maxTouchPoints && navigator.maxTouchPoints > 0 || "ontouchstart" in window || /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
|
|
@@ -655,6 +699,24 @@ var PlayerController = class {
|
|
|
655
699
|
this.setCameraPos();
|
|
656
700
|
this.setControls();
|
|
657
701
|
if (callback) callback();
|
|
702
|
+
this.enableOverShoulderView = opts.enableOverShoulderView ?? false;
|
|
703
|
+
this.setOverShoulderView(this.enableOverShoulderView);
|
|
704
|
+
}
|
|
705
|
+
setOverShoulderView(enable) {
|
|
706
|
+
if (!enable || this.controllerMode == 1) {
|
|
707
|
+
this.camera.clearViewOffset();
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
const w = window.innerWidth;
|
|
711
|
+
const h = window.innerHeight;
|
|
712
|
+
this.camera.setViewOffset(
|
|
713
|
+
w,
|
|
714
|
+
h,
|
|
715
|
+
-w * -0.15,
|
|
716
|
+
0,
|
|
717
|
+
w,
|
|
718
|
+
h
|
|
719
|
+
);
|
|
658
720
|
}
|
|
659
721
|
async initLoader() {
|
|
660
722
|
const dracoLoader = new DRACOLoader();
|
|
@@ -664,7 +726,7 @@ var PlayerController = class {
|
|
|
664
726
|
}
|
|
665
727
|
async initRapier() {
|
|
666
728
|
if (this.RAPIER) return;
|
|
667
|
-
this.RAPIER = await import("
|
|
729
|
+
this.RAPIER = await import("@dimforge/rapier3d-compat");
|
|
668
730
|
await this.RAPIER.init();
|
|
669
731
|
const gravity = new this.RAPIER.Vector3(0, -9.81, 0);
|
|
670
732
|
this.world = new this.RAPIER.World(gravity);
|
|
@@ -701,7 +763,9 @@ var PlayerController = class {
|
|
|
701
763
|
// ==================== 玩家模型相关方法 ====================
|
|
702
764
|
async loadPersonGLB() {
|
|
703
765
|
try {
|
|
704
|
-
const gltf = await this.loader.loadAsync(
|
|
766
|
+
const gltf = await this.loader.loadAsync(
|
|
767
|
+
this.playerModel.url
|
|
768
|
+
);
|
|
705
769
|
this.person = gltf.scene;
|
|
706
770
|
const { size } = this.getBbox(this.person);
|
|
707
771
|
const ratio = this.playerHeight / size.y;
|
|
@@ -721,11 +785,17 @@ var PlayerController = class {
|
|
|
721
785
|
});
|
|
722
786
|
const r = this.playerRadius * scale;
|
|
723
787
|
const h = this.playerHeight * scale;
|
|
724
|
-
this.player = new THREE3.Mesh(
|
|
788
|
+
this.player = new THREE3.Mesh(
|
|
789
|
+
new RoundedBoxGeometry(r * 2, h, r * 2, 1, 75),
|
|
790
|
+
material
|
|
791
|
+
);
|
|
725
792
|
this.player.geometry.translate(0, -h * 0.25, 0);
|
|
726
793
|
this.player.capsuleInfo = {
|
|
727
794
|
radius: r,
|
|
728
|
-
segment: new THREE3.Line3(
|
|
795
|
+
segment: new THREE3.Line3(
|
|
796
|
+
new THREE3.Vector3(),
|
|
797
|
+
new THREE3.Vector3(0, -h * 0.5, 0)
|
|
798
|
+
)
|
|
729
799
|
};
|
|
730
800
|
this.player.name = "capsule";
|
|
731
801
|
this.scene.add(this.player);
|
|
@@ -742,6 +812,7 @@ var PlayerController = class {
|
|
|
742
812
|
this.reset();
|
|
743
813
|
this.personMixer = new THREE3.AnimationMixer(this.person);
|
|
744
814
|
const animations = gltf.animations ?? [];
|
|
815
|
+
console.log("animations", animations);
|
|
745
816
|
this.personActions = /* @__PURE__ */ new Map();
|
|
746
817
|
const animationMappings = [
|
|
747
818
|
[this.playerModel.idleAnim, "idle"],
|
|
@@ -790,7 +861,9 @@ var PlayerController = class {
|
|
|
790
861
|
const finishedAction = ev.action;
|
|
791
862
|
if (finishedAction === this.jumpAction) {
|
|
792
863
|
if (this.fwdPressed) {
|
|
793
|
-
this.playPersonAnimationByName(
|
|
864
|
+
this.playPersonAnimationByName(
|
|
865
|
+
this.shiftPressed ? "running" : "walking"
|
|
866
|
+
);
|
|
794
867
|
return;
|
|
795
868
|
}
|
|
796
869
|
if (this.bkdPressed) {
|
|
@@ -803,11 +876,56 @@ var PlayerController = class {
|
|
|
803
876
|
}
|
|
804
877
|
this.playPersonAnimationByName("idle");
|
|
805
878
|
}
|
|
879
|
+
if (finishedAction === this.personActions?.get("enterCar")) {
|
|
880
|
+
this.onEnterCarAnimFinished();
|
|
881
|
+
}
|
|
882
|
+
if (finishedAction === this.personActions?.get("exitCar")) {
|
|
883
|
+
}
|
|
806
884
|
});
|
|
807
885
|
} catch (error) {
|
|
808
886
|
console.error("\u52A0\u8F7D\u73A9\u5BB6\u6A21\u578B\u5931\u8D25:", error);
|
|
809
887
|
}
|
|
810
888
|
}
|
|
889
|
+
async switchPlayerModel(newPlayerModel) {
|
|
890
|
+
const savedPos = this.player.position.clone();
|
|
891
|
+
const savedQuat = this.player.quaternion.clone();
|
|
892
|
+
const wasFirstPerson = this.isFirstPerson;
|
|
893
|
+
if (wasFirstPerson) {
|
|
894
|
+
this.scene.attach(this.camera);
|
|
895
|
+
}
|
|
896
|
+
if (this.player) {
|
|
897
|
+
this.scene.remove(this.player);
|
|
898
|
+
}
|
|
899
|
+
if (this.person) {
|
|
900
|
+
this.player.remove(this.person);
|
|
901
|
+
this.person = null;
|
|
902
|
+
this.personHead = null;
|
|
903
|
+
}
|
|
904
|
+
if (this.personMixer) {
|
|
905
|
+
this.personMixer.stopAllAction();
|
|
906
|
+
this.personMixer.uncacheRoot(this.personMixer.getRoot());
|
|
907
|
+
this.personMixer = void 0;
|
|
908
|
+
this.personActions = void 0;
|
|
909
|
+
}
|
|
910
|
+
const ratio = newPlayerModel.scale / this.playerModel.scale;
|
|
911
|
+
this.playerModel = { ...this.playerModel, ...newPlayerModel };
|
|
912
|
+
this.gravity *= ratio;
|
|
913
|
+
this.jumpHeight *= ratio;
|
|
914
|
+
this.playerSpeed *= ratio;
|
|
915
|
+
this.playerFlySpeed *= ratio;
|
|
916
|
+
this.curPlayerSpeed *= ratio;
|
|
917
|
+
this._camEpsilon *= ratio;
|
|
918
|
+
this.minCamDistance *= ratio;
|
|
919
|
+
this.maxCamDistance *= ratio;
|
|
920
|
+
this.orginMaxCamDistance *= ratio;
|
|
921
|
+
await this.loadPersonGLB();
|
|
922
|
+
this.player.position.copy(savedPos);
|
|
923
|
+
this.player.quaternion.copy(savedQuat);
|
|
924
|
+
if (wasFirstPerson) {
|
|
925
|
+
this.setFirstPersonCamera();
|
|
926
|
+
}
|
|
927
|
+
this.setDebug(this.displayCollider);
|
|
928
|
+
}
|
|
811
929
|
playPersonAnimationByName(name, fade = 0.18) {
|
|
812
930
|
if (!this.personActions || this.ctPressed) return;
|
|
813
931
|
const next = this.personActions.get(name);
|
|
@@ -845,9 +963,12 @@ var PlayerController = class {
|
|
|
845
963
|
const scale = opts.scale ?? 1;
|
|
846
964
|
const chassisRatio = opts.chassisRatio ?? 0.2;
|
|
847
965
|
const suspensionRestLengthRatio = opts.suspensionRestLengthRatio ?? 0.2;
|
|
966
|
+
const speedMultiplier = opts.speedMultiplier ?? 1;
|
|
967
|
+
const followVehicleDirection = opts.followVehicleDirection ?? true;
|
|
848
968
|
this.vehicleParams.power.accelerateForce = 50 * scale;
|
|
849
969
|
this.vehicleParams.power.brakeForce = 200 * scale;
|
|
850
970
|
this.vehicleParams.power.maxSpeed = 1e4 * scale;
|
|
971
|
+
this.vehicleParams.followVehicleDirection = followVehicleDirection;
|
|
851
972
|
const vehicleModel = await this.loader.loadAsync(opts.url);
|
|
852
973
|
const { size: originalSize } = this.getBbox(vehicleModel.scene);
|
|
853
974
|
const ratio = this.vehicleLength / Math.max(originalSize.x, originalSize.y, originalSize.z);
|
|
@@ -946,13 +1067,25 @@ var PlayerController = class {
|
|
|
946
1067
|
vehicleModel.scene.position.y -= chassisHeight / 2;
|
|
947
1068
|
halfExtents.x *= 0.95;
|
|
948
1069
|
halfExtents.z *= 0.95;
|
|
949
|
-
const chassisDesc = this.RAPIER.RigidBodyDesc.dynamic().setTranslation(
|
|
1070
|
+
const chassisDesc = this.RAPIER.RigidBodyDesc.dynamic().setTranslation(
|
|
1071
|
+
opts.position.x,
|
|
1072
|
+
opts.position.y,
|
|
1073
|
+
opts.position.z
|
|
1074
|
+
).setLinearDamping(this.vehicleParams.chassis.linearDamping).setAngularDamping(this.vehicleParams.chassis.angularDamping).setCanSleep(true).setAdditionalMass(10);
|
|
950
1075
|
const chassisBody = this.world.createRigidBody(chassisDesc);
|
|
951
|
-
const chassisCollider = this.RAPIER.ColliderDesc.cuboid(
|
|
1076
|
+
const chassisCollider = this.RAPIER.ColliderDesc.cuboid(
|
|
1077
|
+
halfExtents.x,
|
|
1078
|
+
halfExtents.y,
|
|
1079
|
+
halfExtents.z
|
|
1080
|
+
);
|
|
952
1081
|
this.world.createCollider(chassisCollider, chassisBody);
|
|
953
1082
|
if (this.vehicleParams.debug.showPhysicsBox) {
|
|
954
1083
|
const debugBox = new THREE3.Mesh(
|
|
955
|
-
new THREE3.BoxGeometry(
|
|
1084
|
+
new THREE3.BoxGeometry(
|
|
1085
|
+
halfExtents.x * 2,
|
|
1086
|
+
halfExtents.y * 2,
|
|
1087
|
+
halfExtents.z * 2
|
|
1088
|
+
),
|
|
956
1089
|
new THREE3.MeshBasicMaterial({
|
|
957
1090
|
color: 16711680,
|
|
958
1091
|
wireframe: true,
|
|
@@ -964,7 +1097,12 @@ var PlayerController = class {
|
|
|
964
1097
|
}
|
|
965
1098
|
vehicleGroup.position.copy(opts.position);
|
|
966
1099
|
vehicleGroup.updateMatrixWorld(true);
|
|
967
|
-
const { vehicle, updateWheelVisuals } = createVehicleController(
|
|
1100
|
+
const { vehicle, updateWheelVisuals } = createVehicleController(
|
|
1101
|
+
this.world,
|
|
1102
|
+
chassisBody,
|
|
1103
|
+
wheelWrappers,
|
|
1104
|
+
wheelsInfo
|
|
1105
|
+
);
|
|
968
1106
|
const vehicleInstance = {
|
|
969
1107
|
vehicleGroup,
|
|
970
1108
|
chassisBody,
|
|
@@ -974,11 +1112,14 @@ var PlayerController = class {
|
|
|
974
1112
|
vehicleActions,
|
|
975
1113
|
vehiclIsOpenDoor: false,
|
|
976
1114
|
vehicleBBox: bbox.clone(),
|
|
977
|
-
pathPlanner: new PathPlanner(
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1115
|
+
pathPlanner: new PathPlanner(
|
|
1116
|
+
this._createObstacleCheckerFor(vehicleGroup, bbox, scale),
|
|
1117
|
+
{
|
|
1118
|
+
debugEnabled: false,
|
|
1119
|
+
scene: this.scene,
|
|
1120
|
+
scale: this.playerModel.scale
|
|
1121
|
+
}
|
|
1122
|
+
),
|
|
982
1123
|
scale,
|
|
983
1124
|
boardingPoint: opts.boardingPoint,
|
|
984
1125
|
seatOffset: opts.seatOffset ?? new THREE3.Vector3(0, 0, 0),
|
|
@@ -989,10 +1130,10 @@ var PlayerController = class {
|
|
|
989
1130
|
l: Math.max(size.x, size.z),
|
|
990
1131
|
w: Math.min(size.x, size.z),
|
|
991
1132
|
h: size.y
|
|
992
|
-
}
|
|
1133
|
+
},
|
|
1134
|
+
speedMultiplier
|
|
993
1135
|
};
|
|
994
1136
|
this.vehicles.push(vehicleInstance);
|
|
995
|
-
console.log(`\u8F66\u8F86\u52A0\u8F7D\u5B8C\u6210\uFF0C\u5F53\u524D\u5171 ${this.vehicles.length} \u8F86\u8F66`, vehicleInstance);
|
|
996
1137
|
this.setControllerTransition();
|
|
997
1138
|
} catch (error) {
|
|
998
1139
|
console.error("\u52A0\u8F7D\u8F66\u8F86\u6A21\u578B\u5931\u8D25:", error);
|
|
@@ -1024,7 +1165,11 @@ var PlayerController = class {
|
|
|
1024
1165
|
for (let x = -1; x <= 1; x += 2) {
|
|
1025
1166
|
for (let y = -1; y <= 1; y += 2) {
|
|
1026
1167
|
for (let z = -1; z <= 1; z += 2) {
|
|
1027
|
-
const localCorner = new THREE3.Vector3(
|
|
1168
|
+
const localCorner = new THREE3.Vector3(
|
|
1169
|
+
halfSize.x * x,
|
|
1170
|
+
halfSize.y * y,
|
|
1171
|
+
halfSize.z * z
|
|
1172
|
+
);
|
|
1028
1173
|
const worldCorner = localCorner.applyQuaternion(vehicleQuat).add(center);
|
|
1029
1174
|
corners.push(worldCorner);
|
|
1030
1175
|
}
|
|
@@ -1045,8 +1190,14 @@ var PlayerController = class {
|
|
|
1045
1190
|
const nodes = [];
|
|
1046
1191
|
const vehiclePos = vehicleGroup.position;
|
|
1047
1192
|
const vehicleQuat = vehicleGroup.quaternion;
|
|
1048
|
-
const vehicleForward = new THREE3.Vector3(
|
|
1049
|
-
|
|
1193
|
+
const vehicleForward = new THREE3.Vector3(
|
|
1194
|
+
0,
|
|
1195
|
+
0,
|
|
1196
|
+
1
|
|
1197
|
+
).applyQuaternion(vehicleQuat);
|
|
1198
|
+
const vehicleRight = new THREE3.Vector3(1, 0, 0).applyQuaternion(
|
|
1199
|
+
vehicleQuat
|
|
1200
|
+
);
|
|
1050
1201
|
const bboxSize = new THREE3.Vector3();
|
|
1051
1202
|
bbox.getSize(bboxSize);
|
|
1052
1203
|
const halfLength = bboxSize.z / 2 * scale;
|
|
@@ -1056,16 +1207,32 @@ var PlayerController = class {
|
|
|
1056
1207
|
const groundY = start.y;
|
|
1057
1208
|
for (const margin of [bypassMargin, extendedMargin]) {
|
|
1058
1209
|
nodes.push(
|
|
1059
|
-
vehiclePos.clone().add(
|
|
1210
|
+
vehiclePos.clone().add(
|
|
1211
|
+
vehicleForward.clone().multiplyScalar(halfLength + margin)
|
|
1212
|
+
).add(
|
|
1213
|
+
vehicleRight.clone().multiplyScalar(-halfWidth - margin)
|
|
1214
|
+
).setY(groundY)
|
|
1060
1215
|
);
|
|
1061
1216
|
nodes.push(
|
|
1062
|
-
vehiclePos.clone().add(
|
|
1217
|
+
vehiclePos.clone().add(
|
|
1218
|
+
vehicleForward.clone().multiplyScalar(halfLength + margin)
|
|
1219
|
+
).add(
|
|
1220
|
+
vehicleRight.clone().multiplyScalar(halfWidth + margin)
|
|
1221
|
+
).setY(groundY)
|
|
1063
1222
|
);
|
|
1064
1223
|
nodes.push(
|
|
1065
|
-
vehiclePos.clone().add(
|
|
1224
|
+
vehiclePos.clone().add(
|
|
1225
|
+
vehicleForward.clone().multiplyScalar(-halfLength - margin)
|
|
1226
|
+
).add(
|
|
1227
|
+
vehicleRight.clone().multiplyScalar(-halfWidth - margin)
|
|
1228
|
+
).setY(groundY)
|
|
1066
1229
|
);
|
|
1067
1230
|
nodes.push(
|
|
1068
|
-
vehiclePos.clone().add(
|
|
1231
|
+
vehiclePos.clone().add(
|
|
1232
|
+
vehicleForward.clone().multiplyScalar(-halfLength - margin)
|
|
1233
|
+
).add(
|
|
1234
|
+
vehicleRight.clone().multiplyScalar(halfWidth + margin)
|
|
1235
|
+
).setY(groundY)
|
|
1069
1236
|
);
|
|
1070
1237
|
}
|
|
1071
1238
|
return nodes;
|
|
@@ -1100,14 +1267,16 @@ var PlayerController = class {
|
|
|
1100
1267
|
* 上车:自动寻找最近的车辆
|
|
1101
1268
|
*/
|
|
1102
1269
|
enterVehicle() {
|
|
1103
|
-
if (this.vehicles.length === 0) return;
|
|
1270
|
+
if (this.vehicles.length === 0 || this.isMovingToBoardingPoint) return;
|
|
1104
1271
|
let nearestVehicle = null;
|
|
1105
1272
|
let nearestDist = Infinity;
|
|
1106
1273
|
let nearBoardingPointWorld = null;
|
|
1107
1274
|
for (const v2 of this.vehicles) {
|
|
1108
1275
|
const boardingPointLocal = v2.boardingPoint.clone().multiplyScalar(v2.scale);
|
|
1109
1276
|
const boardingPointWorld = new THREE3.Vector3();
|
|
1110
|
-
v2.vehicleGroup.localToWorld(
|
|
1277
|
+
v2.vehicleGroup.localToWorld(
|
|
1278
|
+
boardingPointWorld.copy(boardingPointLocal)
|
|
1279
|
+
);
|
|
1111
1280
|
const dist = this.player.position.distanceTo(boardingPointWorld);
|
|
1112
1281
|
if (dist < 800 * this.playerModel.scale && dist < nearestDist) {
|
|
1113
1282
|
nearestDist = dist;
|
|
@@ -1118,9 +1287,15 @@ var PlayerController = class {
|
|
|
1118
1287
|
if (!nearestVehicle || !nearBoardingPointWorld) return;
|
|
1119
1288
|
this.activeVehicle = nearestVehicle;
|
|
1120
1289
|
const v = nearestVehicle;
|
|
1290
|
+
const vel = v.chassisBody.linvel();
|
|
1291
|
+
const horizSpeed = Math.sqrt(vel.x * vel.x + vel.z * vel.z);
|
|
1292
|
+
if (horizSpeed > 0.1) return;
|
|
1121
1293
|
this.boardingPointWorld = nearBoardingPointWorld;
|
|
1122
1294
|
const vehicleForward = new THREE3.Vector3(0, 0, 1).applyQuaternion(v.vehicleGroup.quaternion).normalize();
|
|
1123
|
-
const path = v.pathPlanner.findPath(
|
|
1295
|
+
const path = v.pathPlanner.findPath(
|
|
1296
|
+
this.player.position.clone(),
|
|
1297
|
+
this.boardingPointWorld
|
|
1298
|
+
);
|
|
1124
1299
|
this.boardingWaypoints = path;
|
|
1125
1300
|
this.currentWaypointIndex = 0;
|
|
1126
1301
|
this.boardingTargetDir = vehicleForward;
|
|
@@ -1140,15 +1315,29 @@ var PlayerController = class {
|
|
|
1140
1315
|
}
|
|
1141
1316
|
const currentWaypoint = this.boardingWaypoints[this.currentWaypointIndex];
|
|
1142
1317
|
const currentPos = this.player.position.clone();
|
|
1143
|
-
const horizontalDistance = new THREE3.Vector2(
|
|
1318
|
+
const horizontalDistance = new THREE3.Vector2(
|
|
1319
|
+
currentWaypoint.x - currentPos.x,
|
|
1320
|
+
currentWaypoint.z - currentPos.z
|
|
1321
|
+
).length();
|
|
1144
1322
|
const isLastWaypoint = this.currentWaypointIndex === this.boardingWaypoints.length - 1;
|
|
1145
1323
|
const waypointThreshold = isLastWaypoint ? 0 : 10 * this.playerModel.scale;
|
|
1146
1324
|
if (horizontalDistance > waypointThreshold) {
|
|
1147
|
-
const moveDir = new THREE3.Vector3(
|
|
1148
|
-
|
|
1325
|
+
const moveDir = new THREE3.Vector3(
|
|
1326
|
+
currentWaypoint.x - currentPos.x,
|
|
1327
|
+
0,
|
|
1328
|
+
currentWaypoint.z - currentPos.z
|
|
1329
|
+
).normalize();
|
|
1330
|
+
const moveDistance = Math.min(
|
|
1331
|
+
this.boardingMoveSpeed * this.playerModel.scale * delta,
|
|
1332
|
+
horizontalDistance
|
|
1333
|
+
);
|
|
1149
1334
|
this.player.position.add(moveDir.multiplyScalar(moveDistance));
|
|
1150
1335
|
const lookTarget = this.player.position.clone().add(moveDir);
|
|
1151
|
-
this.targetMat.lookAt(
|
|
1336
|
+
this.targetMat.lookAt(
|
|
1337
|
+
this.player.position,
|
|
1338
|
+
lookTarget,
|
|
1339
|
+
this.player.up
|
|
1340
|
+
);
|
|
1152
1341
|
this.targetQuat.setFromRotationMatrix(this.targetMat);
|
|
1153
1342
|
this.targetQuat.multiply(this.flip180Quat);
|
|
1154
1343
|
const rotateAlpha = Math.min(1, this.boardingRotateSpeed * delta);
|
|
@@ -1162,13 +1351,17 @@ var PlayerController = class {
|
|
|
1162
1351
|
*/
|
|
1163
1352
|
finalizeBoarding(delta) {
|
|
1164
1353
|
const v = this.activeVehicle;
|
|
1165
|
-
if (!this.boardingTargetDir || !v) return;
|
|
1354
|
+
if (!this.boardingTargetDir || !v || !this.isMovingToBoardingPoint) return;
|
|
1166
1355
|
const currentDir = new THREE3.Vector3(0, 0, -1).applyQuaternion(this.player.quaternion).normalize();
|
|
1167
1356
|
const targetDir = this.boardingTargetDir.clone().normalize();
|
|
1168
1357
|
const angleDiff = currentDir.angleTo(targetDir);
|
|
1169
1358
|
if (angleDiff > 0.01) {
|
|
1170
1359
|
const lookTarget = this.player.position.clone().add(targetDir);
|
|
1171
|
-
this.targetMat.lookAt(
|
|
1360
|
+
this.targetMat.lookAt(
|
|
1361
|
+
this.player.position,
|
|
1362
|
+
lookTarget,
|
|
1363
|
+
this.player.up
|
|
1364
|
+
);
|
|
1172
1365
|
this.targetQuat.setFromRotationMatrix(this.targetMat);
|
|
1173
1366
|
const rotateAlpha = Math.min(1, this.boardingRotateSpeed * delta);
|
|
1174
1367
|
this.player.quaternion.slerp(this.targetQuat, rotateAlpha);
|
|
@@ -1178,32 +1371,27 @@ var PlayerController = class {
|
|
|
1178
1371
|
this.boardingTargetDir = null;
|
|
1179
1372
|
v.pathPlanner?.clearVisualization();
|
|
1180
1373
|
this.playPersonAnimationByName("enterCar");
|
|
1374
|
+
this.isBoardingAnimPlaying = true;
|
|
1375
|
+
this.closeDoorTriggered = false;
|
|
1181
1376
|
if (!v.vehiclIsOpenDoor) this.openVehicleDoor();
|
|
1182
1377
|
this.player.rotation.copy(v.vehicleGroup.rotation);
|
|
1183
1378
|
this.player.quaternion.multiply(this.flip180Quat);
|
|
1184
|
-
this.closeVehicleDoorTimer = setTimeout(
|
|
1185
|
-
() => {
|
|
1186
|
-
this.openVehicleDoor(false);
|
|
1187
|
-
},
|
|
1188
|
-
v.enterVehicleTime * 1e3 - 500
|
|
1189
|
-
);
|
|
1190
|
-
this.enterVehicleTimer = setTimeout(() => {
|
|
1191
|
-
if (this.boardingPointWorld) {
|
|
1192
|
-
const offsetY = this.boardingPointWorld.y - this.player.position.y;
|
|
1193
|
-
this.controllerMode = 1;
|
|
1194
|
-
v.vehicleGroup.attach(this.player);
|
|
1195
|
-
this.player.position.add(
|
|
1196
|
-
v.seatOffset.clone().multiplyScalar(v.scale).add(new THREE3.Vector3(0, offsetY, 0))
|
|
1197
|
-
);
|
|
1198
|
-
this.isMovingToBoardingPoint = false;
|
|
1199
|
-
if (this.isChangeControllerTransitionTimer) {
|
|
1200
|
-
clearTimeout(this.isChangeControllerTransitionTimer);
|
|
1201
|
-
this.isChangeControllerTransitionTimer = null;
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
}, v.enterVehicleTime * 1e3);
|
|
1205
1379
|
}
|
|
1206
1380
|
}
|
|
1381
|
+
onEnterCarAnimFinished() {
|
|
1382
|
+
const v = this.activeVehicle;
|
|
1383
|
+
if (!v || !this.isMovingToBoardingPoint) return;
|
|
1384
|
+
this.player.updateMatrixWorld(true);
|
|
1385
|
+
const offsetY = this.boardingPointWorld.y - this.player.position.y;
|
|
1386
|
+
this.controllerMode = 1;
|
|
1387
|
+
this.syncControllerModeBtnEl();
|
|
1388
|
+
this.setOverShoulderView(false);
|
|
1389
|
+
v.vehicleGroup.attach(this.player);
|
|
1390
|
+
this.player.position.add(
|
|
1391
|
+
v.seatOffset.clone().multiplyScalar(v.scale).add(new THREE3.Vector3(0, offsetY, 0))
|
|
1392
|
+
);
|
|
1393
|
+
this.isMovingToBoardingPoint = false;
|
|
1394
|
+
}
|
|
1207
1395
|
/**
|
|
1208
1396
|
* 下车
|
|
1209
1397
|
*/
|
|
@@ -1215,20 +1403,19 @@ var PlayerController = class {
|
|
|
1215
1403
|
this.currentWaypointIndex = 0;
|
|
1216
1404
|
this.boardingTargetDir = null;
|
|
1217
1405
|
const vel = v.chassisBody.linvel();
|
|
1218
|
-
const
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
} else {
|
|
1406
|
+
const horizSpeed = Math.sqrt(vel.x * vel.x + vel.z * vel.z);
|
|
1407
|
+
const isStationary = horizSpeed < 0.1;
|
|
1408
|
+
if (isStationary) {
|
|
1222
1409
|
this.playPersonAnimationByName("exitCar");
|
|
1410
|
+
this.isExitAnimPlaying = true;
|
|
1411
|
+
this.closeExitDoorTriggered = false;
|
|
1412
|
+
} else {
|
|
1413
|
+
this.playPersonAnimationByName("idle");
|
|
1223
1414
|
}
|
|
1224
1415
|
this.openVehicleDoor(true);
|
|
1225
|
-
this.closeVehicleDoorTimer = setTimeout(
|
|
1226
|
-
() => {
|
|
1227
|
-
this.openVehicleDoor(false);
|
|
1228
|
-
},
|
|
1229
|
-
v.enterVehicleTime * 1e3 - 500
|
|
1230
|
-
);
|
|
1231
1416
|
this.controllerMode = 0;
|
|
1417
|
+
this.syncControllerModeBtnEl();
|
|
1418
|
+
this.setOverShoulderView(this.enableOverShoulderView);
|
|
1232
1419
|
this.scene.attach(this.player);
|
|
1233
1420
|
if (this.isFirstPerson) {
|
|
1234
1421
|
this.setFirstPersonCamera();
|
|
@@ -1240,25 +1427,39 @@ var PlayerController = class {
|
|
|
1240
1427
|
this.isFirstPerson = !this.isFirstPerson;
|
|
1241
1428
|
if (this.isFirstPerson) {
|
|
1242
1429
|
this.setFirstPersonCamera();
|
|
1430
|
+
this.setOverShoulderView(false);
|
|
1243
1431
|
} else {
|
|
1432
|
+
this.controls.enabled = true;
|
|
1244
1433
|
this.scene.attach(this.camera);
|
|
1245
1434
|
const worldPos = this.player.position.clone();
|
|
1246
|
-
const dir = new THREE3.Vector3(0, 0, -1).applyQuaternion(
|
|
1435
|
+
const dir = new THREE3.Vector3(0, 0, -1).applyQuaternion(
|
|
1436
|
+
this.player.quaternion
|
|
1437
|
+
);
|
|
1247
1438
|
const angle = Math.atan2(dir.z, dir.x);
|
|
1248
|
-
const offset = new THREE3.Vector3(
|
|
1439
|
+
const offset = new THREE3.Vector3(
|
|
1440
|
+
Math.cos(angle) * 400 * this.playerModel.scale,
|
|
1441
|
+
200 * this.playerModel.scale,
|
|
1442
|
+
Math.sin(angle) * 400 * this.playerModel.scale
|
|
1443
|
+
);
|
|
1249
1444
|
this.camera.position.copy(worldPos).add(offset);
|
|
1250
1445
|
this.controls.target.copy(worldPos);
|
|
1251
1446
|
this.controls.enableZoom = this.enableZoom;
|
|
1447
|
+
this.setOverShoulderView(this.enableOverShoulderView);
|
|
1252
1448
|
}
|
|
1253
1449
|
this.setPointerLock();
|
|
1254
1450
|
}
|
|
1255
1451
|
setFirstPersonCamera() {
|
|
1452
|
+
this.controls.enabled = false;
|
|
1256
1453
|
if (this.personHead) {
|
|
1257
1454
|
this.personHead?.attach(this.camera);
|
|
1258
1455
|
this.camera.position.set(0, 10, 20);
|
|
1259
1456
|
} else {
|
|
1260
1457
|
this.player.attach(this.camera);
|
|
1261
|
-
this.camera.position.set(
|
|
1458
|
+
this.camera.position.set(
|
|
1459
|
+
0,
|
|
1460
|
+
40 * this.playerModel.scale,
|
|
1461
|
+
30 * this.playerModel.scale
|
|
1462
|
+
);
|
|
1262
1463
|
}
|
|
1263
1464
|
this.camera.rotation.set(0, Math.PI, 0);
|
|
1264
1465
|
this.controls.enableZoom = false;
|
|
@@ -1271,20 +1472,30 @@ var PlayerController = class {
|
|
|
1271
1472
|
}
|
|
1272
1473
|
}
|
|
1273
1474
|
setCameraPos() {
|
|
1274
|
-
|
|
1475
|
+
requestAnimationFrame(() => {
|
|
1275
1476
|
if (this.isFirstPerson) {
|
|
1276
1477
|
this.person.add(this.camera);
|
|
1277
|
-
this.camera.position.set(
|
|
1478
|
+
this.camera.position.set(
|
|
1479
|
+
0,
|
|
1480
|
+
40 * this.playerModel.scale,
|
|
1481
|
+
30 * this.playerModel.scale
|
|
1482
|
+
);
|
|
1278
1483
|
} else {
|
|
1279
1484
|
const worldPos = this.player.position.clone();
|
|
1280
|
-
const dir = new THREE3.Vector3(0, 0, -1).applyQuaternion(
|
|
1485
|
+
const dir = new THREE3.Vector3(0, 0, -1).applyQuaternion(
|
|
1486
|
+
this.player.quaternion
|
|
1487
|
+
);
|
|
1281
1488
|
const angle = Math.atan2(dir.z, dir.x);
|
|
1282
|
-
const offset = new THREE3.Vector3(
|
|
1489
|
+
const offset = new THREE3.Vector3(
|
|
1490
|
+
Math.cos(angle) * 400 * this.playerModel.scale,
|
|
1491
|
+
200 * this.playerModel.scale,
|
|
1492
|
+
Math.sin(angle) * 400 * this.playerModel.scale
|
|
1493
|
+
);
|
|
1283
1494
|
this.camera.position.copy(worldPos).add(offset);
|
|
1284
1495
|
this.controls.enableZoom = this.enableZoom;
|
|
1285
1496
|
}
|
|
1286
1497
|
this.camera.updateProjectionMatrix();
|
|
1287
|
-
}
|
|
1498
|
+
});
|
|
1288
1499
|
}
|
|
1289
1500
|
setControls() {
|
|
1290
1501
|
this.controls.enableZoom = this.enableZoom;
|
|
@@ -1308,7 +1519,11 @@ var PlayerController = class {
|
|
|
1308
1519
|
const yaw = -dx * speed * this.mouseSensity;
|
|
1309
1520
|
const pitch = -dy * speed * this.mouseSensity;
|
|
1310
1521
|
this.player.rotateY(yaw);
|
|
1311
|
-
this.camera.rotation.x = THREE3.MathUtils.clamp(
|
|
1522
|
+
this.camera.rotation.x = THREE3.MathUtils.clamp(
|
|
1523
|
+
this.camera.rotation.x + pitch,
|
|
1524
|
+
-1.1,
|
|
1525
|
+
1.4
|
|
1526
|
+
);
|
|
1312
1527
|
} else {
|
|
1313
1528
|
const sensitivity = this.mouseSensity;
|
|
1314
1529
|
const deltaX = -dx * speed * sensitivity;
|
|
@@ -1324,7 +1539,11 @@ var PlayerController = class {
|
|
|
1324
1539
|
const newX = distance * Math.sin(phi) * Math.sin(theta);
|
|
1325
1540
|
const newY = distance * Math.cos(phi);
|
|
1326
1541
|
const newZ = distance * Math.sin(phi) * Math.cos(theta);
|
|
1327
|
-
this.camera.position.set(
|
|
1542
|
+
this.camera.position.set(
|
|
1543
|
+
target.x + newX,
|
|
1544
|
+
target.y + newY,
|
|
1545
|
+
target.z + newZ
|
|
1546
|
+
);
|
|
1328
1547
|
this.camera.lookAt(target);
|
|
1329
1548
|
}
|
|
1330
1549
|
} else {
|
|
@@ -1333,8 +1552,16 @@ var PlayerController = class {
|
|
|
1333
1552
|
if (this.isFirstPerson) {
|
|
1334
1553
|
const yaw = -dx * speed * this.mouseSensity;
|
|
1335
1554
|
const pitch = -dy * speed * this.mouseSensity;
|
|
1336
|
-
this.camera.rotation.y = THREE3.MathUtils.clamp(
|
|
1337
|
-
|
|
1555
|
+
this.camera.rotation.y = THREE3.MathUtils.clamp(
|
|
1556
|
+
this.camera.rotation.y + yaw,
|
|
1557
|
+
Math.PI * (3 / 4),
|
|
1558
|
+
Math.PI * (5 / 4)
|
|
1559
|
+
);
|
|
1560
|
+
this.camera.rotation.x = THREE3.MathUtils.clamp(
|
|
1561
|
+
this.camera.rotation.x + pitch,
|
|
1562
|
+
0,
|
|
1563
|
+
Math.PI * (1 / 3)
|
|
1564
|
+
);
|
|
1338
1565
|
} else {
|
|
1339
1566
|
const sensitivity = this.mouseSensity;
|
|
1340
1567
|
const deltaX = -dx * speed * sensitivity;
|
|
@@ -1350,7 +1577,11 @@ var PlayerController = class {
|
|
|
1350
1577
|
const newX = distance * Math.sin(phi) * Math.sin(theta);
|
|
1351
1578
|
const newY = distance * Math.cos(phi);
|
|
1352
1579
|
const newZ = distance * Math.sin(phi) * Math.cos(theta);
|
|
1353
|
-
this.camera.position.set(
|
|
1580
|
+
this.camera.position.set(
|
|
1581
|
+
target.x + newX,
|
|
1582
|
+
target.y + newY,
|
|
1583
|
+
target.z + newZ
|
|
1584
|
+
);
|
|
1354
1585
|
this.camera.lookAt(target);
|
|
1355
1586
|
}
|
|
1356
1587
|
}
|
|
@@ -1374,7 +1605,12 @@ var PlayerController = class {
|
|
|
1374
1605
|
const itemSize = attr.itemSize;
|
|
1375
1606
|
const normalized = attr.normalized;
|
|
1376
1607
|
if (!attrMap.has(name)) {
|
|
1377
|
-
attrMap.set(name, {
|
|
1608
|
+
attrMap.set(name, {
|
|
1609
|
+
itemSize,
|
|
1610
|
+
arrayCtor: ctor,
|
|
1611
|
+
examples: 1,
|
|
1612
|
+
normalized
|
|
1613
|
+
});
|
|
1378
1614
|
} else {
|
|
1379
1615
|
const m = attrMap.get(name);
|
|
1380
1616
|
if (m.itemSize !== itemSize || m.arrayCtor !== ctor || m.normalized !== normalized) {
|
|
@@ -1401,7 +1637,14 @@ var PlayerController = class {
|
|
|
1401
1637
|
const meta = attrMap.get(name);
|
|
1402
1638
|
const len = count * meta.itemSize;
|
|
1403
1639
|
const array = new meta.arrayCtor(len);
|
|
1404
|
-
g.setAttribute(
|
|
1640
|
+
g.setAttribute(
|
|
1641
|
+
name,
|
|
1642
|
+
new THREE3.BufferAttribute(
|
|
1643
|
+
array,
|
|
1644
|
+
meta.itemSize,
|
|
1645
|
+
meta.normalized
|
|
1646
|
+
)
|
|
1647
|
+
);
|
|
1405
1648
|
}
|
|
1406
1649
|
}
|
|
1407
1650
|
}
|
|
@@ -1432,15 +1675,37 @@ var PlayerController = class {
|
|
|
1432
1675
|
this.collected = this.unifiedAttribute(this.collected);
|
|
1433
1676
|
} else {
|
|
1434
1677
|
const gltf = await this.loader.loadAsync(meshUrl);
|
|
1435
|
-
const
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1678
|
+
const obj = gltf.scene.children[0];
|
|
1679
|
+
if (obj && obj?.geometry) {
|
|
1680
|
+
const mesh = obj;
|
|
1681
|
+
let geom = mesh.geometry.clone();
|
|
1682
|
+
geom.applyMatrix4(mesh.matrixWorld);
|
|
1683
|
+
if (geom.index) geom = geom.toNonIndexed();
|
|
1684
|
+
const safe = this.ensureAttributesMinimal(geom);
|
|
1685
|
+
if (safe) this.collected.push(safe);
|
|
1686
|
+
} else {
|
|
1687
|
+
obj.traverse((c) => {
|
|
1688
|
+
const mesh = c;
|
|
1689
|
+
if (mesh?.isMesh && mesh.geometry && c.name !== "capsule") {
|
|
1690
|
+
try {
|
|
1691
|
+
let geom = mesh.geometry.clone();
|
|
1692
|
+
geom.applyMatrix4(mesh.matrixWorld);
|
|
1693
|
+
if (geom.index) geom = geom.toNonIndexed();
|
|
1694
|
+
const safe = this.ensureAttributesMinimal(geom);
|
|
1695
|
+
if (safe) this.collected.push(safe);
|
|
1696
|
+
} catch (e) {
|
|
1697
|
+
console.warn("\u5904\u7406\u7F51\u683C\u65F6\u51FA\u9519\uFF1A", mesh, e);
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
});
|
|
1701
|
+
if (!this.collected.length) return;
|
|
1702
|
+
this.collected = this.unifiedAttribute(this.collected);
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
const merged = BufferGeometryUtils.mergeGeometries(
|
|
1706
|
+
this.collected,
|
|
1707
|
+
false
|
|
1708
|
+
);
|
|
1444
1709
|
if (!merged) {
|
|
1445
1710
|
console.error("\u5408\u5E76\u51E0\u4F55\u5931\u8D25");
|
|
1446
1711
|
return;
|
|
@@ -1487,7 +1752,10 @@ var PlayerController = class {
|
|
|
1487
1752
|
});
|
|
1488
1753
|
if (!this.dynamicCollected.length) return;
|
|
1489
1754
|
this.dynamicCollected = this.unifiedAttribute(this.dynamicCollected);
|
|
1490
|
-
const merged = BufferGeometryUtils.mergeGeometries(
|
|
1755
|
+
const merged = BufferGeometryUtils.mergeGeometries(
|
|
1756
|
+
this.dynamicCollected,
|
|
1757
|
+
false
|
|
1758
|
+
);
|
|
1491
1759
|
if (!merged) {
|
|
1492
1760
|
console.error("\u5408\u5E76\u51E0\u4F55\u5931\u8D25");
|
|
1493
1761
|
return;
|
|
@@ -1507,7 +1775,9 @@ var PlayerController = class {
|
|
|
1507
1775
|
getAngleWithYAxis(normal) {
|
|
1508
1776
|
const yAxis = { x: 0, y: 1, z: 0 };
|
|
1509
1777
|
const dotProduct = normal.x * yAxis.x + normal.y * yAxis.y + normal.z * yAxis.z;
|
|
1510
|
-
const normalMagnitude = Math.sqrt(
|
|
1778
|
+
const normalMagnitude = Math.sqrt(
|
|
1779
|
+
normal.x * normal.x + normal.y * normal.y + normal.z * normal.z
|
|
1780
|
+
);
|
|
1511
1781
|
const cosTheta = dotProduct / normalMagnitude;
|
|
1512
1782
|
return Math.acos(cosTheta);
|
|
1513
1783
|
}
|
|
@@ -1517,12 +1787,15 @@ var PlayerController = class {
|
|
|
1517
1787
|
clearTimeout(this.isChangeControllerTransitionTimer);
|
|
1518
1788
|
this.isChangeControllerTransitionTimer = null;
|
|
1519
1789
|
}
|
|
1790
|
+
let vGroups = [];
|
|
1791
|
+
for (const v of this.vehicles) {
|
|
1792
|
+
vGroups.push(v.vehicleGroup);
|
|
1793
|
+
}
|
|
1794
|
+
this.createDynamicBVH(vGroups);
|
|
1520
1795
|
this.isChangeControllerTransitionTimer = setTimeout(() => {
|
|
1521
1796
|
this.isChangeControllerTransitionTimer = null;
|
|
1522
|
-
let vGroups = [];
|
|
1523
1797
|
for (const v of this.vehicles) {
|
|
1524
1798
|
this.clearVehicleVelocity(v);
|
|
1525
|
-
vGroups.push(v.vehicleGroup);
|
|
1526
1799
|
}
|
|
1527
1800
|
this.createDynamicBVH(vGroups);
|
|
1528
1801
|
}, 3e3);
|
|
@@ -1551,12 +1824,13 @@ var PlayerController = class {
|
|
|
1551
1824
|
// ==================== 循环更新 ====================
|
|
1552
1825
|
async update(delta = clock.getDelta()) {
|
|
1553
1826
|
if (!this.isupdate || !this.player || !this.collider) return;
|
|
1554
|
-
delta = Math.min(delta, 1 /
|
|
1827
|
+
delta = Math.min(delta, 1 / 40);
|
|
1555
1828
|
if (this.controllerMode == 1) {
|
|
1556
1829
|
this.updateVehicle(delta);
|
|
1557
1830
|
} else {
|
|
1558
1831
|
this.updatePlayer(delta);
|
|
1559
|
-
if (this.isChangeControllerTransitionTimer)
|
|
1832
|
+
if (this.isChangeControllerTransitionTimer)
|
|
1833
|
+
this.updateVehicleInertia(delta);
|
|
1560
1834
|
}
|
|
1561
1835
|
}
|
|
1562
1836
|
/**
|
|
@@ -1567,14 +1841,19 @@ var PlayerController = class {
|
|
|
1567
1841
|
if (!v || !this.world) return;
|
|
1568
1842
|
const { vehicleController, chassisBody, vehicleGroup } = v;
|
|
1569
1843
|
const rotation = chassisBody.rotation();
|
|
1570
|
-
const quat = new THREE3.Quaternion(
|
|
1844
|
+
const quat = new THREE3.Quaternion(
|
|
1845
|
+
rotation.x,
|
|
1846
|
+
rotation.y,
|
|
1847
|
+
rotation.z,
|
|
1848
|
+
rotation.w
|
|
1849
|
+
);
|
|
1571
1850
|
const forward = new THREE3.Vector3(1, 0, 0).applyQuaternion(quat);
|
|
1572
1851
|
const slopeAngle = Math.asin(forward.y);
|
|
1573
1852
|
let factor = 1;
|
|
1574
|
-
if (slopeAngle < -0.05 && this.fwdPressed)
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
const engineForce = (Number(this.fwdPressed) *
|
|
1853
|
+
if (slopeAngle < -0.05 && this.fwdPressed) factor = -Math.sin(slopeAngle) * 10;
|
|
1854
|
+
const accelerateForce = this.vehicleParams.power.accelerateForce * v.speedMultiplier;
|
|
1855
|
+
const maxSpeed = this.vehicleParams.power.maxSpeed * v.speedMultiplier;
|
|
1856
|
+
const engineForce = (Number(this.fwdPressed) * accelerateForce - Number(this.bkdPressed) * accelerateForce) * factor;
|
|
1578
1857
|
vehicleController.setWheelEngineForce(0, engineForce);
|
|
1579
1858
|
vehicleController.setWheelEngineForce(1, engineForce);
|
|
1580
1859
|
vehicleController.setWheelEngineForce(2, engineForce);
|
|
@@ -1594,7 +1873,11 @@ var PlayerController = class {
|
|
|
1594
1873
|
}
|
|
1595
1874
|
const steerLerpFactor = 1 - Math.pow(1 - steerSpeed, delta);
|
|
1596
1875
|
const targetSteering = this.vehicleParams.steering.maxSteerAngle * steerDirection;
|
|
1597
|
-
const steering = THREE3.MathUtils.lerp(
|
|
1876
|
+
const steering = THREE3.MathUtils.lerp(
|
|
1877
|
+
currentSteering,
|
|
1878
|
+
targetSteering,
|
|
1879
|
+
steerLerpFactor
|
|
1880
|
+
);
|
|
1598
1881
|
vehicleController.setWheelSteering(0, steering);
|
|
1599
1882
|
vehicleController.setWheelSteering(1, steering);
|
|
1600
1883
|
if ((this.rgtPressed || this.lftPressed) && this.shiftPressed) {
|
|
@@ -1612,36 +1895,56 @@ var PlayerController = class {
|
|
|
1612
1895
|
this.camera.position.add(lookTarget);
|
|
1613
1896
|
this.controls.update();
|
|
1614
1897
|
const velocity = chassisBody.linvel();
|
|
1615
|
-
const currentSpeed = Math.sqrt(
|
|
1616
|
-
|
|
1898
|
+
const currentSpeed = Math.sqrt(
|
|
1899
|
+
velocity.x * velocity.x + velocity.y * velocity.y + velocity.z * velocity.z
|
|
1900
|
+
);
|
|
1617
1901
|
const speedRatio = Math.min(currentSpeed / maxSpeed, 1);
|
|
1618
1902
|
const baseCamDistance = v.size.l * 0.8;
|
|
1619
1903
|
const maxCamDistanceLimit = v.size.l * 5;
|
|
1620
|
-
const targetDistance = THREE3.MathUtils.lerp(
|
|
1621
|
-
|
|
1904
|
+
const targetDistance = THREE3.MathUtils.lerp(
|
|
1905
|
+
baseCamDistance,
|
|
1906
|
+
maxCamDistanceLimit,
|
|
1907
|
+
speedRatio
|
|
1908
|
+
);
|
|
1909
|
+
this._personToCam.subVectors(
|
|
1910
|
+
this.camera.position,
|
|
1911
|
+
vehicleGroup.position
|
|
1912
|
+
);
|
|
1622
1913
|
const origin = vehicleGroup.position.clone().add(new THREE3.Vector3(0, 0, 0));
|
|
1623
1914
|
const direction = this._personToCam.clone().normalize();
|
|
1624
1915
|
const desiredDist = targetDistance;
|
|
1625
1916
|
this._raycasterPersonToCam.set(origin, direction);
|
|
1626
1917
|
this._raycasterPersonToCam.far = desiredDist;
|
|
1627
|
-
const intersects = this._raycasterPersonToCam.intersectObject(
|
|
1918
|
+
const intersects = this._raycasterPersonToCam.intersectObject(
|
|
1919
|
+
this.collider,
|
|
1920
|
+
false
|
|
1921
|
+
);
|
|
1628
1922
|
if (intersects.length > 0) {
|
|
1629
1923
|
const hit = intersects[0];
|
|
1630
|
-
const safeDist = Math.max(
|
|
1924
|
+
const safeDist = Math.max(
|
|
1925
|
+
hit.distance - this._camEpsilon,
|
|
1926
|
+
this.minCamDistance
|
|
1927
|
+
);
|
|
1631
1928
|
const targetCamPos = origin.clone().add(direction.clone().multiplyScalar(safeDist));
|
|
1632
1929
|
this.camera.position.lerp(targetCamPos, this._camCollisionLerp);
|
|
1633
1930
|
} else {
|
|
1634
1931
|
this._raycasterPersonToCam.far = maxCamDistanceLimit;
|
|
1635
|
-
const intersectsMaxDis = this._raycasterPersonToCam.intersectObject(
|
|
1932
|
+
const intersectsMaxDis = this._raycasterPersonToCam.intersectObject(
|
|
1933
|
+
this.collider,
|
|
1934
|
+
false
|
|
1935
|
+
);
|
|
1636
1936
|
let safeDist = desiredDist;
|
|
1637
1937
|
if (intersectsMaxDis.length) {
|
|
1638
1938
|
const hitMax = intersectsMaxDis[0];
|
|
1639
|
-
safeDist = Math.min(
|
|
1939
|
+
safeDist = Math.min(
|
|
1940
|
+
desiredDist,
|
|
1941
|
+
hitMax.distance - this._camEpsilon
|
|
1942
|
+
);
|
|
1640
1943
|
}
|
|
1641
1944
|
const targetCamPos = origin.clone().add(direction.clone().multiplyScalar(safeDist));
|
|
1642
1945
|
this.camera.position.lerp(targetCamPos, this._camCollisionLerp);
|
|
1643
1946
|
}
|
|
1644
|
-
if (this.fwdPressed || this.bkdPressed) {
|
|
1947
|
+
if ((this.fwdPressed || this.bkdPressed) && this.vehicleParams.followVehicleDirection) {
|
|
1645
1948
|
const vel = chassisBody.linvel();
|
|
1646
1949
|
const velHorizontal = new THREE3.Vector3(vel.x, vel.y, vel.z);
|
|
1647
1950
|
const velSpeed = velHorizontal.length();
|
|
@@ -1649,8 +1952,13 @@ var PlayerController = class {
|
|
|
1649
1952
|
const targetBehindDir = velHorizontal.clone().normalize().negate();
|
|
1650
1953
|
this.camBehindDir.lerp(targetBehindDir, this._camCollisionLerp).normalize();
|
|
1651
1954
|
const camHeightOffset = v.size.h;
|
|
1652
|
-
const targetCamPos = lookTarget.clone().add(
|
|
1653
|
-
|
|
1955
|
+
const targetCamPos = lookTarget.clone().add(
|
|
1956
|
+
this.camBehindDir.clone().multiplyScalar(desiredDist)
|
|
1957
|
+
).add(new THREE3.Vector3(0, camHeightOffset, 0));
|
|
1958
|
+
this.camera.position.lerp(
|
|
1959
|
+
targetCamPos,
|
|
1960
|
+
this._camCollisionLerp
|
|
1961
|
+
);
|
|
1654
1962
|
this.controls.update();
|
|
1655
1963
|
}
|
|
1656
1964
|
}
|
|
@@ -1661,8 +1969,18 @@ var PlayerController = class {
|
|
|
1661
1969
|
const size = new THREE3.Vector3();
|
|
1662
1970
|
v.vehicleBBox?.getSize(size);
|
|
1663
1971
|
const translation2 = chassisBody.translation();
|
|
1664
|
-
chassisBody.setTranslation(
|
|
1665
|
-
|
|
1972
|
+
chassisBody.setTranslation(
|
|
1973
|
+
new this.RAPIER.Vector3(
|
|
1974
|
+
translation2.x,
|
|
1975
|
+
translation2.y + size.y,
|
|
1976
|
+
translation2.z
|
|
1977
|
+
),
|
|
1978
|
+
true
|
|
1979
|
+
);
|
|
1980
|
+
chassisBody.setRotation(
|
|
1981
|
+
new this.RAPIER.Quaternion(0, 0, 0, 1),
|
|
1982
|
+
true
|
|
1983
|
+
);
|
|
1666
1984
|
chassisBody.setLinvel(new this.RAPIER.Vector3(0, 0, 0), true);
|
|
1667
1985
|
chassisBody.setAngvel(new this.RAPIER.Vector3(0, 0, 0), true);
|
|
1668
1986
|
}
|
|
@@ -1677,20 +1995,60 @@ var PlayerController = class {
|
|
|
1677
1995
|
for (const v of this.vehicles) {
|
|
1678
1996
|
const { vehicleController, chassisBody, vehicleGroup, updateWheelVisuals } = v;
|
|
1679
1997
|
vehicleController.updateVehicle(delta);
|
|
1998
|
+
if (chassisBody.isSleeping()) continue;
|
|
1680
1999
|
const velocity = chassisBody.linvel();
|
|
1681
|
-
const currentSpeed = Math.sqrt(
|
|
1682
|
-
|
|
2000
|
+
const currentSpeed = Math.sqrt(
|
|
2001
|
+
velocity.x * velocity.x + velocity.y * velocity.y + velocity.z * velocity.z
|
|
2002
|
+
);
|
|
2003
|
+
const maxSpeed = this.vehicleParams.power.maxSpeed * v.speedMultiplier;
|
|
1683
2004
|
if (currentSpeed > maxSpeed) {
|
|
1684
2005
|
const s = maxSpeed / currentSpeed;
|
|
1685
|
-
chassisBody.setLinvel(
|
|
2006
|
+
chassisBody.setLinvel(
|
|
2007
|
+
new this.RAPIER.Vector3(
|
|
2008
|
+
velocity.x * s,
|
|
2009
|
+
velocity.y * s,
|
|
2010
|
+
velocity.z * s
|
|
2011
|
+
),
|
|
2012
|
+
true
|
|
2013
|
+
);
|
|
1686
2014
|
}
|
|
1687
2015
|
const translation = chassisBody.translation();
|
|
1688
2016
|
const rotationSync = chassisBody.rotation();
|
|
1689
|
-
vehicleGroup.position.set(
|
|
1690
|
-
|
|
2017
|
+
vehicleGroup.position.set(
|
|
2018
|
+
translation.x,
|
|
2019
|
+
translation.y,
|
|
2020
|
+
translation.z
|
|
2021
|
+
);
|
|
2022
|
+
vehicleGroup.quaternion.set(
|
|
2023
|
+
rotationSync.x,
|
|
2024
|
+
rotationSync.y,
|
|
2025
|
+
rotationSync.z,
|
|
2026
|
+
rotationSync.w
|
|
2027
|
+
);
|
|
1691
2028
|
if (updateWheelVisuals) updateWheelVisuals();
|
|
1692
2029
|
}
|
|
1693
2030
|
}
|
|
2031
|
+
/**
|
|
2032
|
+
* 设置人物缩放
|
|
2033
|
+
*/
|
|
2034
|
+
setPlayerScale(newScale) {
|
|
2035
|
+
if (newScale <= 0) return;
|
|
2036
|
+
const ratio = newScale / this.playerModel.scale;
|
|
2037
|
+
this.playerModel.scale = newScale;
|
|
2038
|
+
this.gravity *= ratio;
|
|
2039
|
+
this.jumpHeight *= ratio;
|
|
2040
|
+
this.playerSpeed *= ratio;
|
|
2041
|
+
this.playerFlySpeed *= ratio;
|
|
2042
|
+
this.curPlayerSpeed *= ratio;
|
|
2043
|
+
this._camEpsilon *= ratio;
|
|
2044
|
+
this.minCamDistance *= ratio;
|
|
2045
|
+
this.maxCamDistance *= ratio;
|
|
2046
|
+
this.orginMaxCamDistance *= ratio;
|
|
2047
|
+
if (this.isFirstPerson) this.scene.attach(this.camera);
|
|
2048
|
+
this.player?.scale.multiplyScalar(ratio);
|
|
2049
|
+
if (this.player?.capsuleInfo) this.player.capsuleInfo.radius *= ratio;
|
|
2050
|
+
if (this.isFirstPerson) this.setFirstPersonCamera();
|
|
2051
|
+
}
|
|
1694
2052
|
/**
|
|
1695
2053
|
* 更新人物
|
|
1696
2054
|
*/
|
|
@@ -1701,7 +2059,40 @@ var PlayerController = class {
|
|
|
1701
2059
|
if (!this.isFlying) {
|
|
1702
2060
|
this.player.position.addScaledVector(this.playerVelocity, delta);
|
|
1703
2061
|
}
|
|
2062
|
+
if (this.isBoardingAnimPlaying) {
|
|
2063
|
+
const action = this.personActions?.get("enterCar");
|
|
2064
|
+
const duration = action.getClip().duration;
|
|
2065
|
+
const timeScale = action.getEffectiveTimeScale();
|
|
2066
|
+
const remaining = (duration - action.time) / timeScale * 1e3;
|
|
2067
|
+
if (!this.closeDoorTriggered && remaining <= 500) {
|
|
2068
|
+
this.closeDoorTriggered = true;
|
|
2069
|
+
this.openVehicleDoor(false);
|
|
2070
|
+
}
|
|
2071
|
+
if (action.time >= duration) {
|
|
2072
|
+
this.isBoardingAnimPlaying = false;
|
|
2073
|
+
this.closeDoorTriggered = false;
|
|
2074
|
+
this.onEnterCarAnimFinished();
|
|
2075
|
+
return;
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
if (this.isExitAnimPlaying) {
|
|
2079
|
+
const action = this.personActions?.get("exitCar");
|
|
2080
|
+
if (action) {
|
|
2081
|
+
const duration = action.getClip().duration;
|
|
2082
|
+
const timeScale = action.getEffectiveTimeScale();
|
|
2083
|
+
const remaining = (duration - action.time) / timeScale * 1e3;
|
|
2084
|
+
if (!this.closeExitDoorTriggered && remaining <= 500) {
|
|
2085
|
+
this.closeExitDoorTriggered = true;
|
|
2086
|
+
this.openVehicleDoor(false);
|
|
2087
|
+
}
|
|
2088
|
+
if (action.time >= duration) {
|
|
2089
|
+
this.isExitAnimPlaying = false;
|
|
2090
|
+
this.closeExitDoorTriggered = false;
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
1704
2094
|
this.updateMixers(delta);
|
|
2095
|
+
if (this.controllerMode === 1) return;
|
|
1705
2096
|
this.camera.getWorldDirection(this.camDir);
|
|
1706
2097
|
let angle = Math.atan2(this.camDir.z, this.camDir.x) + Math.PI / 2;
|
|
1707
2098
|
angle = 2 * Math.PI - angle;
|
|
@@ -1716,16 +2107,26 @@ var PlayerController = class {
|
|
|
1716
2107
|
if (this.spacePressed) this.moveDir.add(this.DIR_UP);
|
|
1717
2108
|
}
|
|
1718
2109
|
if (this.isFlying && this.fwdPressed) {
|
|
1719
|
-
this.
|
|
2110
|
+
this.curPlayerSpeed = this.shiftPressed ? this.playerFlySpeed * 2 : this.playerFlySpeed;
|
|
1720
2111
|
} else {
|
|
1721
|
-
this.
|
|
2112
|
+
this.curPlayerSpeed = this.shiftPressed ? this.playerSpeed * 2 : this.playerSpeed;
|
|
1722
2113
|
}
|
|
1723
2114
|
this.moveDir.normalize().applyAxisAngle(this.upVector, angle);
|
|
1724
|
-
this.player.position.addScaledVector(
|
|
2115
|
+
this.player.position.addScaledVector(
|
|
2116
|
+
this.moveDir,
|
|
2117
|
+
this.curPlayerSpeed * delta
|
|
2118
|
+
);
|
|
1725
2119
|
let playerDistanceFromGround = Infinity;
|
|
1726
|
-
this._originTmp.set(
|
|
2120
|
+
this._originTmp.set(
|
|
2121
|
+
this.player.position.x,
|
|
2122
|
+
this.player.position.y,
|
|
2123
|
+
this.player.position.z
|
|
2124
|
+
);
|
|
1727
2125
|
this._raycaster.ray.origin.copy(this._originTmp);
|
|
1728
|
-
const intersects = this._raycaster.intersectObject(
|
|
2126
|
+
const intersects = this._raycaster.intersectObject(
|
|
2127
|
+
this.collider,
|
|
2128
|
+
false
|
|
2129
|
+
);
|
|
1729
2130
|
if (intersects.length > 0) {
|
|
1730
2131
|
playerDistanceFromGround = this.player.position.y - intersects[0].point.y;
|
|
1731
2132
|
const maxH = this.playerHeight * this.playerModel.scale * 0.9;
|
|
@@ -1734,7 +2135,10 @@ var PlayerController = class {
|
|
|
1734
2135
|
if (!this.isFlying) {
|
|
1735
2136
|
if (playerDistanceFromGround >= maxH) {
|
|
1736
2137
|
this.playerVelocity.y += delta * this.gravity;
|
|
1737
|
-
this.player.position.addScaledVector(
|
|
2138
|
+
this.player.position.addScaledVector(
|
|
2139
|
+
this.playerVelocity,
|
|
2140
|
+
delta
|
|
2141
|
+
);
|
|
1738
2142
|
this.playerIsOnGround = false;
|
|
1739
2143
|
} else if (playerDistanceFromGround >= h && playerDistanceFromGround < maxH) {
|
|
1740
2144
|
if (!this.spacePressed) {
|
|
@@ -1748,7 +2152,11 @@ var PlayerController = class {
|
|
|
1748
2152
|
this.player.position.y = intersects[0].point.y + h;
|
|
1749
2153
|
} else if (playerDistanceFromGround < minH) {
|
|
1750
2154
|
this.playerVelocity.set(0, 0, 0);
|
|
1751
|
-
this.player.position.set(
|
|
2155
|
+
this.player.position.set(
|
|
2156
|
+
this.player.position.x,
|
|
2157
|
+
intersects[0].point.y + h,
|
|
2158
|
+
this.player.position.z
|
|
2159
|
+
);
|
|
1752
2160
|
this.playerIsOnGround = true;
|
|
1753
2161
|
}
|
|
1754
2162
|
}
|
|
@@ -1769,13 +2177,20 @@ var PlayerController = class {
|
|
|
1769
2177
|
intersectsTriangle: (tri) => {
|
|
1770
2178
|
const triPoint = this.tempVector;
|
|
1771
2179
|
const capsulePoint = this.tempVector2;
|
|
1772
|
-
const distance = tri.closestPointToSegment(
|
|
2180
|
+
const distance = tri.closestPointToSegment(
|
|
2181
|
+
this.tempSegment,
|
|
2182
|
+
triPoint,
|
|
2183
|
+
capsulePoint
|
|
2184
|
+
);
|
|
1773
2185
|
if (distance < capsuleInfo.radius) {
|
|
1774
2186
|
const normal = tri.getNormal(new THREE3.Vector3());
|
|
1775
2187
|
if (normal.y > 0.5 && !this.isFlying) return;
|
|
1776
2188
|
const depth = capsuleInfo.radius - distance;
|
|
1777
2189
|
const direction = capsulePoint.sub(triPoint).normalize();
|
|
1778
|
-
this.tempSegment.start.addScaledVector(
|
|
2190
|
+
this.tempSegment.start.addScaledVector(
|
|
2191
|
+
direction,
|
|
2192
|
+
depth
|
|
2193
|
+
);
|
|
1779
2194
|
this.tempSegment.end.addScaledVector(direction, depth);
|
|
1780
2195
|
}
|
|
1781
2196
|
}
|
|
@@ -1785,18 +2200,28 @@ var PlayerController = class {
|
|
|
1785
2200
|
intersectsTriangle: (tri) => {
|
|
1786
2201
|
const triPoint = this.tempVector;
|
|
1787
2202
|
const capsulePoint = this.tempVector2;
|
|
1788
|
-
const distance = tri.closestPointToSegment(
|
|
2203
|
+
const distance = tri.closestPointToSegment(
|
|
2204
|
+
this.tempSegment,
|
|
2205
|
+
triPoint,
|
|
2206
|
+
capsulePoint
|
|
2207
|
+
);
|
|
1789
2208
|
if (distance < capsuleInfo.radius) {
|
|
1790
2209
|
const depth = capsuleInfo.radius - distance;
|
|
1791
2210
|
const direction = capsulePoint.sub(triPoint).normalize();
|
|
1792
|
-
this.tempSegment.start.addScaledVector(
|
|
2211
|
+
this.tempSegment.start.addScaledVector(
|
|
2212
|
+
direction,
|
|
2213
|
+
depth
|
|
2214
|
+
);
|
|
1793
2215
|
this.tempSegment.end.addScaledVector(direction, depth);
|
|
1794
2216
|
}
|
|
1795
2217
|
}
|
|
1796
2218
|
});
|
|
1797
2219
|
}
|
|
1798
2220
|
const newPosition = this.tempVector.copy(this.tempSegment.start).applyMatrix4(this.collider.matrixWorld);
|
|
1799
|
-
const deltaVector = this.tempVector2.subVectors(
|
|
2221
|
+
const deltaVector = this.tempVector2.subVectors(
|
|
2222
|
+
newPosition,
|
|
2223
|
+
this.player.position
|
|
2224
|
+
);
|
|
1800
2225
|
const offset = Math.max(0, deltaVector.length() - 1e-5);
|
|
1801
2226
|
deltaVector.normalize().multiplyScalar(offset);
|
|
1802
2227
|
this.player.position.add(deltaVector);
|
|
@@ -1813,14 +2238,22 @@ var PlayerController = class {
|
|
|
1813
2238
|
} else {
|
|
1814
2239
|
lookTarget = this.player.position.clone().add(this.camDir);
|
|
1815
2240
|
}
|
|
1816
|
-
this.targetMat.lookAt(
|
|
2241
|
+
this.targetMat.lookAt(
|
|
2242
|
+
this.player.position,
|
|
2243
|
+
lookTarget,
|
|
2244
|
+
this.player.up
|
|
2245
|
+
);
|
|
1817
2246
|
this.targetQuat.setFromRotationMatrix(this.targetMat);
|
|
1818
2247
|
const alpha = Math.min(1, this.rotationSpeed * delta);
|
|
1819
2248
|
this.player.quaternion.slerp(this.targetQuat, alpha);
|
|
1820
2249
|
}
|
|
1821
2250
|
if ((this.thirdMouseMode === 1 || this.thirdMouseMode === 3) && this.moveDir.lengthSq() > 0) {
|
|
1822
2251
|
lookTarget = this.player.position.clone().add(this.moveDir);
|
|
1823
|
-
this.targetMat.lookAt(
|
|
2252
|
+
this.targetMat.lookAt(
|
|
2253
|
+
this.player.position,
|
|
2254
|
+
lookTarget,
|
|
2255
|
+
this.player.up
|
|
2256
|
+
);
|
|
1824
2257
|
this.targetQuat.setFromRotationMatrix(this.targetMat);
|
|
1825
2258
|
const alpha = Math.min(1, this.rotationSpeed * delta);
|
|
1826
2259
|
this.player.quaternion.slerp(this.targetQuat, alpha);
|
|
@@ -1834,7 +2267,11 @@ var PlayerController = class {
|
|
|
1834
2267
|
this.moveDir.normalize();
|
|
1835
2268
|
this.moveDir.negate();
|
|
1836
2269
|
const lookTarget = this.player.position.clone().add(this.fwdPressed ? this.moveDir : this.camDir);
|
|
1837
|
-
this.targetMat.lookAt(
|
|
2270
|
+
this.targetMat.lookAt(
|
|
2271
|
+
this.player.position,
|
|
2272
|
+
lookTarget,
|
|
2273
|
+
this.player.up
|
|
2274
|
+
);
|
|
1838
2275
|
this.targetQuat.setFromRotationMatrix(this.targetMat);
|
|
1839
2276
|
const alpha = Math.min(1, this.rotationSpeed * delta);
|
|
1840
2277
|
this.player.quaternion.slerp(this.targetQuat, alpha);
|
|
@@ -1842,50 +2279,119 @@ var PlayerController = class {
|
|
|
1842
2279
|
}
|
|
1843
2280
|
if (!this.isFirstPerson) {
|
|
1844
2281
|
const lookTarget = this.player.position.clone();
|
|
1845
|
-
lookTarget.y += this.playerHeight /
|
|
2282
|
+
lookTarget.y += this.playerHeight / 8 * this.playerModel.scale;
|
|
1846
2283
|
this.camera.position.sub(this.controls.target);
|
|
1847
2284
|
this.controls.target.copy(lookTarget);
|
|
1848
2285
|
this.camera.position.add(lookTarget);
|
|
1849
2286
|
this.controls.update();
|
|
1850
2287
|
if (!this.enableZoom) {
|
|
1851
|
-
this._personToCam.subVectors(
|
|
2288
|
+
this._personToCam.subVectors(
|
|
2289
|
+
this.camera.position,
|
|
2290
|
+
this.player.position
|
|
2291
|
+
);
|
|
1852
2292
|
const origin = this.player.position.clone();
|
|
1853
2293
|
const direction = this._personToCam.clone().normalize();
|
|
1854
2294
|
const desiredDist = this._personToCam.length();
|
|
1855
2295
|
this._raycasterPersonToCam.set(origin, direction);
|
|
1856
2296
|
this._raycasterPersonToCam.far = desiredDist;
|
|
1857
|
-
const intersectsCamera = this._raycasterPersonToCam.intersectObject(
|
|
2297
|
+
const intersectsCamera = this._raycasterPersonToCam.intersectObject(
|
|
2298
|
+
this.collider,
|
|
2299
|
+
false
|
|
2300
|
+
);
|
|
1858
2301
|
if (intersectsCamera.length > 0) {
|
|
1859
2302
|
const hit = intersectsCamera[0];
|
|
1860
|
-
const safeDist = Math.max(
|
|
2303
|
+
const safeDist = Math.max(
|
|
2304
|
+
hit.distance - this._camEpsilon,
|
|
2305
|
+
this.minCamDistance
|
|
2306
|
+
);
|
|
1861
2307
|
const targetCamPos = origin.clone().add(direction.clone().multiplyScalar(safeDist));
|
|
1862
|
-
this.camera.position.lerp(
|
|
2308
|
+
this.camera.position.lerp(
|
|
2309
|
+
targetCamPos,
|
|
2310
|
+
this._camCollisionLerp
|
|
2311
|
+
);
|
|
1863
2312
|
} else {
|
|
1864
|
-
this._raycasterPersonToCam.far = this.
|
|
1865
|
-
const intersectsMaxDis = this._raycasterPersonToCam.intersectObject(
|
|
1866
|
-
|
|
2313
|
+
this._raycasterPersonToCam.far = this.maxCamDistance;
|
|
2314
|
+
const intersectsMaxDis = this._raycasterPersonToCam.intersectObject(
|
|
2315
|
+
this.collider,
|
|
2316
|
+
false
|
|
2317
|
+
);
|
|
2318
|
+
let safeDist = this.maxCamDistance;
|
|
1867
2319
|
if (intersectsMaxDis.length) {
|
|
1868
2320
|
const hitMax = intersectsMaxDis[0];
|
|
1869
2321
|
safeDist = hitMax.distance - this._camEpsilon;
|
|
1870
2322
|
}
|
|
1871
2323
|
const targetCamPos = origin.clone().add(direction.clone().multiplyScalar(safeDist));
|
|
1872
|
-
this.camera.position.lerp(
|
|
2324
|
+
this.camera.position.lerp(
|
|
2325
|
+
targetCamPos,
|
|
2326
|
+
this._camCollisionLerp
|
|
2327
|
+
);
|
|
1873
2328
|
}
|
|
1874
2329
|
}
|
|
1875
2330
|
}
|
|
1876
2331
|
if (this.player.position.y < this.boundingBoxMinY - 1) {
|
|
1877
|
-
this._originTmp.set(
|
|
2332
|
+
this._originTmp.set(
|
|
2333
|
+
this.player.position.x,
|
|
2334
|
+
1e4,
|
|
2335
|
+
this.player.position.z
|
|
2336
|
+
);
|
|
1878
2337
|
this._raycaster.ray.origin.copy(this._originTmp);
|
|
1879
|
-
const intersectsFall = this._raycaster.intersectObject(
|
|
2338
|
+
const intersectsFall = this._raycaster.intersectObject(
|
|
2339
|
+
this.collider,
|
|
2340
|
+
false
|
|
2341
|
+
);
|
|
1880
2342
|
if (intersectsFall.length > 0) {
|
|
1881
2343
|
console.log("\u73A9\u5BB6\u4E3Abug\u610F\u5916\u6389\u843D");
|
|
1882
|
-
this.reset(
|
|
2344
|
+
this.reset(
|
|
2345
|
+
new THREE3.Vector3(
|
|
2346
|
+
this.player.position.x,
|
|
2347
|
+
intersectsFall[0].point.y + 5,
|
|
2348
|
+
this.player.position.z
|
|
2349
|
+
)
|
|
2350
|
+
);
|
|
1883
2351
|
} else {
|
|
1884
2352
|
console.log("\u73A9\u5BB6\u6B63\u5E38\u6389\u843D");
|
|
1885
|
-
this.reset(
|
|
2353
|
+
this.reset(
|
|
2354
|
+
new THREE3.Vector3(
|
|
2355
|
+
this.player.position.x,
|
|
2356
|
+
this.player.position.y + 15,
|
|
2357
|
+
this.player.position.z
|
|
2358
|
+
)
|
|
2359
|
+
);
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
if (this.isShowMobileControls) {
|
|
2363
|
+
if (this.vehicles.length) {
|
|
2364
|
+
let near = false;
|
|
2365
|
+
for (const v of this.vehicles) {
|
|
2366
|
+
this.nearCheckLocal.copy(v.boardingPoint).multiplyScalar(v.scale);
|
|
2367
|
+
v.vehicleGroup.localToWorld(
|
|
2368
|
+
this.nearCheckWorld.copy(this.nearCheckLocal)
|
|
2369
|
+
);
|
|
2370
|
+
if (this.player.position.distanceTo(this.nearCheckWorld) < 800 * this.playerModel.scale) {
|
|
2371
|
+
near = true;
|
|
2372
|
+
this.syncVehicleBtnEl(near);
|
|
2373
|
+
break;
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
if (near !== this.isNearVehicle) {
|
|
2377
|
+
this.isNearVehicle = near;
|
|
2378
|
+
this.syncVehicleBtnEl(near);
|
|
2379
|
+
}
|
|
2380
|
+
} else {
|
|
2381
|
+
this.isNearVehicle = false;
|
|
2382
|
+
this.syncVehicleBtnEl(false);
|
|
1886
2383
|
}
|
|
1887
2384
|
}
|
|
1888
2385
|
}
|
|
2386
|
+
/**
|
|
2387
|
+
* 获取屏幕中心点向前射线与碰撞体的交点
|
|
2388
|
+
*/
|
|
2389
|
+
getCenterScreenRaycastHit() {
|
|
2390
|
+
this.camera.updateMatrixWorld();
|
|
2391
|
+
this.centerRay.setFromCamera(this.centerMouse, this.camera);
|
|
2392
|
+
const intersects = this.centerRay.intersectObject(this.collider, false);
|
|
2393
|
+
return intersects[0];
|
|
2394
|
+
}
|
|
1889
2395
|
/**
|
|
1890
2396
|
* 更新模型动画
|
|
1891
2397
|
*/
|
|
@@ -1901,7 +2407,7 @@ var PlayerController = class {
|
|
|
1901
2407
|
this.player.position.copy(position ?? this.initPos);
|
|
1902
2408
|
}
|
|
1903
2409
|
getPosition() {
|
|
1904
|
-
return this.player
|
|
2410
|
+
return this.player?.position;
|
|
1905
2411
|
}
|
|
1906
2412
|
// ==================== 输入处理 ====================
|
|
1907
2413
|
setInput(input) {
|
|
@@ -1920,7 +2426,14 @@ var PlayerController = class {
|
|
|
1920
2426
|
}
|
|
1921
2427
|
if (typeof input.jump === "boolean") {
|
|
1922
2428
|
if (input.jump) {
|
|
2429
|
+
if (this.isMovingToBoardingPoint) {
|
|
2430
|
+
this.isMovingToBoardingPoint = false;
|
|
2431
|
+
this.boardingWaypoints = [];
|
|
2432
|
+
this.currentWaypointIndex = 0;
|
|
2433
|
+
this.boardingTargetDir = null;
|
|
2434
|
+
}
|
|
1923
2435
|
this.spacePressed = true;
|
|
2436
|
+
if (this.controllerMode == 1) return;
|
|
1924
2437
|
if (!this.playerIsOnGround || this.isFlying) return;
|
|
1925
2438
|
this.playPersonAnimationByName("jumping");
|
|
1926
2439
|
this.playerVelocity.y = this.jumpHeight;
|
|
@@ -1935,13 +2448,20 @@ var PlayerController = class {
|
|
|
1935
2448
|
if (input.toggleView) {
|
|
1936
2449
|
this.changeView();
|
|
1937
2450
|
}
|
|
1938
|
-
if (input.toggleFly) {
|
|
2451
|
+
if (input.toggleFly && this.playerFlyEnabled && this.controllerMode == 0) {
|
|
1939
2452
|
this.isFlying = !this.isFlying;
|
|
1940
2453
|
this.setAnimationByPressed();
|
|
1941
2454
|
if (!this.isFlying && !this.playerIsOnGround) {
|
|
1942
2455
|
this.playPersonAnimationByName("jumping");
|
|
1943
2456
|
}
|
|
1944
2457
|
}
|
|
2458
|
+
if (input.toggleVehicle) {
|
|
2459
|
+
if (this.controllerMode == 0) {
|
|
2460
|
+
this.enterVehicle();
|
|
2461
|
+
} else {
|
|
2462
|
+
this.exitVehicle();
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
1945
2465
|
}
|
|
1946
2466
|
onAllEvent() {
|
|
1947
2467
|
this.isupdate = true;
|
|
@@ -1981,11 +2501,17 @@ var PlayerController = class {
|
|
|
1981
2501
|
userSelect: "none"
|
|
1982
2502
|
});
|
|
1983
2503
|
container.appendChild(this.joystickZoneEl);
|
|
1984
|
-
["touchstart", "touchmove", "touchend", "touchcancel"].forEach(
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
2504
|
+
["touchstart", "touchmove", "touchend", "touchcancel"].forEach(
|
|
2505
|
+
(evtName) => {
|
|
2506
|
+
this.joystickZoneEl?.addEventListener(
|
|
2507
|
+
evtName,
|
|
2508
|
+
(e) => e.preventDefault(),
|
|
2509
|
+
{
|
|
2510
|
+
passive: false
|
|
2511
|
+
}
|
|
2512
|
+
);
|
|
2513
|
+
}
|
|
2514
|
+
);
|
|
1989
2515
|
this.joystickManager = nipple.create({
|
|
1990
2516
|
zone: this.joystickZoneEl,
|
|
1991
2517
|
mode: "static",
|
|
@@ -2008,13 +2534,22 @@ var PlayerController = class {
|
|
|
2008
2534
|
const dirY = rawY > deadzone ? 1 : rawY < -deadzone ? -1 : 0;
|
|
2009
2535
|
const sprintThreshold = JOY_SIZE / 2;
|
|
2010
2536
|
const isSprinting = distance >= sprintThreshold;
|
|
2011
|
-
const prev = this.prevJoyState || {
|
|
2012
|
-
|
|
2537
|
+
const prev = this.prevJoyState || {
|
|
2538
|
+
dirX: 0,
|
|
2539
|
+
dirY: 0,
|
|
2540
|
+
shift: false
|
|
2541
|
+
};
|
|
2542
|
+
if (dirX === prev.dirX && dirY === prev.dirY && isSprinting === prev.shift)
|
|
2543
|
+
return;
|
|
2013
2544
|
this.prevJoyState = { dirX, dirY, shift: isSprinting };
|
|
2014
2545
|
this.setInput({ moveX: dirX, moveY: dirY, shift: isSprinting });
|
|
2015
2546
|
});
|
|
2016
2547
|
this.joystickManager.on("end", () => {
|
|
2017
|
-
const prev = this.prevJoyState || {
|
|
2548
|
+
const prev = this.prevJoyState || {
|
|
2549
|
+
dirX: 0,
|
|
2550
|
+
dirY: 0,
|
|
2551
|
+
shift: false
|
|
2552
|
+
};
|
|
2018
2553
|
if (prev.dirX !== 0 || prev.dirY !== 0 || prev.shift !== false) {
|
|
2019
2554
|
this.prevJoyState = { dirX: 0, dirY: 0, shift: false };
|
|
2020
2555
|
this.setInput({ moveX: 0, moveY: 0, shift: false });
|
|
@@ -2033,15 +2568,29 @@ var PlayerController = class {
|
|
|
2033
2568
|
userSelect: "none"
|
|
2034
2569
|
});
|
|
2035
2570
|
container.appendChild(this.lookAreaEl);
|
|
2036
|
-
["touchstart", "touchmove", "touchend", "touchcancel"].forEach(
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2571
|
+
["touchstart", "touchmove", "touchend", "touchcancel"].forEach(
|
|
2572
|
+
(evtName) => {
|
|
2573
|
+
this.lookAreaEl?.addEventListener(
|
|
2574
|
+
evtName,
|
|
2575
|
+
(e) => e.preventDefault(),
|
|
2576
|
+
{
|
|
2577
|
+
passive: false
|
|
2578
|
+
}
|
|
2579
|
+
);
|
|
2580
|
+
}
|
|
2581
|
+
);
|
|
2582
|
+
this.lookAreaEl.addEventListener("pointerdown", this.onPointerDown, {
|
|
2583
|
+
passive: false
|
|
2584
|
+
});
|
|
2585
|
+
this.lookAreaEl.addEventListener("pointermove", this.onPointerMove, {
|
|
2586
|
+
passive: false
|
|
2587
|
+
});
|
|
2588
|
+
this.lookAreaEl.addEventListener("pointerup", this.onPointerUp, {
|
|
2589
|
+
passive: false
|
|
2590
|
+
});
|
|
2591
|
+
this.lookAreaEl.addEventListener("pointercancel", this.onPointerUp, {
|
|
2592
|
+
passive: false
|
|
2040
2593
|
});
|
|
2041
|
-
this.lookAreaEl.addEventListener("pointerdown", this.onPointerDown, { passive: false });
|
|
2042
|
-
this.lookAreaEl.addEventListener("pointermove", this.onPointerMove, { passive: false });
|
|
2043
|
-
this.lookAreaEl.addEventListener("pointerup", this.onPointerUp, { passive: false });
|
|
2044
|
-
this.lookAreaEl.addEventListener("pointercancel", this.onPointerUp, { passive: false });
|
|
2045
2594
|
const createBtn = (rightPx, bottomPx, bgUrl) => {
|
|
2046
2595
|
const btn = document.createElement("button");
|
|
2047
2596
|
const styles = {
|
|
@@ -2073,7 +2622,9 @@ var PlayerController = class {
|
|
|
2073
2622
|
Object.assign(btn.style, styles);
|
|
2074
2623
|
container.appendChild(btn);
|
|
2075
2624
|
["touchstart", "touchend", "touchcancel"].forEach((evtName) => {
|
|
2076
|
-
btn.addEventListener(evtName, (e) => e.preventDefault(), {
|
|
2625
|
+
btn.addEventListener(evtName, (e) => e.preventDefault(), {
|
|
2626
|
+
passive: false
|
|
2627
|
+
});
|
|
2077
2628
|
});
|
|
2078
2629
|
return btn;
|
|
2079
2630
|
};
|
|
@@ -2120,6 +2671,15 @@ var PlayerController = class {
|
|
|
2120
2671
|
},
|
|
2121
2672
|
{ passive: false }
|
|
2122
2673
|
);
|
|
2674
|
+
this.vehicleBtnEl = createBtn(14 + 100, 14 + 120, vehicle_default);
|
|
2675
|
+
this.vehicleBtnEl.addEventListener(
|
|
2676
|
+
"touchstart",
|
|
2677
|
+
(e) => {
|
|
2678
|
+
e.preventDefault();
|
|
2679
|
+
this.setInput({ toggleVehicle: true });
|
|
2680
|
+
},
|
|
2681
|
+
{ passive: false }
|
|
2682
|
+
);
|
|
2123
2683
|
}
|
|
2124
2684
|
destroyMobileControls() {
|
|
2125
2685
|
try {
|
|
@@ -2128,7 +2688,9 @@ var PlayerController = class {
|
|
|
2128
2688
|
this.joystickManager = null;
|
|
2129
2689
|
}
|
|
2130
2690
|
if (this.joystickZoneEl?.parentElement) {
|
|
2131
|
-
this.joystickZoneEl.parentElement.removeChild(
|
|
2691
|
+
this.joystickZoneEl.parentElement.removeChild(
|
|
2692
|
+
this.joystickZoneEl
|
|
2693
|
+
);
|
|
2132
2694
|
this.joystickZoneEl = null;
|
|
2133
2695
|
}
|
|
2134
2696
|
if (this.lookAreaEl?.parentElement) {
|
|
@@ -2147,14 +2709,86 @@ var PlayerController = class {
|
|
|
2147
2709
|
this.viewBtnEl.parentElement.removeChild(this.viewBtnEl);
|
|
2148
2710
|
this.viewBtnEl = null;
|
|
2149
2711
|
}
|
|
2150
|
-
this.
|
|
2151
|
-
|
|
2712
|
+
if (this.vehicleBtnEl?.parentElement) {
|
|
2713
|
+
this.vehicleBtnEl.parentElement.removeChild(this.vehicleBtnEl);
|
|
2714
|
+
this.vehicleBtnEl = null;
|
|
2715
|
+
}
|
|
2716
|
+
this.lookAreaEl?.removeEventListener(
|
|
2717
|
+
"pointerdown",
|
|
2718
|
+
this.onPointerDown
|
|
2719
|
+
);
|
|
2720
|
+
this.lookAreaEl?.removeEventListener(
|
|
2721
|
+
"pointermove",
|
|
2722
|
+
this.onPointerMove
|
|
2723
|
+
);
|
|
2152
2724
|
this.lookAreaEl?.removeEventListener("pointerup", this.onPointerUp);
|
|
2153
|
-
this.lookAreaEl?.removeEventListener(
|
|
2725
|
+
this.lookAreaEl?.removeEventListener(
|
|
2726
|
+
"pointercancel",
|
|
2727
|
+
this.onPointerUp
|
|
2728
|
+
);
|
|
2154
2729
|
} catch (e) {
|
|
2155
2730
|
console.warn("\u9500\u6BC1\u79FB\u52A8\u7AEF\u6447\u6746\u63A7\u5236\u65F6\u51FA\u9519\uFF1A", e);
|
|
2156
2731
|
}
|
|
2157
2732
|
}
|
|
2733
|
+
syncVehicleBtnEl(show) {
|
|
2734
|
+
if (!this.vehicleBtnEl) return;
|
|
2735
|
+
this.vehicleBtnEl.style.display = show ? "block" : "none";
|
|
2736
|
+
}
|
|
2737
|
+
syncControllerModeBtnEl() {
|
|
2738
|
+
if (!this.isShowMobileControls) return;
|
|
2739
|
+
if (this.controllerMode == 0) {
|
|
2740
|
+
this.flyBtnEl.style.display = "block";
|
|
2741
|
+
const overlayColor = "rgba(0,0,0,0.5)";
|
|
2742
|
+
this.jumpBtnEl.style.backgroundImage = `linear-gradient(${overlayColor}, ${overlayColor}), url("${jump_default}")`;
|
|
2743
|
+
} else {
|
|
2744
|
+
this.flyBtnEl.style.display = "none";
|
|
2745
|
+
const overlayColor = "rgba(0,0,0,0.5)";
|
|
2746
|
+
this.jumpBtnEl.style.backgroundImage = `linear-gradient(${overlayColor}, ${overlayColor}), url("${break_default}")`;
|
|
2747
|
+
this.jumpBtnEl.style.backgroundImage = `url(${break_default})`;
|
|
2748
|
+
}
|
|
2749
|
+
}
|
|
2750
|
+
// ==================== 更新参数 ====================
|
|
2751
|
+
setMouseSensitivity(mouseSensity) {
|
|
2752
|
+
this.mouseSensity = mouseSensity;
|
|
2753
|
+
this.controls.rotateSpeed = this.mouseSensity * 0.05;
|
|
2754
|
+
}
|
|
2755
|
+
setGravity(gravity) {
|
|
2756
|
+
this.gravity = gravity * this.playerModel.scale;
|
|
2757
|
+
}
|
|
2758
|
+
setJumpHeight(jumpHeight) {
|
|
2759
|
+
this.jumpHeight = jumpHeight * this.playerModel.scale;
|
|
2760
|
+
}
|
|
2761
|
+
setPlayerSpeed(playerSpeed) {
|
|
2762
|
+
this.playerSpeed = playerSpeed * this.playerModel.scale;
|
|
2763
|
+
this.curPlayerSpeed = this.playerSpeed;
|
|
2764
|
+
}
|
|
2765
|
+
setPlayerFlySpeed(playerFlySpeed) {
|
|
2766
|
+
this.playerFlySpeed = playerFlySpeed * this.playerModel.scale;
|
|
2767
|
+
}
|
|
2768
|
+
setMinCamDistance(minCamDistance) {
|
|
2769
|
+
this.minCamDistance = minCamDistance * this.playerModel.scale;
|
|
2770
|
+
}
|
|
2771
|
+
setMaxCamDistance(maxCamDistance) {
|
|
2772
|
+
this.maxCamDistance = maxCamDistance * this.playerModel.scale;
|
|
2773
|
+
this.orginMaxCamDistance = this.maxCamDistance;
|
|
2774
|
+
}
|
|
2775
|
+
setThirdMouseMode(thirdMouseMode) {
|
|
2776
|
+
this.thirdMouseMode = thirdMouseMode;
|
|
2777
|
+
this.setPointerLock();
|
|
2778
|
+
}
|
|
2779
|
+
setEnableZoom(enableZoom) {
|
|
2780
|
+
this.enableZoom = enableZoom;
|
|
2781
|
+
this.controls.enableZoom = this.enableZoom;
|
|
2782
|
+
}
|
|
2783
|
+
setDebug(debug) {
|
|
2784
|
+
if (this.collider) this.scene.remove(this.collider);
|
|
2785
|
+
if (debug) {
|
|
2786
|
+
this.scene.add(this.collider);
|
|
2787
|
+
this.player.material.opacity = 0.5;
|
|
2788
|
+
} else {
|
|
2789
|
+
this.player.material.opacity = 0;
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2158
2792
|
// ==================== 销毁 ====================
|
|
2159
2793
|
destroy() {
|
|
2160
2794
|
this.offAllEvent();
|
|
@@ -2197,10 +2831,24 @@ function playerController() {
|
|
|
2197
2831
|
update: (dt) => c.update(dt),
|
|
2198
2832
|
destroy: () => c.destroy(),
|
|
2199
2833
|
setInput: (i) => c.setInput(i),
|
|
2200
|
-
|
|
2834
|
+
getPosition: () => c.getPosition(),
|
|
2835
|
+
getCenterScreenRaycastHit: () => c.getCenterScreenRaycastHit(),
|
|
2201
2836
|
getPerson: () => c.person,
|
|
2202
2837
|
getActiveVehicle: () => c.activeVehicle,
|
|
2203
|
-
getAllVehicles: () => c.vehicles
|
|
2838
|
+
getAllVehicles: () => c.vehicles,
|
|
2839
|
+
switchPlayerModel: (model) => c.switchPlayerModel(model),
|
|
2840
|
+
setMouseSensitivity: (mouseSensity) => c.setMouseSensitivity(mouseSensity),
|
|
2841
|
+
setGravity: (gravity) => c.setGravity(gravity),
|
|
2842
|
+
setJumpHeight: (jumpHeight) => c.setJumpHeight(jumpHeight),
|
|
2843
|
+
setPlayerSpeed: (playerSpeed) => c.setPlayerSpeed(playerSpeed),
|
|
2844
|
+
setPlayerFlySpeed: (playerFlySpeed) => c.setPlayerFlySpeed(playerFlySpeed),
|
|
2845
|
+
setMinCamDistance: (minCamDistance) => c.setMinCamDistance(minCamDistance),
|
|
2846
|
+
setMaxCamDistance: (maxCamDistance) => c.setMaxCamDistance(maxCamDistance),
|
|
2847
|
+
setThirdMouseMode: (thirdMouseMode) => c.setThirdMouseMode(thirdMouseMode),
|
|
2848
|
+
setEnableZoom: (enableZoom) => c.setEnableZoom(enableZoom),
|
|
2849
|
+
setDebug: (debug) => c.setDebug(debug),
|
|
2850
|
+
setOverShoulderView: (enable) => c.setOverShoulderView(enable),
|
|
2851
|
+
setPlayerScale: (scale) => c.setPlayerScale(scale)
|
|
2204
2852
|
};
|
|
2205
2853
|
}
|
|
2206
2854
|
function onAllEvent() {
|