加入正常铁轨,测试隧道,隧道需要根据section再生成待修改
This commit is contained in:
parent
33442d2969
commit
b2f1bfae58
@ -86,7 +86,7 @@ export function Jlmap3ddata(mapid,scope){
|
||||
//初始化站台
|
||||
jlmap3ddata.stationstandlist = new StationStandList();
|
||||
jlmap3ddata.trainlisttest = new TrainListTest();
|
||||
LinkList(mapdata.linkList,scene);
|
||||
|
||||
assetloader.assetinit(scene)
|
||||
.then(function(data){
|
||||
//console.log(data);
|
||||
@ -106,6 +106,7 @@ export function Jlmap3ddata(mapid,scope){
|
||||
})
|
||||
.then(function(data){
|
||||
//console.log(data);
|
||||
LinkList(mapdata.linkList,scene,assetloader);
|
||||
loadingInstance.close();
|
||||
});
|
||||
//初始化信号
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
export function LinkList(data,scene){
|
||||
export function LinkList(data,scene,assetloader){
|
||||
|
||||
let groups = new THREE.Group();
|
||||
let linklist = [];
|
||||
@ -29,215 +29,270 @@ export function LinkList(data,scene){
|
||||
let linksgroup = new THREE.Group();
|
||||
linksgroup.name = "link";
|
||||
scene.add(linksgroup);
|
||||
console.log(linksgroup);
|
||||
|
||||
let suidaogroup = new THREE.Group();
|
||||
suidaogroup.name = "suidao";
|
||||
scene.add(suidaogroup);
|
||||
|
||||
linktest(data,scene);
|
||||
|
||||
|
||||
// return linklist;
|
||||
|
||||
function linktest(data,scene){
|
||||
let texture = new THREE.TextureLoader().load( '../../static/material/guidao/z025111.png' );
|
||||
texture.repeat.set(1,1);
|
||||
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
|
||||
// texture.repeat.x = 2000;
|
||||
let testmaterial = new THREE.MeshPhongMaterial( { map: texture } );
|
||||
function linktest(data,scene){
|
||||
console.log(assetloader.modellist);
|
||||
let autorail = null;
|
||||
let autosuidao = null;
|
||||
for(let i=0;i<assetloader.modellist.length;i++){
|
||||
if(assetloader.modellist[i].deviceType == "autorail"){
|
||||
autorail = assetloader.modellist[i].mesh.children[0];
|
||||
}
|
||||
if(assetloader.modellist[i].deviceType == "autosuidao"){
|
||||
autosuidao = assetloader.modellist[i].mesh.children[0];
|
||||
}
|
||||
}
|
||||
autosuidao.rotation.x = 0;
|
||||
let rightlist = [];
|
||||
let leftlist = [];
|
||||
let count = autorail.geometry.attributes.position.count;
|
||||
for(let i=0;i<count;i++){
|
||||
if(autorail.geometry.attributes.position.array[i*3] >0.49){
|
||||
rightlist.push(i);
|
||||
}
|
||||
if(autorail.geometry.attributes.position.array[i*3] <-0.49){
|
||||
leftlist.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
let testmesh1 = new THREE.Mesh( new THREE.PlaneBufferGeometry( 1, 4 ), testmaterial );
|
||||
testmesh1.rotation.x = - Math.PI / 2;
|
||||
autorail.rightlist = rightlist;
|
||||
autorail.leftlist = leftlist;
|
||||
|
||||
let reallinks = [];
|
||||
let testlink;
|
||||
testlink = data;
|
||||
if(data){
|
||||
let index,startdata;
|
||||
for(let n=0;n<data.length;n++){
|
||||
if(data[n].leftFdCode == undefined && data[n].leftSdCode == undefined && data[n].rightFdCode ){
|
||||
if(startdata){
|
||||
if(data[n].lp.x<startdata.lp.x){
|
||||
startdata = data[n];
|
||||
index = n;
|
||||
}
|
||||
}else{
|
||||
rightlist = [];
|
||||
leftlist = [];
|
||||
count = autosuidao.geometry.attributes.position.count;
|
||||
for(let i=0;i<count;i++){
|
||||
if(autosuidao.geometry.attributes.position.array[i*3] >0.49){
|
||||
rightlist.push(i);
|
||||
}
|
||||
if(autosuidao.geometry.attributes.position.array[i*3] <-0.49){
|
||||
leftlist.push(i);
|
||||
}
|
||||
}
|
||||
autosuidao.rightlist = rightlist;
|
||||
autosuidao.leftlist = leftlist;
|
||||
|
||||
console.log(autorail);
|
||||
console.log(autosuidao);
|
||||
|
||||
let reallinks = [];
|
||||
let testlink;
|
||||
testlink = data;
|
||||
if(data){
|
||||
let index,startdata;
|
||||
for(let n=0;n<data.length;n++){
|
||||
if(data[n].leftFdCode == undefined && data[n].leftSdCode == undefined && data[n].rightFdCode ){
|
||||
if(startdata){
|
||||
if(data[n].lp.x<startdata.lp.x){
|
||||
startdata = data[n];
|
||||
index = n;
|
||||
}
|
||||
|
||||
// n = data.length;
|
||||
}
|
||||
}
|
||||
buildmodel(startdata);
|
||||
reallinks.push(startdata);
|
||||
data.splice(index,1);
|
||||
|
||||
|
||||
for(let i=0;i<reallinks.length;i++){
|
||||
console.log(data.length);
|
||||
for(let j=0;j<data.length;j++){
|
||||
if(reallinks[i].leftFdCode && j>=0){
|
||||
if(reallinks[i].leftFdCode == data[j].code){
|
||||
buildmodel(data[j],reallinks[i],j,"left");
|
||||
reallinks.push(data[j]);
|
||||
data.splice(j,1);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
if(reallinks[i].leftSdCode && j>=0){
|
||||
|
||||
if(reallinks[i].leftSdCode == data[j].code){
|
||||
buildmodel(data[j],reallinks[i],j,"left");
|
||||
reallinks.push(data[j]);
|
||||
data.splice(j,1);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
if(reallinks[i].rightFdCode && j>=0){
|
||||
if(reallinks[i].rightFdCode == data[j].code){
|
||||
|
||||
buildmodel(data[j],reallinks[i],j,"right");
|
||||
reallinks.push(data[j]);
|
||||
data.splice(j,1);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
if(reallinks[i].rightSdCode && j>=0){
|
||||
if(reallinks[i].rightSdCode == data[j].code){
|
||||
buildmodel(data[j],reallinks[i],j,"right");
|
||||
reallinks.push(data[j]);
|
||||
data.splice(j,1);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function checklink(code,data){
|
||||
if(code == data.leftFdCode){
|
||||
|
||||
}
|
||||
if(code == data.leftSdCode){
|
||||
|
||||
}
|
||||
if(code == data.rightFdCode){
|
||||
|
||||
}
|
||||
if(code == data.rightSdCode){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function buildmodel(data,mdata,sx,direct){
|
||||
console.log("sa");
|
||||
let len = data.lengthFact;
|
||||
let testmesh2 = testmesh1.clone(true);
|
||||
let newgeometry = new THREE.PlaneBufferGeometry( 1, 4 );
|
||||
for(let j=0;j<testmesh2.geometry.attributes.position.array.length;j++){
|
||||
if(testmesh2.geometry.attributes.position.array[j]== 0.5){
|
||||
newgeometry.attributes.position.array[j] = len-10;
|
||||
}
|
||||
}
|
||||
newgeometry.attributes.uv.array[2] = len-10;
|
||||
|
||||
newgeometry.attributes.uv.array[6] = len-10;
|
||||
|
||||
newgeometry.attributes.position.needsUpdate = true;
|
||||
newgeometry.attributes.uv.needsUpdate = true;
|
||||
|
||||
testmesh2.geometry = newgeometry;
|
||||
testmesh2.geometry.computeBoundingBox();
|
||||
testmesh2.geometry.center();
|
||||
|
||||
testmesh2.material.needsUpdate = true;
|
||||
|
||||
// data.lp.y *= 10;
|
||||
// data.rp.y *= 10;
|
||||
|
||||
if(mdata){
|
||||
if(direct == "leftfd"){
|
||||
data.rp.x = mdata.lp.x;
|
||||
data.rp.y = mdata.lp.y;
|
||||
|
||||
data.lp.x = data.rp.x - data.lengthFact;
|
||||
data.lp.y = data.rp.y;
|
||||
testmesh2.position.x = (data.lp.x + data.rp.x)/2;
|
||||
testmesh2.position.z = (data.lp.y + data.rp.y)/2;
|
||||
}
|
||||
|
||||
if(direct == "rightfd"){
|
||||
data.lp.x = mdata.rp.x;
|
||||
data.lp.y = mdata.rp.y;
|
||||
|
||||
data.rp.x = data.lp.x + data.lengthFact;
|
||||
data.rp.y = data.lp.y;
|
||||
testmesh2.position.x = (data.lp.x + data.rp.x)/2;
|
||||
testmesh2.position.z = (data.lp.y + data.rp.y)/2;
|
||||
}
|
||||
|
||||
if(direct == "left"){
|
||||
let dx = Math.abs(data.lp.x - data.rp.x);
|
||||
let dy = Math.abs(data.lp.y - data.rp.y);
|
||||
let distance = Math.sqrt(Math.pow(dx,2)+Math.pow(dy,2));
|
||||
|
||||
data.lp.x = (data.lp.x-data.rp.x)*data.lengthFact/distance+mdata.lp.x;
|
||||
data.lp.y = (data.lp.y-data.rp.y)*data.lengthFact/distance+mdata.lp.y;
|
||||
|
||||
data.rp.x = mdata.lp.x;
|
||||
data.rp.y = mdata.lp.y;
|
||||
testmesh2.position.x = (data.rp.x + data.lp.x)/2;
|
||||
testmesh2.position.z = (data.rp.y + data.lp.y)/2;
|
||||
|
||||
let axix = new THREE.Vector3(1,0,0);
|
||||
let axixnow = new THREE.Vector3(data.rp.x-data.lp.x,0,data.rp.y-data.lp.y);
|
||||
let rotenum = axixnow.angleTo(axix);
|
||||
//不同坐标系方向值不同
|
||||
if(data.lp.y>data.rp.y){
|
||||
testmesh2.rotation.z = rotenum;
|
||||
}else {
|
||||
testmesh2.rotation.z = -rotenum;
|
||||
}
|
||||
}
|
||||
|
||||
if(direct == "right"){
|
||||
|
||||
let dx = Math.abs(data.lp.x - data.rp.x);
|
||||
let dy = Math.abs(data.lp.y - data.rp.y);
|
||||
let distance = Math.sqrt(Math.pow(dx,2)+Math.pow(dy,2));
|
||||
data.rp.x = (data.rp.x-data.lp.x)*data.lengthFact/distance+mdata.rp.x;
|
||||
data.rp.y = (data.rp.y-data.lp.y)*data.lengthFact/distance+mdata.rp.y;
|
||||
|
||||
data.lp.x = mdata.rp.x;
|
||||
data.lp.y = mdata.rp.y;
|
||||
testmesh2.position.x = (data.lp.x + data.rp.x)/2;
|
||||
testmesh2.position.z = (data.lp.y + data.rp.y)/2;
|
||||
|
||||
let axix = new THREE.Vector3(1,0,0);
|
||||
let axixnow = new THREE.Vector3(data.rp.x-data.lp.x,0,data.rp.y-data.lp.y);
|
||||
let rotenum = axixnow.angleTo(axix);
|
||||
//不同坐标系方向值不同
|
||||
if(data.lp.y>data.rp.y){
|
||||
testmesh2.rotation.z = rotenum;
|
||||
}else {
|
||||
testmesh2.rotation.z = -rotenum;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
data.lp.x = data.lp.x;
|
||||
data.rp.x = data.lp.x + data.lengthFact;
|
||||
startdata = data[n];
|
||||
index = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildmodel(startdata);
|
||||
reallinks.push(startdata);
|
||||
data.splice(index,1);
|
||||
|
||||
|
||||
for(let i=0;i<reallinks.length;i++){
|
||||
for(let j=0;j<data.length;j++){
|
||||
if(reallinks[i].leftFdCode && j>=0){
|
||||
if(reallinks[i].leftFdCode == data[j].code){
|
||||
buildmodel(data[j],reallinks[i],j,"left");
|
||||
reallinks.push(data[j]);
|
||||
data.splice(j,1);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
if(reallinks[i].leftSdCode && j>=0){
|
||||
|
||||
if(reallinks[i].leftSdCode == data[j].code){
|
||||
buildmodel(data[j],reallinks[i],j,"left");
|
||||
reallinks.push(data[j]);
|
||||
data.splice(j,1);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
if(reallinks[i].rightFdCode && j>=0){
|
||||
if(reallinks[i].rightFdCode == data[j].code){
|
||||
|
||||
buildmodel(data[j],reallinks[i],j,"right");
|
||||
reallinks.push(data[j]);
|
||||
data.splice(j,1);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
if(reallinks[i].rightSdCode && j>=0){
|
||||
if(reallinks[i].rightSdCode == data[j].code){
|
||||
buildmodel(data[j],reallinks[i],j,"right");
|
||||
reallinks.push(data[j]);
|
||||
data.splice(j,1);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function checklink(code,data){
|
||||
if(code == data.leftFdCode){
|
||||
|
||||
}
|
||||
if(code == data.leftSdCode){
|
||||
|
||||
}
|
||||
if(code == data.rightFdCode){
|
||||
|
||||
}
|
||||
if(code == data.rightSdCode){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function buildmodel(data,mdata,sx,direct){
|
||||
console.log(data);
|
||||
let len = data.lengthFact;
|
||||
// console.log(autorail);
|
||||
// console.log(autosuidao);
|
||||
|
||||
let testmesh2 = autorail.clone(true);
|
||||
|
||||
for(let i=0;i<autorail.rightlist.length;i++){
|
||||
testmesh2.geometry.attributes.position.array[autorail.rightlist[i]*3] = len-20;
|
||||
testmesh2.geometry.attributes.uv.array[autorail.rightlist[i]*2] = testmesh2.geometry.attributes.position.array[0]-testmesh2.geometry.attributes.position.array[3];
|
||||
}
|
||||
let newrail = new THREE.BufferGeometry();
|
||||
newrail.copy(testmesh2.geometry);
|
||||
testmesh2.geometry = newrail;
|
||||
testmesh2.geometry.attributes.position.needsUpdate = true;
|
||||
testmesh2.geometry.attributes.uv.needsUpdate = true;
|
||||
testmesh2.geometry.computeBoundingSphere();
|
||||
testmesh2.geometry.center();
|
||||
|
||||
let testmesh1 = autosuidao.clone(true);
|
||||
|
||||
for(let i=0;i<autosuidao.rightlist.length;i++){
|
||||
testmesh1.geometry.attributes.position.array[autosuidao.rightlist[i]*3] = len-20;
|
||||
testmesh1.geometry.attributes.uv.array[autosuidao.rightlist[i]*2] = (testmesh1.geometry.attributes.position.array[3]-testmesh1.geometry.attributes.position.array[0])/15.3;
|
||||
}
|
||||
let newsuidao = new THREE.BufferGeometry();
|
||||
newsuidao.copy(testmesh1.geometry);
|
||||
testmesh1.geometry = newsuidao;
|
||||
testmesh1.geometry.attributes.position.needsUpdate = true;
|
||||
testmesh1.geometry.attributes.uv.needsUpdate = true;
|
||||
testmesh1.geometry.computeBoundingSphere();
|
||||
testmesh1.geometry.center();
|
||||
|
||||
// testmesh2.add(testmesh1);
|
||||
// data.lp.y *= 10;
|
||||
// data.rp.y *= 10;
|
||||
|
||||
if(mdata){
|
||||
if(direct == "leftfd"){
|
||||
data.rp.x = mdata.lp.x;
|
||||
data.rp.y = mdata.lp.y;
|
||||
|
||||
data.lp.x = data.rp.x - data.lengthFact;
|
||||
data.lp.y = data.rp.y;
|
||||
testmesh2.position.x = (data.lp.x + data.rp.x)/2;
|
||||
testmesh2.position.z = (data.lp.y + data.rp.y)/2;
|
||||
}
|
||||
|
||||
if(direct == "rightfd"){
|
||||
data.lp.x = mdata.rp.x;
|
||||
data.lp.y = mdata.rp.y;
|
||||
|
||||
data.rp.x = data.lp.x + data.lengthFact;
|
||||
data.rp.y = data.lp.y;
|
||||
testmesh2.position.x = (data.lp.x + data.rp.x)/2;
|
||||
testmesh2.position.z = (data.lp.y + data.rp.y)/2;
|
||||
}
|
||||
|
||||
if(direct == "left"){
|
||||
let dx = Math.abs(data.lp.x - data.rp.x);
|
||||
let dy = Math.abs(data.lp.y - data.rp.y);
|
||||
let distance = Math.sqrt(Math.pow(dx,2)+Math.pow(dy,2));
|
||||
|
||||
data.lp.x = (data.lp.x-data.rp.x)*data.lengthFact/distance+mdata.lp.x;
|
||||
data.lp.y = (data.lp.y-data.rp.y)*data.lengthFact/distance+mdata.lp.y;
|
||||
|
||||
data.rp.x = mdata.lp.x;
|
||||
data.rp.y = mdata.lp.y;
|
||||
testmesh2.position.x = (data.rp.x + data.lp.x)/2;
|
||||
testmesh2.position.z = (data.rp.y + data.lp.y)/2;
|
||||
|
||||
let axix = new THREE.Vector3(1,0,0);
|
||||
let axixnow = new THREE.Vector3(data.rp.x-data.lp.x,0,data.rp.y-data.lp.y);
|
||||
let rotenum = axixnow.angleTo(axix);
|
||||
//不同坐标系方向值不同
|
||||
if(data.lp.y>data.rp.y){
|
||||
testmesh2.rotation.z = rotenum;
|
||||
}else {
|
||||
testmesh2.rotation.z = -rotenum;
|
||||
}
|
||||
}
|
||||
|
||||
if(direct == "right"){
|
||||
|
||||
let dx = Math.abs(data.lp.x - data.rp.x);
|
||||
let dy = Math.abs(data.lp.y - data.rp.y);
|
||||
let distance = Math.sqrt(Math.pow(dx,2)+Math.pow(dy,2));
|
||||
data.rp.x = (data.rp.x-data.lp.x)*data.lengthFact/distance+mdata.rp.x;
|
||||
data.rp.y = (data.rp.y-data.lp.y)*data.lengthFact/distance+mdata.rp.y;
|
||||
|
||||
data.lp.x = mdata.rp.x;
|
||||
data.lp.y = mdata.rp.y;
|
||||
testmesh2.position.x = (data.lp.x + data.rp.x)/2;
|
||||
testmesh2.position.z = (data.lp.y + data.rp.y)/2;
|
||||
|
||||
let axix = new THREE.Vector3(1,0,0);
|
||||
let axixnow = new THREE.Vector3(data.rp.x-data.lp.x,0,data.rp.y-data.lp.y);
|
||||
let rotenum = axixnow.angleTo(axix);
|
||||
//不同坐标系方向值不同
|
||||
if(data.lp.y>data.rp.y){
|
||||
testmesh2.rotation.z = rotenum;
|
||||
}else {
|
||||
testmesh2.rotation.z = -rotenum;
|
||||
}
|
||||
|
||||
}
|
||||
testmesh2.position.y = 10;
|
||||
testmesh2.code = data.code;
|
||||
var box = new THREE.BoxHelper( testmesh2, 0xff0000 );
|
||||
scene.add( box );
|
||||
linksgroup.add( testmesh2 );
|
||||
|
||||
}else{
|
||||
data.lp.x = data.lp.x;
|
||||
data.rp.x = data.lp.x + data.lengthFact;
|
||||
|
||||
testmesh2.position.x = (data.lp.x + data.rp.x)/2;
|
||||
testmesh2.position.z = (data.lp.y + data.rp.y)/2;
|
||||
|
||||
}
|
||||
|
||||
// testmesh2.position.y = 10;
|
||||
testmesh2.code = data.code;
|
||||
testmesh1.position.x = testmesh2.position.x;
|
||||
testmesh1.position.z = testmesh2.position.z;
|
||||
testmesh1.rotation.x = -Math.PI/2;
|
||||
testmesh1.rotation.z = testmesh2.rotation.z;
|
||||
var box = new THREE.BoxHelper( testmesh2, 0xff0000 );
|
||||
scene.add( box );
|
||||
suidaogroup.add( testmesh1 );
|
||||
linksgroup.add( testmesh2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,9 +60,23 @@ let defaultsuidao = {
|
||||
}//https://joylink.club/oss/models/suidao/suidao.FBX
|
||||
//../../static/model/
|
||||
|
||||
let defaultautorail = {
|
||||
id:"100",
|
||||
name:"autorail",
|
||||
deviceType:"autorail",
|
||||
type:"autorail",
|
||||
picUrl:"",
|
||||
assetUrl:"../../static/model/auto/rail.FBX"
|
||||
}
|
||||
|
||||
|
||||
|
||||
let defaultautosuidao = {
|
||||
id:"101",
|
||||
name:"autosuidao",
|
||||
deviceType:"autosuidao",
|
||||
type:"autosuidao",
|
||||
picUrl:"",
|
||||
assetUrl:"../../static/model/auto/suidao.FBX"
|
||||
}
|
||||
|
||||
export function AssetLoader(){
|
||||
|
||||
@ -95,6 +109,9 @@ export function AssetLoader(){
|
||||
scope.modellist.push(suidao);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
let modeldata = JSON.parse(data);
|
||||
|
||||
for(let j=0;j<modeldata.length;j++){
|
||||
@ -151,6 +168,12 @@ export function AssetLoader(){
|
||||
let station = new AssetModel(defaultstation);
|
||||
scope.modellist.push(station);
|
||||
|
||||
let autorail = new AssetModel(defaultautorail);
|
||||
scope.modellist.push(autorail);
|
||||
|
||||
let autosuidao = new AssetModel(defaultautosuidao);
|
||||
scope.modellist.push(autosuidao);
|
||||
|
||||
fbxpromise(signal)
|
||||
.then(function(data){
|
||||
////console.log(data);
|
||||
@ -160,6 +183,14 @@ export function AssetLoader(){
|
||||
////console.log(data);
|
||||
return fbxpromise(station);
|
||||
})
|
||||
.then(function(data){
|
||||
////console.log(data);
|
||||
return fbxpromise(autorail);
|
||||
})
|
||||
.then(function(data){
|
||||
////console.log(data);
|
||||
return fbxpromise(autosuidao);
|
||||
})
|
||||
.then(function(data){
|
||||
////console.log(scope.modellist);
|
||||
resolve("loaderassets");
|
||||
@ -381,10 +412,10 @@ export function AssetLoader(){
|
||||
var loader = new THREE.FBXLoader();
|
||||
loader.load( asset.assetUrl, function ( object ) {
|
||||
let mixer = new THREE.AnimationMixer( object );
|
||||
object.traverse(function (node) {//获取其中对象
|
||||
node.frustumCulled = true;
|
||||
|
||||
});
|
||||
// object.traverse(function (node) {//获取其中对象
|
||||
// node.frustumCulled = true;
|
||||
//
|
||||
// });
|
||||
|
||||
|
||||
if(asset.deviceType == "train"){
|
||||
|
BIN
static/model/auto/rail.FBX
Normal file
BIN
static/model/auto/rail.FBX
Normal file
Binary file not shown.
BIN
static/model/auto/suidao.FBX
Normal file
BIN
static/model/auto/suidao.FBX
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user