Ambiera Forum

Discussions, Help and Support.

Ambiera Forum > CopperCube > Programming and Scripting
load model 3d external

bobby
Guest
Quote
2022-01-03 15:35:41

hello everyone, I ask for your help please.
I've been hanging out on the forum for days and looking for a script to help me load a 3d model outside the game and put it inside the game. can you help me please thank you very much


just_in_case
Moderator
Quote
2022-01-04 11:35:45

Unfortunately No, you can't load 3D models during runtime of the game, but you can add them in the editor via scripting with the help of command-line tools that require Studio version of coppercube.
But if you were planning to import them in the client game, then sorry right now there is no such feature in CC afaik, maybe someday we will be able to load them during runtime.


csp-games
Guest
Quote
2022-01-08 10:17:08

You can use copperlicht code in the behavior scripts etc. I would write a mesh loader function and include it as an additional script in the html head section (talking about webGL target only), right after the include of copperlichtdata/copperlicht.js

Here's an example for constructing a mesh based on the data held in some arrays:

// helper function for quickly creating a 3d vertex from 3d position and texture coodinates
createVertex = function(x, y, z, s, t,s2,t2)
{
var vtx = new CL3D.Vertex3D(true);
vtx.Pos.X = x;
vtx.Pos.Y = y;
vtx.Pos.Z = z;
vtx.TCoords.X = s;
vtx.TCoords.Y = t;
vtx.TCoords2.X = s2;
vtx.TCoords2.Y = t2;
return vtx;
}


// our own scene node implementation, lightmapped
MySceneNode = function(engine)
{
this.init(); // init scene node specific members


// create a 3d mesh with n=surfs mesh buffers / materials
buf=new Array();
this.MyMesh = new CL3D.Mesh();
for(i=1;i<=surfs;i++){
buf[i] = new CL3D.MeshBuffer();
this.MyMesh.AddMeshBuffer(buf[i]);

// set indices and vertices

// triangle vertex index lists in inde[i]
for(j=0;j<nverts[i]*3;j+=3){
buf[i].Indices.push( inde[i][j],inde[i][j+1],inde[i][j+2] );
}//j

// vertex data in arrays buf[i] is x,y,z,u,v,u2,v2 (7 values)
for(j=0;j<nverts[i]*7;j+=7){
buf[i].Vertices.push(createVertex( vert[i][j], vert[i][j+1], vert[i][j+2], vert[i][j+3], vert[i][j+4], vert[i][j+5], vert[i][j+6]) );
}//j

// set the textures of the materials

buf[i].Mat.Tex1 = engine.getTextureManager().getTexture(txx1[i], true);
buf[i].Mat.Tex2 = engine.getTextureManager().getTexture(txx2[i], true);
buf[i].Mat.Type = CL3D.Material.EMT_LIGHTMAP;
}//i




csp-games
Guest
Quote
2022-01-08 10:20:15

oops, by:

// vertex data in arrays buf[i] is x,y,z,u,v,u2,v2 (7 values)

i meant

// vertex data in arrays vert[i] is x,y,z,u,v,u2,v2 (7 values)


just_in_case
Moderator
Quote
2022-01-08 12:06:12

@CSP , thanks for the mesh loader script. There is lot of possibilities with the WebGL target. I wish if there were more possibilities for the windows client too. Like i have seen your Ascii shader thing, and we can configure key input, can also use controller support and extend the physics engine.

But when it comes to windows client there are many limitation. I really want the feature to apply shader to the whole screen but We can't apply shader to screen space in windows. It only allows us to use a scenenode with material to apply shader.

@bobby my answer above was with regard to windows target. For webgl you can always use third party libraries or use the mesh loader script provided by @CSP-GAMES above.


csp-games
Guest
Quote
2022-01-09 03:16:15

That's indeed one of the pros of WebGL targets, the ability to inject code in various ways. But I use copperlicht mainly because I want to produce for WebGL, I think it is its strength. It comes close to Unity, which has a market value of 3 billions, but is much less of a bloatware. We all have seen those 100MB+ tictactoes made with unity.

Anyway, re mesh loader, my above code takes the data from some arrays. Heres some code that can load a file from an url, including the files in the folder in which the game runs on a server. Not sure about cross-origin, just try it.

function myReadFile(mypath)
// reads a file from a URL into an array, then splits it up into an array of lines
// please note, the data processing is not executed right in the function call, but later, once the file was loaded.
// To access the data, you have to check whether it is actually loaded, eg. by setting a global variable to 1.
{
fetch(mypath)
.then(response => response.text())
.then( data => {
// here we can process the data
alert(data);
alert(data.length);
const mydata=data.split("\n"); // split at linebreaks
alert(mydata[0]); // show 1st line
myfile_is_loaded=1; // global
} );
}


In case you want to let the user choose a file, you can use:


function readFileC () {
// (A) GET SELECTED FILE from a <input type="file" value="Choose File" id="demoPickC" o-n-c-h-a-n-g-e="readFileC()"/>

let selected = document.getElementById("demoPickC").files[0];

// (B) READ SELECTED FILE
let reader = new FileReader();
reader.addEventListener("load", () => {
var bindata = reader.result;
//console.log(bindata);
alert(bindata); // here again, the data is not available immediately
});
reader.readAsBinaryString(selected);
}




csp-games
Guest
Quote
2022-01-09 10:29:54

So, to conclude with this, now we have the file loader and the mesh reconstructor, all that is still required is to parse the loaded file and prepare the data for the reconstructor. But be aware, you need to know how to parse and extract data from strings in javascript, using at least .indexOf() and .substr().

However, a good mesh loader isn't so easy, depending on the format. For instance an OBJ file may look as simple as this:


List of geometric vertices, with (x, y, z [,w]) coordinates, w is optional and defaults to 1.0.
v -0.5 -0.5 -0.5
v 0.5 -0.5 -0.5
v -0.5 -0.5 0.5
v 0.5 -0.5 0.5
List of texture coordinates, in (u, [,v ,w]) coordinates, these will vary between 0 and 1. v, w are optional and default to 0.
vt 0.0 0.0
vt 1.0 0.0
vt 0.0 1.0
vt 1.0 1.0
define the following as group (or surface) and assign material
g object
mtlib my_mtl.mtl
usemtl mytex
Polygonal face element (see below)
f 1/1 2/2 3/3
f 2/2 4/4 3/3
end of file

each v line is a vertex 3D coordinate. vt lines are the UV sets (where a vertex is on the texture, 0 to 1, or, where for example 4 would repeat/tile the texture 4x). referencing a MTL file allows to name texture files for the following object.
Then follow the triangles as a list of indicies, pointing to a vertex defined earlier, and also to a UV set, but that's usually the same. So this file is a simple quad made out of 2 triangles.

It's easy to write a mesh exporter for such a simple format in an other app that can load meshes and write files, I use Blitz3D for that, and it's also easy to load that mesh in copperlicht, as explained above. However, the OBJ file format has much more options, some of which other exporters may use (for example faces f can have more than 3 vertices, being actually polygons). So your mesh loader may work for meshes that you exported with your own, compatible code, or with some luck also for existing OBJ files from nebulous sources, but definitily not for ANY OBJ file. For further info search "obj file format" at duckduckgo.com, esp. about the MTL file format too.


csp-games
Guest
Quote
2022-01-09 10:41:42

Note: the forum has again messed up some code, it removes all the characters with code 35, you know, these:


X X
XXXXX
X X
XXXXX
X X


They are used in the OBJ format to define remarks, so every line that explains something in human language, should have such a sign at the line start.

Is it getting ridicules? ^^


csp-games
Guest
Quote
2022-01-09 11:35:39

Just some further thoughts on loading files dynamically:

As per se javascript loads files as parallel threads, meaning you say "load!, it starts an independent task that loads the file, but doesn't wait until loading is complete, but just keeps on executing the next line, it may be a good idea to simulate a non-multi-thread loading behavior as we know it from simple native programming in EXEs etc.

So we can just go into a loop after the load command, that waits until a certain global variable is set to one. But you can't just use a loop that does nothing else,like
while(my_file_is_loaded==0) {}
because browsers recognize this as faulty code and may prevent execution. However, if you add some code, for instance a "loading.." progress graphics effect, it may be feasible to the browser and you get a program pause until the file is loaded, and you can then use it right away.

More elegant than a while() loop would be to call a thread on a timeout, that keeps on calling itself on a timeout, until the file is loaded, however the original calling function - your apps' main loop maybe - will not remember the values of anything non-global when you just call it.


function my_mainthread(){
// ...
myLoadFile("test.obj");
i_m_waiting();
// ...
renn=self.setTimeout('my_mainthread()',"33");
}

function i_m_waiting(){
if(my_file_is_loaded==0){
renn=self.setTimeout('i_m_waiting()',"33"); // 33=30 hz, 17=60hz ...
}
else{
renn=self.setTimeout('my_mainthread()',"33");
}
}

But when the waiting thread branches back to the main thread, it won't continue after the load call, so my simple solution is to just use a lot of globals and global arrays. Some may say it's bad practice, but I don't see why, it's extremly robust and flexible, given the used names are pre-fixed uniquely, like for instance: var csp__x=0;


csp-games
Guest
Quote
2022-01-09 11:51:06

And yet one more thing important:
In case the file cannot be loaded, esp. over the web, you may want to check the elapsed time and offer an option to abort or skip loading, or keep on waiting for the file. There are also certain ways to catch server error responses like 404... as response methods, look it up.


Create reply:


Posted by: (you are not logged in)


Enter the missing letter in: "Interna?ional" (you are not logged in)


Text:

 

  

Possible Codes


Feature Code
Link [url] www.example.com [/url]
Bold [b]bold text[/b]
Image [img]http://www.example.com/image.jpg[/img]
Quote [quote]quoted text[/quote]
Code [code]source code[/code]

Emoticons


   






Copyright© Ambiera e.U. all rights reserved.
Privacy Policy | Terms and Conditions | Imprint | Contact