11/*
2- * Copyright (c) 2009-2022 jMonkeyEngine
2+ * Copyright (c) 2009-2025 jMonkeyEngine
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
6262public class J3MLoader implements AssetLoader {
6363
6464 private static final Logger logger = Logger .getLogger (J3MLoader .class .getName ());
65- // private ErrorLogger errors;
6665 private ShaderNodeLoaderDelegate nodesLoaderDelegate ;
6766 boolean isUseNodes = false ;
6867 int langSize = 0 ;
@@ -86,7 +85,6 @@ public J3MLoader() {
8685 shaderNames = new EnumMap <>(Shader .ShaderType .class );
8786 }
8887
89-
9088 // <TYPE> <LANG> : <SOURCE>
9189 private void readShaderStatement (String statement ) throws IOException {
9290 String [] split = statement .split (":" );
@@ -103,7 +101,6 @@ private void readShaderStatement(String statement) throws IOException {
103101 }
104102 }
105103
106-
107104 private void readShaderDefinition (Shader .ShaderType shaderType , String name , String ... languages ) {
108105 shaderNames .put (shaderType , name );
109106
@@ -129,15 +126,15 @@ private void readLightMode(String statement) throws IOException{
129126 LightMode lm = LightMode .valueOf (split [1 ]);
130127 technique .setLightMode (lm );
131128 }
132-
133-
129+
130+
134131 // LightMode <SPACE>
135132 private void readLightSpace (String statement ) throws IOException {
136133 String [] split = statement .split (whitespacePattern );
137134 if (split .length != 2 ){
138135 throw new IOException ("LightSpace statement syntax incorrect" );
139136 }
140- TechniqueDef .LightSpace ls = TechniqueDef .LightSpace .valueOf (split [1 ]);
137+ TechniqueDef .LightSpace ls = TechniqueDef .LightSpace .valueOf (split [1 ]);
141138 technique .setLightSpace (ls );
142139 }
143140
@@ -297,7 +294,7 @@ private Texture parseTextureType(final VarType type, final String value) {
297294 for (final TextureOptionValue textureOptionValue : textureOptionValues ) {
298295 textureOptionValue .applyToTexture (texture );
299296 }
300- }
297+ }
301298 return texture ;
302299 }
303300
@@ -311,28 +308,28 @@ private Object readValue(final VarType type, final String value) throws IOExcept
311308 if (split .length != 1 ){
312309 throw new IOException ("Float value parameter must have 1 entry: " + value );
313310 }
314- return Float .parseFloat (split [0 ]);
311+ return Float .parseFloat (split [0 ]);
315312 case Vector2 :
316313 if (split .length != 2 ){
317314 throw new IOException ("Vector2 value parameter must have 2 entries: " + value );
318315 }
319316 return new Vector2f (Float .parseFloat (split [0 ]),
320- Float .parseFloat (split [1 ]));
317+ Float .parseFloat (split [1 ]));
321318 case Vector3 :
322319 if (split .length != 3 ){
323320 throw new IOException ("Vector3 value parameter must have 3 entries: " + value );
324321 }
325322 return new Vector3f (Float .parseFloat (split [0 ]),
326- Float .parseFloat (split [1 ]),
327- Float .parseFloat (split [2 ]));
323+ Float .parseFloat (split [1 ]),
324+ Float .parseFloat (split [2 ]));
328325 case Vector4 :
329326 if (split .length != 4 ){
330327 throw new IOException ("Vector4 value parameter must have 4 entries: " + value );
331328 }
332329 return new ColorRGBA (Float .parseFloat (split [0 ]),
333- Float .parseFloat (split [1 ]),
334- Float .parseFloat (split [2 ]),
335- Float .parseFloat (split [3 ]));
330+ Float .parseFloat (split [1 ]),
331+ Float .parseFloat (split [2 ]),
332+ Float .parseFloat (split [3 ]));
336333 case Int :
337334 if (split .length != 1 ){
338335 throw new IOException ("Int value parameter must have 1 entry: " + value );
@@ -536,12 +533,12 @@ private void readDefine(String statement) throws IOException{
536533 MatParam param = materialDef .getMaterialParam (paramName );
537534 if (param == null ) {
538535 logger .log (Level .WARNING , "In technique ''{0}'':\n "
539- + "Define ''{1}'' mapped to non-existent"
540- + " material parameter ''{2}'', ignoring." ,
536+ + "Define ''{1}'' mapped to non-existent"
537+ + " material parameter ''{2}'', ignoring." ,
541538 new Object []{technique .getName (), defineName , paramName });
542539 return ;
543540 }
544-
541+
545542 VarType paramType = param .getVarType ();
546543 technique .addShaderParamDefine (paramName , paramType , defineName );
547544 }else {
@@ -553,7 +550,6 @@ private void readDefines(List<Statement> defineList) throws IOException{
553550 for (Statement statement : defineList ){
554551 readDefine (statement .getLine ());
555552 }
556-
557553 }
558554
559555 private void readTechniqueStatement (Statement statement ) throws IOException {
@@ -600,12 +596,23 @@ private void readTechniqueStatement(Statement statement) throws IOException{
600596 }
601597 }
602598
603- private void readTransparentStatement (String statement ) throws IOException {
599+ private void readTransparentStatement (String statement ) throws IOException {
600+ boolean transparent = readBooleanStatement (statement , "Transparent" );
601+ material .setTransparent (transparent );
602+ }
603+
604+ private void readReceivesShadowsStatement (String statement ) throws IOException {
605+ boolean receivesShadows = readBooleanStatement (statement , "ReceivesShadows" );
606+ material .setReceivesShadows (receivesShadows );
607+ }
608+
609+ private boolean readBooleanStatement (String statement , String propertyName ) throws IOException {
604610 String [] split = statement .split (whitespacePattern );
605- if (split .length != 2 ){
606- throw new IOException ("Transparent statement syntax incorrect" );
611+ if (split .length != 2 ) {
612+ throw new IOException (propertyName + " statement syntax incorrect" );
607613 }
608- material .setTransparent (parseBoolean (split [1 ]));
614+
615+ return parseBoolean (split [1 ]);
609616 }
610617
611618 private static String createShaderPrologue (List <String > presetDefines ) {
@@ -665,7 +672,7 @@ private void readTechnique(Statement techStat) throws IOException{
665672
666673 if (isUseNodes ){
667674 //used for caching later, the shader here is not a file.
668-
675+
669676 // KIRILL 9/19/2015
670677 // Not sure if this is needed anymore, since shader caching
671678 // is now done by TechniqueDef.
@@ -722,9 +729,11 @@ private void loadFromRoot(List<Statement> roots) throws IOException{
722729 boolean extending = false ;
723730 Statement materialStat = roots .get (0 );
724731 String materialName = materialStat .getLine ();
732+
725733 if (materialName .startsWith ("MaterialDef" )){
726734 materialName = materialName .substring ("MaterialDef " .length ()).trim ();
727735 extending = false ;
736+
728737 }else if (materialName .startsWith ("Material" )){
729738 materialName = materialName .substring ("Material " .length ()).trim ();
730739 extending = true ;
@@ -753,7 +762,7 @@ private void loadFromRoot(List<Statement> roots) throws IOException{
753762 material = new Material (def );
754763 material .setKey (key );
755764 material .setName (split [0 ].trim ());
756- // material.setAssetName(fileName);
765+
757766 }else if (split .length == 1 ){
758767 if (extending ){
759768 throw new MatParseException ("Expected ':', got '{'" , materialStat );
@@ -765,24 +774,26 @@ private void loadFromRoot(List<Statement> roots) throws IOException{
765774 throw new MatParseException ("Cannot use colon in material name/path" , materialStat );
766775 }
767776
768- for (Statement statement : materialStat .getContents ()){
777+ for (Statement statement : materialStat .getContents ()) {
769778 split = statement .getLine ().split ("[ \\ {]" );
770779 String statType = split [0 ];
771- if (extending ){
772- if (statType .equals ("MaterialParameters" )){
780+ if (extending ) {
781+ if (statType .equals ("MaterialParameters" )) {
773782 readExtendingMaterialParams (statement .getContents ());
774- }else if (statType .equals ("AdditionalRenderState" )){
783+ } else if (statType .equals ("AdditionalRenderState" )) {
775784 readAdditionalRenderState (statement .getContents ());
776- }else if (statType .equals ("Transparent" )){
785+ } else if (statType .equals ("Transparent" )) {
777786 readTransparentStatement (statement .getLine ());
787+ } else if (statType .equals ("ReceivesShadows" )) {
788+ readReceivesShadowsStatement (statement .getLine ());
778789 }
779- }else {
780- if (statType .equals ("Technique" )){
790+ } else {
791+ if (statType .equals ("Technique" )) {
781792 readTechnique (statement );
782- }else if (statType .equals ("MaterialParameters" )){
793+ } else if (statType .equals ("MaterialParameters" )) {
783794 readMaterialParams (statement .getContents ());
784- }else {
785- throw new MatParseException ("Expected material statement, got '" + statType + "'" , statement );
795+ } else {
796+ throw new MatParseException ("Expected material statement, got '" + statType + "'" , statement );
786797 }
787798 }
788799 }
@@ -797,6 +808,7 @@ public Object load(AssetInfo info) throws IOException {
797808 key = info .getKey ();
798809 if (key .getExtension ().equals ("j3m" ) && !(key instanceof MaterialKey )) {
799810 throw new IOException ("Material instances must be loaded via MaterialKey" );
811+
800812 } else if (key .getExtension ().equals ("j3md" ) && key instanceof MaterialKey ) {
801813 throw new IOException ("Material definitions must be loaded via AssetKey" );
802814 }
@@ -968,4 +980,4 @@ public void applyToTexture(final Texture texture) {
968980 textureOption .applyToTexture (value , texture );
969981 }
970982 }
971- }
983+ }
0 commit comments