From 5b44a286a9869289283e95ea37b924a2688c5cb3 Mon Sep 17 00:00:00 2001 From: min Date: Mon, 8 Jun 2026 18:59:23 +0300 Subject: [PATCH] =?UTF-8?q?fix(import):=20=D0=B7=D0=B0=D0=BB=D0=B8=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=82=D0=B5=D0=BD=D0=B5=D0=B9=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D1=82=20+=20Anchored=3DTrue=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=B2=D1=81=D0=B5=D1=85=20=D0=B8=D0=BC?= =?UTF-8?q?=D0=BF=D0=BE=D1=80=D1=82.=20Part?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. PrimitiveManager: mat.ambientColor=(1,1,1). Теперь scene.ambientColor ("Заливка теней" слайдер) реально влияет на тени. Юзер крутит значение и видит изменение. 2. converter.py: Roblox-Part импортируется всегда с Anchored=True (force-anchored). Welds у нас заглушки, без них unanchored Part'ы рассыпаются физикой. Если юзеру нужно падающее — снимет в инспекторе вручную. Деплой converter.py на VM 130 + systemctl restart. --- .../src/__pycache__/converter.cpython-314.pyc | Bin 58378 -> 57867 bytes rbxl-importer/src/converter.py | 28 +++++++++++++----- src/editor/engine/PrimitiveManager.js | 7 +++-- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/rbxl-importer/src/__pycache__/converter.cpython-314.pyc b/rbxl-importer/src/__pycache__/converter.cpython-314.pyc index 447629e0731214e02241ee9ac9b1774cd9733126..6a970143b7f310de1a057acf50dc9337cf620ebd 100644 GIT binary patch delta 3463 zcmd^CYfN0n6~1$qeZaoW!ajM}%fc=uJk2W!i3t!8q%K@A#HfW78~Gu};04Eo##uW^ zmF-Gq)nn>SWRi7S+e`ggd}WDPNlR2WvYgm#vUWn;HgYN}X&qNw6j!)O6!px#?1o5= z^QVd`b$^`s&bc%9&dfL8IkWpO%6@r4rdz4gCNcOs{z>+hU1ukCb7r|=z`MSHudtlY zvzN(N&NFC^xCPowt`eK6S`5PE7JGu~^Sufn6%M$)#msltjmcG zX;x$K=Lj-HH#E!qb%Gp`pkTDg2Y(!_3zbDp#e$NCRE*Z(PxiNtS%gH%cVq-*!J4D0 zn7=YVG!QO1H6-~-jMnI1A*gBJB*ttHJQl;tUBMm+>oknkbg(N}7fs0(v5SGANDj1(TZIhCcNK<{!)@oR zQ%x6>FScE_&eQnbL}3NAw2XURBn&gK0{80fZf1c=r`wO_NQFR~$y%|QYQx~-_J1LZ zZ9jC^9e~TjcliFFoFEP^1!=HwGPG9Yz_yeFh^%#krhTnE19v_XKI?MAzV^;??*sU4 zZ$5t8n@>>zMFkWUB3d)C%v(sEY8o!3hECI40+}6Uq!cdC|KN=Jo4T!Ie%+VK|{ zdO6(}Dvz2<1i3Ctq%FpgQu5;*E&6eeL?1b&93|4eDv6^-yqt0*V&pMSk(zcy&dgUW zxuMcCl@pcWPUve^vRWNK_!06sJn0nJKnNq**COGGnCKB|k=*u;^Dc zkVW=r;0~ipR14|w_2&Ja*Km)%Aux>+h-Shf(B`!)v6)_l!T%P2${&IpSO2|H;--=(6fDiL3oVcDTpFNDSgQheMu)Z($3FqOeeFvZqqR9x%;hS z@+dtfXpU?WXfrt|Hq!|h#AA}i_A9B%`P*Cm$&v>C`qRgVinF1#(>N8}>~+JHK2rjh z#kt^%zIl=jxBF{I4is*0g-?53_|Oc0*xsTMN4Pl;j?0BL-gRUpguJ&?@4ZS04|I}3 zP!CoRs_+$H9nqu8pBd~!m47l=uMijTZ@4zn#6Q17LwtI-Zq{J(Zxmz{Ww?URi0FnP z^{_r94-H2x4+?U8gt^;j^0x+($DS0FlAq}e)`Vn78)AMzakwNraIQk~Rg5vkk7B2N zRg66&$i}eC6T;*`<4H`8(Q-IFB#&D21vQOm7^D5FBR{m`%(D~EPT8UbwNXc%pw&a+ zPCK0|<^iKEuu3pe9Loa~TNtA`AQP+<+ZdxG&>A$2uM_N&?^zXYoid$^`_<$LaXY8rw=mBKeG1$f~j}wzFy@p z6-zsV7h*enzV9sA%OBf+B|-hoNh|{2=xWT%)1$B8!>9Z+goOFRUlq#m1wR`r5>KW_ z2}R>3I62mU&;B*`98p}r*Ls`yorh#{gIMjPLPtwh0qj3qi-Ttl1D@ga<7MOm|I+x& zEV;>72Dj09g^p|_H^K1g4Kl~izj}!*nN2CY_1h*g2g{CrMZV79@$a8itBIHY z+Z!8L{B-?vJ+5_hI*pX^r>4_shj-pI%gL|#n{T}>TQZR%IDaXJEh7*awZd1I)?<&S z-abUgY5wjzi7Yt{?98X+4gS{5pIB_d@BNVw1q@y-t;YX2;y;{)euDRH@wUCNnxs*P zX5kSBMQAXHby}>_3y-mwvc$ZF@HhXs%96jst@nRV=J|;aa1q6DYxZ4I#J~RG6{Ys) SYGRpZs1;UQ_(LBLu>S#2s4bHK delta 3222 zcmdT`eN>a@6@Q;M2?>ydganch2p<7L_>j*+#KK^FS<#6B(#E9}`KaLdT7uTYRBX4k z9(UYwyyciG)==jb+uDXbht9e)t7qK~b)}-|oZY(C&YrVVUAvcQ58XMPXV3G#268rL zyFYez_Wp72@80M8zV~;Z=X}|4_rj>uut!b>QbhUeW-5%Fq z|B$P`*Yl0h;SrZ-bbC+#aDlsP=RiUK;K;Ch)D?ky-7b&2+l5*EnS5iJByWKsVk(ED zYPyV9r|XFmE;&=!Gf}`f&*PsqNF}Vx3R7*V52xDG%2>J&hABgW?n3r-yM)LLhtzJ) zPZGRT5??0qWkvez*~DXs^c1pnXhiK`?Ku$B?2%Z_j5QaYXucRDs~zg@8+P~hG~$-^ zK7^9+M;k`bxH2K;s$Au@a3X@P$>Y5ZoP;1Qicx5u-so=#l!vq>oRqp`j6&trcv~m* zT(n>(r}{cp~J`C`mDJ4LK3mHr=C+@(h%C~VJxqTO0B_Nrm*nR-b&iD?E*x9_$#x(mo}bFbnB z`9{-TH)M-)$#Jo@SmZ`nC`CtP2XN<>eL`Pe7(~M$NN&HcOw9A^o6W5bdn4*^=EsT zMaD?ek%*Iej;dEPd3COgIQew^kB({vbw@}3mpZPyfu6h(COWF4_#K(xosM_S|8klt zPDFepk7=7{20;wE&Idy`yhc|8w+J<#eK*bm(R( z8sVcyZBjbB=kEyK^Q?o+N1E`fTdyPQU#W8`qHAbGiJ0o+sG1(-)j2V7l873`@>_39 z3B^mHxgi>-ZJT4!7W~P;j}Ys!&}=fK*i9?2J=HFQ;82c!WqR8!@b1t8%7Kx=EVwmn z5?LKFux?iYTp!E?Jd`C14}*gvop%>XS$UycdmibW4|hhKr~n@N=AV=A^*>>=dowDA z8Mlqk+hSA>X`W${u3k@*l#h!+jNkJ((6}N;c~zzLZskN2rDpke@aUQ^XwhK#wr9sb(O|WH*I>Fn;Mbo}A#+d47!#K+t z$PjQ0BUkGuO#w;Bu!@USz-!x+kOJQSw$VvPsTg&VuZ&Yu9M7nYllA_D9~-6&fy&_a zPx> zQd~#MXt>}hs6)<#3m$jZu3C$P$|pFK5p_3?j^Hb>SUN)0 zc<5Wpv`Mz7tUw!+T@1lJc?o860cJ*Cfc7kVHn?`bfGlw7kQws!q=|AI3fRa)52OjSsgn8-l z+9*CU9Q?u4Ov?M;zKAl9h4dBw1Io~C{dXwC)S~rhwsn3}`<(NtDseukG}sul&Fk-9 zh~NL&{jNv46PdZh!DR1Stb4UBN>sh>dA zlS+*DofpRz(`&4j-e4s#exQcr+qnbB&=~Ig{zZhI!$saA5t(8O6i3ku&nkuDBU*S7 z){?eQVHb*eg-q58Jfh2JEk#h73K78a^7G1%spBR01=B z?bOOYX+cPW+nzs(i1W@1y+{H*FWy9I+;Xa(C2Hd38iY*vN-#DS_257LtcN8_H=S)F zXZ^w16jXsvoi))8Z@#9Jpndqm*MBXF*hmSSnYFML2<8tM;PcsT(xdZ@LkRitXBVPb zz#kQFAkt&3W->}pS+>?7t~_qlCK7lX8`{Q zSR6y7#PJ1=z~eVAv*>ql^X;?fI)45)7^U5Vuf`9(ox1@@}SfpQIsN{Nd*!RAN F{Rc;*&a40c diff --git a/rbxl-importer/src/converter.py b/rbxl-importer/src/converter.py index dd054c7..7509a40 100644 --- a/rbxl-importer/src/converter.py +++ b/rbxl-importer/src/converter.py @@ -397,7 +397,9 @@ class Converter: 'canCollide': bool(props.get('CanCollide', True)), 'visible': props.get('Transparency', 0) < 1.0 if isinstance(props.get('Transparency'), (int, float)) else True, 'opacity': max(0.0, 1.0 - (props.get('Transparency', 0) or 0)), - 'anchored': bool(props.get('Anchored', False)), + # FORCE-ANCHORED — Welds импортируем как заглушки, без них + # физика 700+ unanchored Part'ов = карта рассыпается. + 'anchored': True, 'mass': 1.0, 'rotationX': rot['rx'], 'rotationY': rot['ry'], 'rotationZ': rot['rz'], } @@ -428,7 +430,9 @@ class Converter: 'material': material_to_string(props.get('Material')), 'canCollide': bool(props.get('CanCollide', True)), 'visible': True, - 'anchored': bool(props.get('Anchored', False)), + # FORCE-ANCHORED — Welds импортируем как заглушки, без них + # физика 700+ unanchored Part'ов = карта рассыпается. + 'anchored': True, 'mass': 1.0, 'rotationX': rot['rx'], 'rotationY': rot['ry'], 'rotationZ': rot['rz'], }) @@ -457,7 +461,9 @@ class Converter: 'material': material_to_string(props.get('Material')), 'canCollide': bool(props.get('CanCollide', True)), 'visible': True, - 'anchored': bool(props.get('Anchored', False)), + # FORCE-ANCHORED — Welds импортируем как заглушки, без них + # физика 700+ unanchored Part'ов = карта рассыпается. + 'anchored': True, 'mass': 1.0, 'rotationX': rot['rx'], 'rotationY': rot['ry'], 'rotationZ': rot['rz'], }) @@ -529,7 +535,9 @@ class Converter: 'material': material_to_string(props.get('Material')), 'canCollide': bool(props.get('CanCollide', True)), 'visible': True, - 'anchored': bool(props.get('Anchored', False)), + # FORCE-ANCHORED — Welds импортируем как заглушки, без них + # физика 700+ unanchored Part'ов = карта рассыпается. + 'anchored': True, 'mass': 1.0, 'rotationX': rot['rx'], 'rotationY': rot['ry'], 'rotationZ': rot['rz'], 'note': f'MeshPart (no GLB) rbxid={rbx_id}', @@ -550,7 +558,9 @@ class Converter: 'rotationX': rot['rx'], 'rotationY': rot['ry'], 'rotationZ': rot['rz'], 'color': get_part_color(props), 'canCollide': bool(props.get('CanCollide', True)), - 'anchored': bool(props.get('Anchored', False)), + # FORCE-ANCHORED — Welds импортируем как заглушки, без них + # физика 700+ unanchored Part'ов = карта рассыпается. + 'anchored': True, 'origin': 'roblox-meshpart', 'rbxAssetId': rbx_id, }) @@ -590,7 +600,9 @@ class Converter: 'material': material_to_string(props.get('Material')), 'canCollide': bool(props.get('CanCollide', True)), 'visible': True, - 'anchored': bool(props.get('Anchored', False)), + # FORCE-ANCHORED — Welds импортируем как заглушки, без них + # физика 700+ unanchored Part'ов = карта рассыпается. + 'anchored': True, 'mass': 1.0, 'rotationX': rot['rx'], 'rotationY': rot['ry'], 'rotationZ': rot['rz'], 'note': f'Union (no CSG GLB) rbxid={rbx_id}', @@ -609,7 +621,9 @@ class Converter: 'rotationX': rot['rx'], 'rotationY': rot['ry'], 'rotationZ': rot['rz'], 'color': get_part_color(props), 'canCollide': bool(props.get('CanCollide', True)), - 'anchored': bool(props.get('Anchored', False)), + # FORCE-ANCHORED — Welds импортируем как заглушки, без них + # физика 700+ unanchored Part'ов = карта рассыпается. + 'anchored': True, 'origin': 'roblox-union', 'rbxAssetId': rbx_id, }) diff --git a/src/editor/engine/PrimitiveManager.js b/src/editor/engine/PrimitiveManager.js index 8d7d899..e8b2a08 100644 --- a/src/editor/engine/PrimitiveManager.js +++ b/src/editor/engine/PrimitiveManager.js @@ -507,8 +507,11 @@ export class PrimitiveManager { const matName = `${mesh.name}_mat`; const mat = new StandardMaterial(matName, this.scene); mat.diffuseColor = Color3.FromHexString(color || '#888888'); - // ambient = default (0,0,0). Освещение настраивается через - // глобальную панель «Свет и атмосфера» (sun/hemi/saturation). + // ambient = (1,1,1) — пассивный, реагирует на scene.ambientColor. + // Юзер крутит «Заливку теней» (sceneAmbient) → тени светлеют. + // На прямом свете diffuse доминирует — пересвета нет если + // sceneAmbient в разумных пределах (0..0.5). + mat.ambientColor = new Color3(1, 1, 1); // Если задан textureUrl — подгружаем PNG как diffuseTexture. Это // используется для GD-скинов куба (например /gd/skins/cube_smile.png).