모델 정보(Web)
업데이트: 2019/11/07
모델 정보 편집에 대하여
모델 정보는 기본적으로 Modeler에서 생성됩니다.
파라미터에 대한 정점 등의 움직임은 .moc3 파일에 기록됩니다.
그 외의 물리 연산이나 아트메쉬에 붙일 수 있는 유저 데이터 등은 다른 파일로서 출력되는데,
모델에 대한 모든 파일 참조를 기록하는 것이 .model3.json 파일입니다.
Modeler에서 .moc3 파일을 출력할 때 동시에 출력할 수 있습니다. 「임베디드용 데이터 내보내기」
또한 Cubism Viewer (for OW)를 사용하여 모션, 표정 파일, 포즈 파일의 임베디드 설정을 추가할 수 있습니다.
Framework를 사용하여 .model3.json 파일에서 로드
Framework를 이용한 로드에서는 모델에 필요한 정보를 .model3.json 파일에서 추출하고,
CubismUserModel 클래스를 상속한 인스턴스를 정비하고 이용하는 것을 상정하고 있습니다.
// TypeScript const dir: string = "example/"; const fileName: string = "example.model3.json"; const path: string = dir + fileName; fetch(path).then( (response) => { return response.arrayBuffer(); } ).then( (arrayBuffer) => { let buffer: ArrayBuffer = arrayBuffer; let size = buffer.byteLength; let setting: ICubismModelSetting = new CubismModelSettingJson(buffer, size); deleteBuffer(buffer, path); // 생략 }
ICubismModelSetting 클래스로 추출한 각 요소는 CubismUserModel.load~~ 계열 함수로 로드할 수 있습니다.
// TypeScript // buffer는 .model3.json의 ArrayBuffer this.loadModel(buffer);
.model3.json 파일의 전체 로드 흐름은 샘플의 LAppModel.loadAssets 함수에서
LAppModel.setupModel 함수, CubismUserModel.createRenderer 함수, LAppModel.setupTextures 함수의 흐름을 따라가면 파악하기 쉽습니다.
인스턴스 생성(.moc3 파일 로드)
먼저 .moc3 파일을 메모리에 로드합니다.
읽은 버퍼와 크기를 CubismMoc.create 함수에 전달하고 먼저 CubismMoc 인스턴스를 만듭니다.
그런 다음 CubismMoc.createModel 함수를 호출하여 CubismModel 인스턴스를 만듭니다.
이 CubismModel 인스턴스로부터 파라미터의 조작이나 draw를 위한 정보 취득 등을 실시합니다.
// TypeScript // buffer 는 .moc3 의 ArrayBuffer this._moc = CubismMoc.create(buffer); this._model = this._moc.createModel();
그래픽 환경 연결
Framework는 모델의 텍스쳐 정보를 그래픽 API에 의존하지 않기 위해 CubismRenderer 클래스의 파생 클래스를 사용합니다.
모델과 관련된 그래픽 관련 정보는 모두 CubismRenderer 클래스의 파생 클래스에서 관리합니다.
CubismRenderer 클래스에서 그래픽 API에 대한 파생 클래스를 생성하고,
CubismRenderer_WebGL.initialize 함수로 CubismModel 인스턴스를 등록하면 CubismRenderer 인스턴스와 CubismModel 인스턴스가 연결됩니다.
// TypeScript let renderer: CubismRenderer_WebGL = new CubismRenderer_WebGL(); renderer.initialize(model);
텍스쳐 연결
Framework에서 모델이 가지는 텍스쳐는 CubismRenderer 클래스의 파생 클래스가 관리합니다.
그러나 그 기능은 그래픽 API에 대한 의존을 피하기 위해 CubismRenderer 클래스에 그 메소드의 등록은 되어 있지 않습니다.
대상으로 하는 그래픽스 API에 따라 메소드의 스펙 변화에 주의해 주세요.
WebGL 처리는 CubismRenderer 클래스의 파생 CubismRenderer_WebGL 클래스 내의 CubismRenderer_WebGL.bindTexture 함수를 사용하여 등록합니다.
첫 번째 인수는 모델의 텍스쳐 번호, Editor에서는 텍스쳐 아틀라스의 번호로 확인할 수 있습니다.
두 번째 인수는 텍스쳐의 WebGL에서의 관리 번호입니다.
아래 예제는 WebGL에서의 텍스쳐 불러오기입니다.
// TypeScript // WebGL 텍스쳐 유닛에 텍스쳐 로드 let texturePath = this._modelSetting.getTextureFileName(modelTextureNumber); texturePath = this._modelHomeDir + texturePath; img[modelTextureNumber] = new Image(); img[modelTextureNumber].onload = () => { // 텍스쳐 오브젝트 생성 let tex: WebGLTexture = gl.createTexture(); // 텍스쳐 선택 gl.bindTexture(gl.TEXTURE_2D, tex); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); // Premult 처리 수행시키기 if(usePremultiply) { gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1); } // 텍스쳐에 픽셀 쓰기 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[modelTextureNumber]); // 밉맵 생성 gl.generateMipmap(gl.TEXTURE_2D); this.getRenderer().bindTexture(modelTextureNumber, tex); } img[modelTextureNumber].src = texturePath; this.getRenderer().setIsPremultipliedAlpha(usePremultiply);
표시 위치와 크기 지정
여기까지의 설정을 실시하면 모델을 그릴 수는 있지만
많을 경우 표시 위치나 축척이 너무 달라 그대로는 화면에 표시되지 않습니다.
csmGetDrawableVertexPositions 함수로 반환되는 정점 범위에 대해서는 「DrawableVertexPositions 범위」를 참조하십시오.
크기를 조정하려면 CubismModelMatrix 클래스와 CubismModel.getCanvasWidth 함수, getCanvasHeight 함수를 사용합니다.
// TypeScript let modelMatrix: CubismModelMatrix = new CubismModelMatrix(this._model.getCanvasWidth(), this._model.getCanvasHeight());
이 행렬은 그리기 전에 Projection 행렬에 곱해지고 MVP 행렬로서 렌더러에 전달됩니다.
// TypeScript let projectionMatrix: CubismMatrix44 = new CubismMatrix44(); projectionMatrix.scale(1, window.width / window.height); projectionMatrix.multiplyByMatrix(modelMatrix); this.getRenderer().setMvpMatrix(projectionMatrix); this.getRenderer().drawModel();
정점 업데이트
CubismModel 인스턴스에 대한 파라미터 조작을 아트메쉬의 정점에 반영하기 위해 CubismModel.update 함수를 실행합니다.
// TypeScript model.update();
그리기
그리기는 CubismModel 인스턴스에서는 실행하지 않고 연결된 렌더러에 명령하여 실시합니다.
// TypeScript let projectionMatrix: CubismMatrix44 = new CubismMatrix44(); projectionMatrix.scale(1, window.width / window.height); projectionMatrix.multiplyByMatrix(modelMatrix); this.getRenderer().setMvpMatrix(projectionMatrix); this.getRenderer().drawModel();
CubismModel 클래스에서 모델에 존재하지 않는 파라미터 ID 사용
CubismModel 클래스의 파라미터, 파츠 불투명도의 조작에서는 .moc3 파일에 존재하지 않는 ID에서도 취급을 실시하는 기능이 있습니다.
이 기능은 CubismMotion 클래스, CubismPose 클래스 등이 이용하고 있으며,
이용해서 새로운 기구를 작성할 때에는 기존의 기능과 충돌하지 않도록 사용하는 ID에 주의해 주세요.
또한 Framework를 읽을 때 작성된 파라미터를 사용하여 다른 기능과 연동할 가능성에 유의하십시오.
※존재하지 않는 최대치, 최소치, 초기치에 대한 액세스는 오류가 발생합니다
// TypeScript // CubismModel public getParameterIndex(parameterId: CubismIdHandle): number { let parameterIndex: number; const idCount: number = this._model.parameters.count; for(parameterIndex = 0; parameterIndex < idCount; ++parameterIndex) { if(parameterId ! = this._parameterIds.at(parameterIndex)) { continue; } return parameterIndex; } // 모델에 존재하지 않는 경우 부재 파라미터 ID 리스트 내를 검색해 그 인덱스를 반환 if(this._notExistParameterId.isExist(parameterId)) { return this._notExistParameterId.getValue(parameterId); } // 부재 파라미터 ID 목록에 없으면 새 요소를 추가 parameterIndex = this._model.parameters.count + this._notExistParameterId.getSize(); this._notExistParameterId.setValue(parameterId, parameterIndex); this._notExistParameterValues.appendKey(parameterIndex); return parameterIndex; }