8 Replies Latest reply on Jul 16, 2006 9:47 PM by WrongAgain

    How to stick texture to a mesh object?

    WrongAgain Level 1

      I write an instance by my comprehension. But it seems not right at all. It didn't work. My instance is in
      http://www.gzvr.com/test/MeshProblem/testMesh.htm
      The code of the button is:

      on mouseUp me
      --below is code in subject "newMesh" in Director Help
      nm = member("scene").newMesh("pyramid",6 , 5, 0, 3)
      nm.vertexList = [ vector(0,0,0), vector(40,0,0), vector(40,0,40), vector(0,0,40), vector(20,50,20) ]
      nm.colorList = [ rgb(255,0,0), rgb(0,255,0), rgb(0,0,255) ]
      nm.face[1].vertices = [ 4,1,2 ]
      nm.face[2].vertices = [ 4,2,3 ]
      nm.face[3].vertices = [ 5,2,1 ]
      nm.face[4].vertices = [ 5,3,2 ]
      nm.face[5].vertices = [ 5,4,3 ]
      nm.face[6].vertices = [ 5,1,4 ]
      nm.face[1].colors = [3,2,3]
      nm.face[2].colors = [3,3,2]
      nm.face[3].colors = [1,3,2]
      nm.face[4].colors = [1,2,3]
      nm.face[5].colors = [1,3,2]
      nm.face[6].colors = [1,2,3]
      nm.generateNormals(#flat)
      nm.build()
      nm = member("scene").newModel("Pyramid1", nm)

      --below is my code. I write it by my comprehension. It didn't work.
      member("scene").newtexture("map",#fromcastmember,member("myTexture"))
      member("scene").newshader("myShader", #standard)
      member("scene").shader("myShader").texture = member("scene").texture("map")
      repeat with i = 1 to nm.shaderList.count
      nm.shaderList = member("scene").shader("myShader")
      end repeat
      end

      Note that there is no picture having been sticked on the mesh model. It seems there is colorful pattern on it because different vertex has been set different color. My texture picture is
      http://www.gzvr.com/test/MeshProblem/StraightArrowTest.png

        • 1. Re: How to stick texture to a mesh object?
          a¿ex Level 1
          hello wrongagain

          vertex colors override any shader settings including the texture of a shader.
          it's an "either or" type of thing, you can't use both at the same time.

          omit the colorlist, when creating the mesh and use 0 for the number of colors and you'll see the shader.

          but still you won't see the texture on your model, as all texture coords are set to point(0,0).
          either define proper texture coordinates for each vertex or use a #texturemodelist[<indexOfYourTexture>] <> #none (e.g. #wrapplanar), which will automatically generate texture coordinates according to the texturemodelist setting.

          on a sidenote:
          there's a little quirk in the repeat loop to set the shaderlist:

          repeat with i = 1 to nm.shaderList.count
          nm.shaderList = member("scene").shader("myShader")
          end repeat


          first of all a code design hint:
          you should never "repeat to" an expression (-> the last value of your repeat with i = first to last), as it gets evaluated on each iteration. so on each iteration the count of the shaderlist of model nm is evaluated. not a biggie, but still costs cycles.
          two options here:

          cnt = nm.shaderList.count
          repeat with i = 1 to cnt
          ...

          or, if the ordering doesn't matter (most of the cases):

          repeat with i = nm.shaderList.count down to 1
          ...

          the second case looks very similar to the "wrong case", BUT the start parameter of a loop must only be evaluated once, when the loop starts, for obvious reasons.

          so option 2 is the best, as you even save the creation of the variable cnt :-)

          but there is another error in your repeat loop:

          setting the shaderlist property of a model IS already a shortcut to set ALL shaders of the model at once.

          so:
          nm.shaderList = member("scene").shader("myShader")

          would have been enough in your case.
          doing it in a repeat loop would have looked like:

          repeat with i = nm.shaderList.count down to 1
          nm.shaderList = member("scene").shader("myShader")
          end repeat


          still you would waste cycles, as you dereference the member AND the shader of the member in each iteration. (referencing a member by name can slow down the performance noticeably especially, if you have lots of members)
          so you should store results, which you reuse more than once in local variables:

          mem = member("scene")
          mem.newtexture("map",#fromcastmember,member("myTexture"))
          mem.newshader("myShader", #standard)
          mem.shader("myShader").texture = mem.texture("map")

          shd = mem.shader("myShader")
          repeat with i = nm.shaderList.count down to 1
          nm.shaderList
          = shd
          end repeat



          which saved you a bunch of member("scene")'s


          HTH
          • 2. Re: How to stick texture to a mesh object?
            WrongAgain Level 1
            but still you won't see the texture on your model, as all texture coords are set to point(0,0).
            either define proper texture coordinates for each vertex or use a #texturemodelist[<indexOfYourTexture>] <> #none (e.g. #wrapplanar), which will automatically generate texture coordinates according to the texturemodelist setting.
            ----------------------------------------------------------------
            In fact, what I want to know is how to set the texture coordinates. In my comprehension, it should be:

            nm.textureCoordinateList = [[0,0],[1,0],[1,1],[1,0],[0.5,0.5]]

            I want the bottom of the pyramid is exactly my texture picture. I think there is five vertexes so there should be five items in list. I don't know if it is right. But it didn't work yet.


            Add the sentence above to my code. And according your advice, I modified the code, as follow:

            on mouseUp me
            --below is code in subject "newMesh" in Director Help
            nm = member("scene").newMesh("pyramid",6 , 5, 0, 0, 5)
            nm.vertexList = [ vector(0,0,0), vector(40,0,0), vector(40,0,40), vector(0,0,40), vector(20,50,20) ]
            nm.face[1].vertices = [ 4,1,2 ]
            nm.face[2].vertices = [ 4,2,3 ]
            nm.face[3].vertices = [ 5,2,1 ]
            nm.face[4].vertices = [ 5,3,2 ]
            nm.face[5].vertices = [ 5,4,3 ]
            nm.face[6].vertices = [ 5,1,4 ]
            nm.generateNormals(#flat)
            nm.textureCoordinateList = [[0,0],[1,0],[1,1],[1,0],[0.5,0.5]] <------Add this
            nm.build()
            nm = member("scene").newModel("Pyramid1", nm)

            --below is my code. I write it by my comprehension. It didn't work.
            p_scene = member("scene")
            p_scene.newtexture("map",#fromcastmember,member("myTexture"))
            p_scene.newshader("myShader", #standard)
            p_scene.shader("myShader").texture = p_scene.texture("map")
            nm.shaderList = member("scene").shader("myShader")
            end


            But the texture didn't display correctly yet. Where is wrong in my code?



            • 3. Re: How to stick texture to a mesh object?
              a¿ex Level 1
              you need to assign the texture coordinates to the faces also.
              not only the vertices, something like:



              nm = member("scene").newMesh("pyramid",6 , 5, 0, 0, 5)
              nm.vertexList = [ vector(0,0,0), vector(40,0,0), vector(40,0,40), vector(0,0,40), vector(20,50,20) ]
              nm.textureCoordinateList = [[0,0],[1,0],[1,1],[0,1],[0.5,1]]

              nm.face[1].vertices = [ 4,1,2 ]
              nm.face[1].texcoords = [ 1,2,3 ]

              nm.face[2].vertices = [ 4,2,3 ]
              nm.face[2].texcoords = [ 1,3,4 ]


              nm.face[3].vertices = [ 5,2,1 ]
              nm.face[3].texcoords = [ 5,1,2 ]

              nm.face[4].vertices = [ 5,3,2 ]
              nm.face[4].texcoords = [ 5,1,2 ]

              nm.face[5].vertices = [ 5,4,3 ]
              nm.face[5].texcoords = [ 5,1,2 ]

              nm.face[6].vertices = [ 5,1,4 ]
              nm.face[6].texcoords = [ 5,1,2 ]

              nm.generateNormals(#flat)

              nm.build()
              nm = member("scene").newModel("Pyramid1", nm)

              --below is my code. I write it by my comprehension. It didn't work.
              p_scene = member("scene")
              p_scene.newtexture("map",#fromcastmember,member("myTexture"))
              p_scene.newshader("myShader", #standard)
              p_scene.shader("myShader").texture = p_scene.texture("map")
              nm.shaderList = member("scene").shader("myShader")



              I don't know how you want to map the texture on the triangle faces.
              something like the above should work.
              • 4. Re: How to stick texture to a mesh object?
                WrongAgain Level 1
                Yes your code do work, thanks. And:


                I don't know how you want to map the texture on the triangle faces.
                something like the above should work.
                --------------------------------------------------------------
                It's my first time to use lingo to stick texture. I have no experience about it. I read the Help and write code by my imagination.
                What I want to do is only to create an object and stick texture on it. Textures on object should not be distorted. Is there any method more simply or more usual?
                • 5. Re: How to stick texture to a mesh object?
                  a¿ex Level 1
                  no, you are prett ymuch on your own, as soon as the objects you want to create can't be created with the few built-in primitives, you must "make your hands dirty".
                  the whole shockwave3d is more intended to be a "playback" engine to deal with 3-D data created in a 3-D package, which offer an user interface to the "low level" stiff you can do by code with sw3d.
                  Nonetheless the fact that we CAN do the low level stuff like this "by hand" sets sw3d apart and I really appreciate that, as it allows for very small filesizes with truely dynamic apps, which generate the content at runtime on demand.

                  If on the other hand, I would an easier way to create a pyramid and map a texture onto the faces with full control over the mapping mode, I can always use one of many 3-D packages, that export to w3d format and create the content faster than programming it from scratch.

                  It depends on the needs, the project, the timeline, the payment etc.
                  I always tend to the "programming route", if possible (at least for such easy objects as your pyramid is),

                  as for the texture mapping: in some cases you don't need to mess around with texture coordinates and can simply use one of the the #texturelistmode setting, like #wrapplanar.

                  • 6. Re: How to stick texture to a mesh object?
                    WrongAgain Level 1
                    My project is a dynamic app, so the first response in my mind was to create the objects dynamically. But now I think about it, find the objects also can be built in 3-D packages previously. It will be OK as long as making appropriate transformations on them before use. :-)


                    As for #wrapplanar, I had ever tried it, but it can not give me what I want. When using #wrapplanar, the texture became strange bars. Look:
                    http://www.gzvr.com/test/MeshProblem/testMesh1.htm
                    It seems the texture projective direction is not right. I don’t know how to control the projective direction.
                    The code of above (using #wrapplanar) is as follow:

                    on mouseUp me
                    nm = member("scene").newMesh("pyramid",6 , 5, 0, 0, 0)
                    nm.vertexList = [ vector(0,0,0), vector(40,0,0), vector(40,0,40), vector(0,0,40), vector(20,50,20) ]
                    nm.face[1].vertices = [ 4,1,2 ]
                    nm.face[2].vertices = [ 4,2,3 ]
                    nm.face[3].vertices = [ 5,2,1 ]
                    nm.face[4].vertices = [ 5,3,2 ]
                    nm.face[5].vertices = [ 5,4,3 ]
                    nm.face[6].vertices = [ 5,1,4 ]
                    nm.generateNormals(#flat)
                    nm.build()
                    nm = member("scene").newModel("Pyramid1", nm)

                    p_scene = member("scene")
                    p_scene.newtexture("map",#fromcastmember,member("myTexture"))
                    myShader = p_scene.newshader("myShader", #standard)
                    myShader.texture = p_scene.texture("map")
                    myShader.textureMode = #wrapPlanar -- ß----------here, use #wrapPlanar
                    nm.shaderList = member("scene").shader("myShader")
                    end
                    • 7. Re: How to stick texture to a mesh object?
                      a¿ex Level 1
                      the wraptransformlist of the shader controls how the wrapplanar is mapped onto the model.
                      get yourself the 3DPI ( http://www.3DPI-director.com) in order to INSPECT and explore all these PROPERTIES.
                      :-)
                      indispensable tool, when it comes to 3-D in director.
                      • 8. Re: How to stick texture to a mesh object?
                        WrongAgain Level 1
                        I got it.
                        Thanks for your patience! I leant much from here. :-)